aboutsummaryrefslogtreecommitdiffstats
path: root/src/system-posix.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/system-posix.c')
-rw-r--r--src/system-posix.c256
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])