* Licensed under the GPL v2. For licencing details see COPYING.
*/
-/** \file fd.c helper functions for file descriptor handling */
+/** \file fd.c Helper functions for file descriptor handling. */
#include <sys/types.h>
#include <dirent.h>
#include "para.h"
#include "error.h"
+
/**
- * check whether a file exists
+ * Check whether a file exists.
*
- * \param fn the file name
+ * \param fn The file name.
*
* \return Non-zero iff file exists.
*/
}
/**
- * paraslash's wrapper for select(2)
+ * Paraslash's wrapper for select(2).
*
* It calls select(2) (with no exceptfds) and starts over if select() was
* interrupted by a signal.
*
- * \param n the highest-numbered descriptor in any of the two sets, plus 1
- * \param readfds fds that should be checked for readability
- * \param writefds fds that should be checked for writablility
+ * \param n The highest-numbered descriptor in any of the two sets, plus 1.
+ * \param readfds fds that should be checked for readability.
+ * \param writefds fds that should be checked for writablility.
* \param timeout_tv upper bound on the amount of time elapsed before select()
- * returns
+ * returns.
*
- * \return The return value of the underlying select() call.
+ * \return The return value of the underlying select() call on success, the
+ * negative system error code on errors.
*
* All arguments are passed verbatim to select(2).
- * \sa select(2) select_tut(2)
+ * \sa select(2) select_tut(2).
*/
int para_select(int n, fd_set *readfds, fd_set *writefds,
struct timeval *timeout_tv)
err = errno;
} while (ret < 0 && err == EINTR);
if (ret < 0)
- PARA_CRIT_LOG("select error: %s, max_fileno: %d\n",
- strerror(err), n);
+ return -ERRNO_TO_PARA_ERROR(errno);
return ret;
}
}
/**
- * set a file descriptor in a fd_set
+ * Set a file descriptor in a fd_set.
*
- * \param fd the file descriptor to be set
- * \param fds the file descriptor set
- * \param max_fileno highest-numbered file descriptor
+ * \param fd The file descriptor to be set.
+ * \param fds The file descriptor set.
+ * \param max_fileno Highest-numbered file descriptor.
*
* This wrapper for FD_SET() passes its first two arguments to \p FD_SET. Upon
* return, \a max_fileno contains the maximum of the old_value and \a fd.
*
- * \sa para_select
+ * \sa para_select.
*/
void para_fd_set(int fd, fd_set *fds, int *max_fileno)
{
}
/**
-* paraslash's wrapper for fgets(3)
-* \param line pointer to the buffer to store the line
-* \param size the size of the buffer given by \a line
-* \param f the stream to read from
+* Paraslash's wrapper for fgets(3).
+
+* \param line Pointer to the buffer to store the line.
+* \param size The size of the buffer given by \a line.
+* \param f The stream to read from.
*
* \return Unlike the standard fgets() function, an integer value
* is returned. On success, this function returns 1. On errors, -E_FGETS
/**
* Paraslash's wrapper for mmap.
*
- * \param length number of bytes to mmap
- * \param prot either PROT_NONE or the bitwise OR of one or more of
- * PROT_EXEC PROT_READ PROT_WRITE
- * \param flags exactly one of MAP_SHARED and MAP_PRIVATE
- * \param fd the file to mmap from
- * \param offset mmap start
+ * \param length Number of bytes to mmap.
+ * \param prot Either PROT_NONE or the bitwise OR of one or more of
+ * PROT_EXEC PROT_READ PROT_WRITE.
+ * \param flags Exactly one of MAP_SHARED and MAP_PRIVATE.
+ * \param fd The file to mmap from.
+ * \param offset Mmap start.
*
* \return This function either returns a valid pointer to the mapped area
* or calls exit() on errors.
* \param flags The usual open(2) flags.
* \param mode Specifies the permissions to use.
*
- * The mode parameter must be specified when O_CREAT is in the flags, and is ignored
- * otherwise.
+ * The mode parameter must be specified when O_CREAT is in the flags, and is
+ * ignored otherwise.
*
* \return The file descriptor on success, negative on errors.
*
/**
* Wrapper for chdir(2).
*
- * \param path the specified directory.
+ * \param path The specified directory.
*
- * \return Positive on success, negative on errors.
+ * \return Standard.
*/
int para_chdir(const char *path)
{
* \param dir Result pointer.
* \param cwd File descriptor of the current working directory.
*
- * \return Positive on success, negative on errors.
+ * \return Standard.
*
* Opening the current directory (".") and calling fchdir() to return is
* usually faster and more reliable than saving cwd in some buffer and calling
ret = para_chdir(dirname);
if (ret < 0)
goto close_cwd;
- ret = -E_OPENDIR;
*dir = opendir(".");
- if (!*dir)
- goto change_to_orig_dir;
- return 1;
+ if (*dir)
+ return 1;
+ ret = -ERRNO_TO_PARA_ERROR(errno);
/* Ignore return value of fchdir() and close(). We're busted anyway. */
change_to_orig_dir:
if (cwd)
/**
* A wrapper for fchdir().
*
- * \param fd An open file descriptor
+ * \param fd An open file descriptor.
*
- * \return Positive on success, negative on errors.
+ * \return Standard.
*/
int para_fchdir(int fd)
{
if (fchdir(fd) < 0)
- return -E_FCHDIR;
+ return -ERRNO_TO_PARA_ERROR(errno);
return 1;
}
static int signal_pipe[2];
/**
- * initialize the paraslash signal subsystem
+ * Initialize the paraslash signal subsystem.
*
* This function creates a pipe, the signal pipe, to deliver pending
* signals to the application (Bernstein's trick). It should be called
*/
int para_signal_init(void)
{
- int ret = -E_SIGNAL_PIPE;
- if (pipe(signal_pipe))
+ int ret;
+ if (pipe(signal_pipe) < 0) {
+ ret = -ERRNO_TO_PARA_ERROR(errno);
goto err_out;
+ }
ret = mark_fd_nonblock(signal_pipe[0]);
if (ret < 0)
goto err_out;
}
/**
- * reap one child
+ * Reap one child.
+ *
+ * \para, pid In case a child died, its pid is returned here.
+ *
+ * Call waitpid() and print a log message containing the pid and the cause of
+ * the child's death.
*
- * call waitpid() and print a log message containing the pid
- * and the cause of the child's death.
+ * \return A (negative) paraslash error code on errors, zero, if no child died,
+ * one otherwise. If and only if the function returns one, the content of \a
+ * pid is meaningful.
*
- * \return Like \p waitpid(), this function returns the process ID of the
- * terminated child; on error, \p -E_WAITPID is returned.
* \sa waitpid(2)
*/
-pid_t para_reap_child(void)
+int para_reap_child(pid_t *pid)
{
int status;
- pid_t pid = waitpid(-1, &status, WNOHANG);
+ *pid = waitpid(-1, &status, WNOHANG);
- if (pid <= 0) {
- if (pid < 0)
- pid = -E_WAITPID;
- return pid;
- }
+ if (!*pid)
+ return 0;
+ if (*pid < 0)
+ return -ERRNO_TO_PARA_ERROR(errno);
if (WIFEXITED(status))
- PARA_DEBUG_LOG("child %i exited. Exit status: %i\n", pid,
+ PARA_DEBUG_LOG("child %i exited. Exit status: %i\n", *pid,
WEXITSTATUS(status));
else if (WIFSIGNALED(status))
- PARA_DEBUG_LOG("child %i was killed by signal %i\n", pid,
+ PARA_DEBUG_LOG("child %i was killed by signal %i\n", *pid,
WTERMSIG(status));
else
- PARA_WARNING_LOG("child %i terminated abormally\n", pid);
- return pid;
+ PARA_WARNING_LOG("child %i terminated abormally\n", *pid);
+ return 1;
}
/**
- * paraslash's zombie killer
+ * Paraslash's zombie killer.
*
* It just calls \p para_reap_child() until there are no more children left to
* reap.
*/
void para_reap_children(void)
{
- while (para_reap_child() > 0)
+ pid_t pid;
+
+ while (para_reap_child(&pid) > 0)
; /* nothing */
}
* This should be called if the fd for the signal pipe is ready for reading.
*
* \return On success, the number of the received signal is returned. \p
- * -E_SIGNAL_READ is returned if a read error occured while reading the signal
+ * -E_SIGNAL_READ is returned if a read error occurred while reading the signal
* pipe. If the read was interrupted by another signal the function returns 0.
*/
int para_next_signal(void)