diff options
Diffstat (limited to 'src/system-posix.c')
-rw-r--r-- | src/system-posix.c | 256 |
1 files changed, 0 insertions, 256 deletions
diff --git a/src/system-posix.c b/src/system-posix.c index 3312523..780906d 100644 --- a/src/system-posix.c +++ b/src/system-posix.c @@ -153,262 +153,6 @@ __assuan_sendmsg (assuan_context_t ctx, assuan_fd_t fd, assuan_msghdr_t msg, -static int -writen (int fd, const char *buffer, size_t length) -{ - while (length) - { - int nwritten = write (fd, buffer, length); - - if (nwritten < 0) - { - if (errno == EINTR) - continue; - return -1; /* write error */ - } - length -= nwritten; - buffer += nwritten; - } - return 0; /* okay */ -} - - -/* Return the maximum number of currently allowed open file - * descriptors. */ -static int -get_max_fds (void) -{ - int max_fds = -1; - -#ifdef HAVE_GETRLIMIT - struct rlimit rl; - - /* Under Linux we can figure out the highest used file descriptor by - * reading /proc/PID/fd. This is in the common cases much faster - * than for example doing 4096 close calls where almost all of them - * will fail. We use the same code in GnuPG and measured this: On a - * system with a limit of 4096 files and only 8 files open with the - * highest number being 10, we speedup close_all_fds from 125ms to - * 0.4ms including the readdir. - * - * Another option would be to close the file descriptors as returned - * from reading that directory - however then we need to snapshot - * that list before starting to close them. */ -#ifdef __linux__ - { - DIR *dir = NULL; - struct dirent *dir_entry; - const char *s; - int x; - - dir = opendir ("/proc/self/fd"); - if (dir) - { - while ((dir_entry = readdir (dir))) - { - s = dir_entry->d_name; - if ( *s < '0' || *s > '9') - continue; - x = atoi (s); - if (x > max_fds) - max_fds = x; - } - closedir (dir); - } - if (max_fds != -1) - return max_fds + 1; - } -#endif /* __linux__ */ - -# ifdef RLIMIT_NOFILE - if (!getrlimit (RLIMIT_NOFILE, &rl)) - max_fds = rl.rlim_max; -# endif - -# ifdef RLIMIT_OFILE - if (max_fds == -1 && !getrlimit (RLIMIT_OFILE, &rl)) - max_fds = rl.rlim_max; - -# endif -#endif /*HAVE_GETRLIMIT*/ - -#ifdef _SC_OPEN_MAX - if (max_fds == -1) - { - long int scres = sysconf (_SC_OPEN_MAX); - if (scres >= 0) - max_fds = scres; - } -#endif - -#ifdef _POSIX_OPEN_MAX - if (max_fds == -1) - max_fds = _POSIX_OPEN_MAX; -#endif - -#ifdef OPEN_MAX - if (max_fds == -1) - max_fds = OPEN_MAX; -#endif - - if (max_fds == -1) - max_fds = 256; /* Arbitrary limit. */ - - /* AIX returns INT32_MAX instead of a proper value. We assume that - this is always an error and use a more reasonable limit. */ -#ifdef INT32_MAX - if (max_fds == INT32_MAX) - max_fds = 256; -#endif - - return max_fds; -} - - -int -__assuan_spawn (assuan_context_t ctx, assuan_pid_t *r_pid, const char *name, - const char **argv, - assuan_fd_t fd_in, assuan_fd_t fd_out, - assuan_fd_t *fd_child_list, - void (*atfork) (void *opaque, int reserved), - void *atforkvalue, unsigned int flags) -{ - int pid; - - pid = fork (); - if (pid < 0) - return -1; - - if (pid == 0) - { - /* Child process (server side). */ - int i; - int n; - char errbuf[512]; - int *fdp; - int fdnul; - - if (atfork) - atfork (atforkvalue, 0); - - fdnul = open ("/dev/null", O_WRONLY); - if (fdnul == -1) - { - TRACE1 (ctx, ASSUAN_LOG_SYSIO, "__assuan_spawn", ctx, - "can't open `/dev/null': %s", strerror (errno)); - _exit (4); - } - - /* Dup handles to stdin/stdout. */ - if (fd_out != STDOUT_FILENO) - { - if (dup2 (fd_out == ASSUAN_INVALID_FD ? fdnul : fd_out, - STDOUT_FILENO) == -1) - { - TRACE1 (ctx, ASSUAN_LOG_SYSIO, "__assuan_spawn", ctx, - "dup2 failed in child: %s", strerror (errno)); - _exit (4); - } - } - - if (fd_in != STDIN_FILENO) - { - if (dup2 (fd_in == ASSUAN_INVALID_FD ? fdnul : fd_in, - STDIN_FILENO) == -1) - { - TRACE1 (ctx, ASSUAN_LOG_SYSIO, "__assuan_spawn", ctx, - "dup2 failed in child: %s", strerror (errno)); - _exit (4); - } - } - - /* Dup stderr to /dev/null unless it is in the list of FDs to be - passed to the child. */ - fdp = fd_child_list; - if (fdp) - { - for (; *fdp != -1 && *fdp != STDERR_FILENO; fdp++) - ; - } - if (!fdp || *fdp == -1) - { - if (dup2 (fdnul, STDERR_FILENO) == -1) - { - TRACE1 (ctx, ASSUAN_LOG_SYSIO, "pipe_connect_unix", ctx, - "dup2(dev/null, 2) failed: %s", strerror (errno)); - _exit (4); - } - } - close (fdnul); - - /* Close all files which will not be duped and are not in the - fd_child_list. */ - n = get_max_fds (); - for (i = 0; i < n; i++) - { - if (i == STDIN_FILENO || i == STDOUT_FILENO || i == STDERR_FILENO) - continue; - fdp = fd_child_list; - if (fdp) - { - while (*fdp != -1 && *fdp != i) - fdp++; - } - - if (!(fdp && *fdp != -1)) - close (i); - } - gpg_err_set_errno (0); - - if (! name) - { - /* No name and no args given, thus we don't do an exec - but continue the forked process. */ - *argv = "server"; - - /* FIXME: Cleanup. */ - return 0; - } - - execv (name, (char *const *) argv); - - /* oops - use the pipe to tell the parent about it */ - snprintf (errbuf, sizeof(errbuf)-1, - "ERR %d can't exec `%s': %.50s\n", - _assuan_error (ctx, GPG_ERR_ASS_SERVER_START), - name, strerror (errno)); - errbuf[sizeof(errbuf)-1] = 0; - writen (1, errbuf, strlen (errbuf)); - _exit (4); - } - - if (! name) - *argv = "client"; - - *r_pid = pid; - - return 0; -} - - - -/* FIXME: Add some sort of waitpid function that covers GPGME and - gpg-agent's use of assuan. */ -assuan_pid_t -__assuan_waitpid (assuan_context_t ctx, assuan_pid_t pid, int nowait, - int *status, int options) -{ - if (nowait) - return 0; - - /* We can't just release the PID, a waitpid is mandatory. But - NOWAIT in POSIX systems just means the caller already did the - waitpid for this child. */ - return waitpid (pid, status, options ? WNOHANG : 0); -} - - - int __assuan_socketpair (assuan_context_t ctx, int namespace, int style, int protocol, assuan_fd_t filedes[2]) |