diff options
Diffstat (limited to 'doc/files_and_dirs.rst')
-rw-r--r-- | doc/files_and_dirs.rst | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/doc/files_and_dirs.rst b/doc/files_and_dirs.rst new file mode 100644 index 0000000..a4fdc59 --- /dev/null +++ b/doc/files_and_dirs.rst @@ -0,0 +1,190 @@ +=========================== +File and directory handling +=========================== + + +Directory traversal +=================== + +libHX provides a minimal readdir-style wrapper for cross-platform directory +traversal. This is needed because the Win32 platforms does not have readdir, +and there is some housekeeping to do on Unixish platforms, since the dirent +structure needs allocation of a path-specific size. + +.. code-block:: c + + #include <libHX/io.h> + + struct HXdir *HXdir_open(const char *directory); + const char *HXdir_read(struct HXdir *handle); + void HXdir_close(struct HXdir *handle); + +``HXdir_open`` returns a pointer to its private data area, or ``NULL`` upon +failure, in which case ``errno`` is preserved from the underlying system calls. +``HXdir_read`` causes the next entry from the directory to be fetched. The +pointer returned by ``HXdir_read`` must not be freed, and the data is +overwritten in subsequent calls to the same handle. If you want to keep it +around, you will have to duplicate it yourself. ``HXdir_close`` will close the +directory and free the private data it held. + + +Example +------- + +.. code-block:: c + + #include <errno.h> + #include <stdio.h> + #include <libHX/io.h> + + struct HXdir *dh; + if ((dh = HXdir_open(".")) == NULL) { + fprintf(stderr, "Could not open directory: %s\n", strerror(errno)); + return; + } + while ((dentry = HXdir_read(dh)) != NULL) + printf("%s\n", dentry); + HXdir_close(dh); + +This sample will open the current directory, and print out all entries as it +iterates over them. + + +Operation on directory entries +============================== + +.. code-block:: c + + #include <libHX/io.h> + + int HX_readlink(hxmc_t **buf, const char *path); + int HX_realpath(hxmc_t **buf, const char *path, unsigned int flags); + +``HX_readlink`` calls through to readlink to read the target of a symbolic +link, and stores the result in the memory container referenced by ``*buf`` +(similar to ``HX_getl`` semantics). If ``*buf`` is ``NULL``, a new container +will be allocated and a pointer to it stored in ``*buf``. The container's +content is naturally zero-terminated automatically. The return value of the +function will be the length of the link target, or negative to indicate the +system error value. + +``HX_realpath`` will normalize the given path by transforming various path +components into alternate descriptions. The flags parameter controls its +actions: + +``HX_REALPATH_DEFAULT`` + A mnemonic for a set of standard flags: ``HX_REALPATH_SELF | + HX_REALPATH_PARENT``. Note that ``HX_REALPATH_ABSOLUTE``, which would + also be required to get libc's ``realpath``(3) behavior, is not + included in the set. + +``HX_REALPATH_ABSOLUTE`` + Requests that the output path shall be absolute. In the absence of this + flag, an absolute output path will only be produced if the input path + is also absolute. + +``HX_REALPATH_SELF`` + Request resolution of `.` path components. + +``HX_REALPATH_PARENT` + Request resolution of `..` path components. + +The result is stored in a memory container whose pointer is returned through +``*buf``. The return value of the function will be negative to indicate a +possible system error, or be positive non-zero for success. + + +Operations on directories +========================= + +.. code-block:: c + + #include <libHX/io.h> + + int HX_mkdir(const char *path, unsigned int mode); + int HX_rrmdir(const char *path); + +``HX_mkdir`` will create the directory given by path and all its parents that +do not exist yet using the given mode. It is equivalent to the ``mkdir -p`` +shell command. It will return >0 for success, or ``-errno`` on error. + +``HX_rrmdir`` also maps to an operation commonly done on the shell, ``rm -Rf``, +deleting the directory given by path, including all files within it and its +subdirectories. Errors during deletion are ignored, but if there was any, the +errno value of the first one is returned negated. + + +Operations on files +=================== + +.. code-block:: c + + #include <libHX/io.h> + + #define HXF_KEEP ... + #define HXF_UID ... + #define HXF_GID ... + + int HX_copy_file(const char *src, const char *dest, unsigned int flags, ...); + int HX_copy_dir(const char *src, const char *dest, unsigned int flags, ...); + char *HX_slurp_fd(int fd, size_t *outsize); + char *HX_slurp_file(const char *file, size_t *outsize); + +``HX_copy_file`` + Copies one named file to a new location. Possible ``flags`` are + ``HXF_KEEP``, ``HXF_UID`` and ``HXF_GID``. Error checking by + ``HX_copy_file`` is flakey. ``HX_copy_file`` will return >0 on success, + or ``-errno`` on failure. Errors can arise from the use of the syscalls + ``open``, ``read`` and ``write``. The return value of ``fchmod``, which + is used to set the UID and GID, is actually ignored, which means + verifying that the owner has been set cannot be detected with + ``HX_copy_file`` alone (historic negligience?). + +``HXF_KEEP`` + Do not overwrite existing files. + +``HXF_UID`` + Change the new file's owner to the UID given in the varargs section + (...). ``HXF_UID`` is processed before ``HXF_GID``. + +``HXF_GID`` + Change the new file's group owner to the GID given in the varargs + section. This is processed after ``HXF_UID``. + +``HX_copy_dir`` + Copies one named directory to a new location, recursively. + (Uses ``HX_copy_file`` and ``HX_copy_dir``.) Error checking by + ``HX_copy_dir`` is flakey. + +``HX_slurp_fd`` + Reads all remaining bytes from the given filedescriptor ``fd`` and + returns a pointer to a newly-allocated content buffer. If ``outsize`` + is not ``NULL``, the size of the buffer will be written to it. The + buffer is always terminated by a gratuitious NUL (not counted in + ``outsize``). Once no longer needed, the buffer should be released with + ``free``. + +``HX_slurp_file`` + Reads all bytes from the given filename and returns a pointer to the + content buffer. Inherits all the characteristics from ``HX_slurp_fd``. + + +Filedescriptor helpers +====================== + +.. code-block:: c + + #include <libHX/io.h> + + ssize_t HXio_fullread(int fd, void *buf, size_t size, unsigned int flags); + ssize_t HXio_fullwrite(int fd, const void *buf, size_t size, unsigned int flags); + ssize_t HX_sendfile(int dst, int src, size_t count); + +Since plain ``read``(2) and ``write``(2) may process only part of the buffer — +even more likely so with sockets —, libHX provides two functions that calls +these in a loop to retry said operations until the full amount has been +processed. Since read and write can also be used with socket file descriptors, +so can these. + +``HX_sendfile`` wraps ``sendfile``(2) for the same reason; in addition, it +falls back to a read-write loop on platforms which do not offer sendfile. |