aboutsummaryrefslogtreecommitdiff
path: root/src/utils.c
diff options
context:
space:
mode:
authorlns <matzeton@googlemail.com>2018-04-25 12:41:03 +0200
committerlns <matzeton@googlemail.com>2018-04-25 12:41:03 +0200
commitd05358d2667d5b55a1bec36d051d95c06a3c7536 (patch)
tree11e9ef6d9cf9ecf12988151545c094397a6989ec /src/utils.c
parent03e137c2193d550dda156f86ca68c896f0dffe84 (diff)
POTD skeleton #29.
Signed-off-by: lns <matzeton@googlemail.com>
Diffstat (limited to 'src/utils.c')
-rw-r--r--src/utils.c86
1 files changed, 76 insertions, 10 deletions
diff --git a/src/utils.c b/src/utils.c
index a5fa5a9..996a8a7 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -2,6 +2,8 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <stdarg.h>
+#include <fcntl.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -15,6 +17,7 @@
#define _POSIX_PATH_MAX 256
char *arg0 = NULL;
+static int null_fd = -1;
static void sighandler_child(int signo)
@@ -90,18 +93,81 @@ pid_t daemonize(int stay_foreground)
/* Set new file permissions */
umask(0);
- if (stay_foreground)
- return pid;
+ if (!stay_foreground) {
+ /* Change the working directory to the root directory */
+ /* or another appropriated directory */
+ chdir("/");
+ /* Close all open file descriptors */
+ assert( close_fds_except(-1) == 0 );
+ } else {
+ assert( close_fds_except(0, 1, 2, -1) == 0 );
+ }
- /* Change the working directory to the root directory */
- /* or another appropriated directory */
-// chdir("/");
+ return pid;
+}
- /* Close all open file descriptors */
- int x;
- for (x = sysconf(_SC_OPEN_MAX); x>=0; x--) {
-// close (x);
+int close_fds_except(int fds, ...)
+{
+ int fd;
+ long max_fd;
+ size_t i, except_count, found;
+ va_list ap;
+
+ max_fd = sysconf(_SC_OPEN_MAX);
+ if (max_fd <= 0)
+ return 1;
+
+ va_start(ap, fds);
+ {
+ int *all_fds = malloc(max_fd * sizeof(*all_fds));
+ assert(all_fds);
+ memset(all_fds, -1, max_fd * sizeof(*all_fds));
+
+ except_count = 0;
+ while ( (fd = va_arg(ap, int)) >= 0 ) {
+ all_fds[except_count++] = fd;
+ }
+
+ for (fd = max_fd; fd >= 0; --fd) {
+ found = 0;
+ for (i = 0; i < except_count; ++i) {
+ if (fd == all_fds[i])
+ found++;
+ }
+ if (!found) {
+ close(fd);
+ }
+ }
+
+ free(all_fds);
}
+ va_end(ap);
- return pid;
+ return 0;
+}
+
+int redirect_devnull_to(int fds, ...)
+{
+ int fd, rc = 0;
+ va_list ap;
+
+ if (null_fd < 0)
+ null_fd = open("/dev/null", O_RDWR);
+ assert(null_fd >= 0);
+
+ va_start(ap, fds);
+ {
+ while ( (fd = va_arg(ap, int)) >= 0 ) {
+ if ( dup2(null_fd, fd) < 0 )
+ rc++;
+ }
+ }
+ va_end(ap);
+
+ return rc;
+}
+
+int change_user_group(const char *user, const char *group)
+{
+ return 0;
}