aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libassuan.def4
-rw-r--r--src/libassuan.vers4
-rw-r--r--src/system-posix.c256
-rw-r--r--src/system-w32.c258
-rw-r--r--src/system.c27
5 files changed, 4 insertions, 545 deletions
diff --git a/src/libassuan.def b/src/libassuan.def
index 6f5452f..235d01b 100644
--- a/src/libassuan.def
+++ b/src/libassuan.def
@@ -91,7 +91,7 @@ EXPORTS
__assuan_close @70
__assuan_pipe @71
__assuan_socketpair @72
- __assuan_spawn @73
+; __assuan_spawn @73
__assuan_usleep @74
assuan_fdopen @75
assuan_client_read_response @76
@@ -109,7 +109,7 @@ EXPORTS
__assuan_write @88
__assuan_recvmsg @89
__assuan_sendmsg @90
- __assuan_waitpid @91
+; __assuan_waitpid @91
assuan_check_version @92
assuan_sock_set_sockaddr_un @93
assuan_sock_set_flag @94
diff --git a/src/libassuan.vers b/src/libassuan.vers
index 209f43d..6839db2 100644
--- a/src/libassuan.vers
+++ b/src/libassuan.vers
@@ -113,7 +113,7 @@ LIBASSUAN_1.0 {
__assuan_close;
__assuan_pipe;
__assuan_socketpair;
- __assuan_spawn;
+# __assuan_spawn;
__assuan_usleep;
__assuan_socket;
__assuan_connect;
@@ -121,7 +121,7 @@ LIBASSUAN_1.0 {
__assuan_write;
__assuan_recvmsg;
__assuan_sendmsg;
- __assuan_waitpid;
+# __assuan_waitpid;
local:
*;
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])
diff --git a/src/system-w32.c b/src/system-w32.c
index 1d06cd6..9248edf 100644
--- a/src/system-w32.c
+++ b/src/system-w32.c
@@ -64,33 +64,6 @@ __assuan_usleep (assuan_context_t ctx, unsigned int usec)
-/* Three simple wrappers, only used because thes function are named in
- the def file. */
-HANDLE
-_assuan_w32ce_prepare_pipe (int *r_rvid, int write_end)
-{
- (void)r_rvid;
- (void)write_end;
- return INVALID_HANDLE_VALUE;
-}
-
-HANDLE
-_assuan_w32ce_finish_pipe (int rvid, int write_end)
-{
- (void)rvid;
- (void)write_end;
- return INVALID_HANDLE_VALUE;
-}
-
-DWORD
-_assuan_w32ce_create_pipe (HANDLE *read_hd, HANDLE *write_hd,
- LPSECURITY_ATTRIBUTES sec_attr, DWORD size)
-{
- return CreatePipe (read_hd, write_hd, sec_attr, size);
-}
-
-
-
/* Create a pipe with one inheritable end. Default implementation. */
int
__assuan_pipe (assuan_context_t ctx, assuan_fd_t fd[2], int inherit_idx)
@@ -399,237 +372,6 @@ __assuan_sendmsg (assuan_context_t ctx, assuan_fd_t fd, assuan_msghdr_t msg,
gpg_err_set_errno (ENOSYS);
return -1;
}
-
-
-
-
-/* Build a command line for use with W32's CreateProcess. On success
- CMDLINE gets the address of a newly allocated string. */
-static int
-build_w32_commandline (assuan_context_t ctx, const char * const *argv,
- char **cmdline)
-{
- int i, n;
- const char *s;
- char *buf, *p;
-
- *cmdline = NULL;
- n = 0;
- for (i=0; (s = argv[i]); i++)
- {
- n += strlen (s) + 1 + 2; /* (1 space, 2 quoting */
- for (; *s; s++)
- if (*s == '\"')
- n++; /* Need to double inner quotes. */
- }
- n++;
-
- buf = p = _assuan_malloc (ctx, n);
- if (! buf)
- return -1;
-
- for (i = 0; argv[i]; i++)
- {
- if (i)
- p = stpcpy (p, " ");
- if (! *argv[i]) /* Empty string. */
- p = stpcpy (p, "\"\"");
- else if (strpbrk (argv[i], " \t\n\v\f\""))
- {
- p = stpcpy (p, "\"");
- for (s = argv[i]; *s; s++)
- {
- *p++ = *s;
- if (*s == '\"')
- *p++ = *s;
- }
- *p++ = '\"';
- *p = 0;
- }
- else
- p = stpcpy (p, argv[i]);
- }
-
- *cmdline= buf;
- return 0;
-}
-
-
-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)
-{
- SECURITY_ATTRIBUTES sec_attr;
- PROCESS_INFORMATION pi =
- {
- NULL, /* Returns process handle. */
- 0, /* Returns primary thread handle. */
- 0, /* Returns pid. */
- 0 /* Returns tid. */
- };
- STARTUPINFOW si;
- assuan_fd_t fd;
- assuan_fd_t *fdp;
- char *cmdline;
- wchar_t *wcmdline = NULL;
- wchar_t *wname = NULL;
- HANDLE nullfd = INVALID_HANDLE_VALUE;
- int rc;
-
- /* fixme: Actually we should set the "_assuan_pipe_connect_pid" env
- variable. However this requires us to write a full environment
- handler, because the strings are expected in sorted order. The
- suggestion given in the MS Reference Library, to save the old
- value, change it, create process and restore it, is not thread
- safe. */
-
- /* Build the command line. */
- if (build_w32_commandline (ctx, argv, &cmdline))
- return -1;
-
- /* Start the process. */
- memset (&sec_attr, 0, sizeof sec_attr);
- sec_attr.nLength = sizeof sec_attr;
- sec_attr.bInheritHandle = FALSE;
-
- memset (&si, 0, sizeof si);
- si.cb = sizeof (si);
- si.dwFlags = STARTF_USESTDHANDLES;
- /* FIXME: Dup to nul if ASSUAN_INVALID_FD. */
- si.hStdInput = fd_in;
- si.hStdOutput = fd_out;
-
- /* Dup stderr to /dev/null unless it is in the list of FDs to be
- passed to the child. */
- fd = assuan_fd_from_posix_fd (fileno (stderr));
- fdp = fd_child_list;
- if (fdp)
- {
- for (; *fdp != ASSUAN_INVALID_FD && *fdp != fd; fdp++)
- ;
- }
- if (!fdp || *fdp == ASSUAN_INVALID_FD)
- {
- nullfd = CreateFileW (L"nul", GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, 0, NULL);
- if (nullfd == INVALID_HANDLE_VALUE)
- {
- TRACE1 (ctx, ASSUAN_LOG_SYSIO, "__assuan_spawn", ctx,
- "can't open `nul': %s", _assuan_w32_strerror (ctx, -1));
- _assuan_free (ctx, cmdline);
- gpg_err_set_errno (EIO);
- return -1;
- }
- si.hStdError = nullfd;
- }
- else
- si.hStdError = fd;
-
- /* Note: We inherit all handles flagged as inheritable. This seems
- to be a security flaw but there seems to be no way of selecting
- handles to inherit. A fix for this would be to use a helper
- process like we have in gpgme.
- Take care: CreateProcessW may modify wpgmname */
- /* _assuan_log_printf ("CreateProcess, path=`%s' cmdline=`%s'\n", */
- /* name, cmdline); */
- if (name && !(wname = _assuan_utf8_to_wchar (name)))
- rc = 0;
- else if (!(wcmdline = _assuan_utf8_to_wchar (cmdline)))
- rc = 0;
- else
- rc = CreateProcessW (wname, /* Program to start. */
- wcmdline, /* Command line arguments. */
- &sec_attr, /* Process security attributes. */
- &sec_attr, /* Thread security attributes. */
- TRUE, /* Inherit handles. */
- (CREATE_DEFAULT_ERROR_MODE
- | ((flags & 128)? DETACHED_PROCESS : 0)
- | GetPriorityClass (GetCurrentProcess ())
- | CREATE_SUSPENDED), /* Creation flags. */
- NULL, /* Environment. */
- NULL, /* Use current drive/directory. */
- &si, /* Startup information. */
- &pi /* Returns process information. */
- );
- if (!rc)
- {
- TRACE1 (ctx, ASSUAN_LOG_SYSIO, "pipe_connect_w32", ctx,
- "CreateProcess failed%s: %s", _assuan_w32_strerror (ctx, -1));
- free (wname);
- free (wcmdline);
- _assuan_free (ctx, cmdline);
- if (nullfd != INVALID_HANDLE_VALUE)
- CloseHandle (nullfd);
-
- gpg_err_set_errno (EIO);
- return -1;
- }
-
- free (wname);
- free (wcmdline);
- _assuan_free (ctx, cmdline);
- if (nullfd != INVALID_HANDLE_VALUE)
- CloseHandle (nullfd);
-
- ResumeThread (pi.hThread);
- CloseHandle (pi.hThread);
-
- /* _assuan_log_printf ("CreateProcess ready: hProcess=%p hThread=%p" */
- /* " dwProcessID=%d dwThreadId=%d\n", */
- /* pi.hProcess, pi.hThread, */
- /* (int) pi.dwProcessId, (int) pi.dwThreadId); */
-
- *r_pid = (assuan_pid_t) pi.hProcess;
-
- /* No need to modify peer process, as we don't change the handle
- names. However this also means we are not safe, as we inherit
- too many handles. Should use approach similar to gpgme and glib
- using a helper process. */
-
- 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)
-{
- int code;
- DWORD exit_code;
-
- (void)ctx;
-
- if (nowait)
- return 0;
-
- code = WaitForSingleObject ((HANDLE)pid, options? 0: INFINITE);
-
- if (code == WAIT_OBJECT_0)
- {
- if (status)
- {
- GetExitCodeProcess ((HANDLE)pid, &exit_code);
- *status = (int)exit_code;
- }
- CloseHandle ((HANDLE)pid);
- return pid;
- }
- else if (code == WAIT_TIMEOUT)
- return 0;
- else
- return -1;
-}
-
-
int
__assuan_socketpair (assuan_context_t ctx, int namespace, int style,
diff --git a/src/system.c b/src/system.c
index d687b1b..0862681 100644
--- a/src/system.c
+++ b/src/system.c
@@ -376,33 +376,6 @@ _assuan_spawn (assuan_context_t ctx, const char *name, const char **argv,
return TRACE_SYSERR (res);
}
-
-
-
-/* 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 action,
- int *status, int options)
-{
-#if DEBUG_SYSIO
- assuan_pid_t res;
- TRACE_BEG4 (ctx, ASSUAN_LOG_SYSIO, "_assuan_waitpid", ctx,
- "pid=%i, action=%i, status=%p, options=%i",
- pid, action, status, options);
- _assuan_pre_syscall ();
- res = __assuan_waitpid (ctx, pid, action, status, options);
- _assuan_post_syscall ();
-#else
- assuan_pid_t res;
- _assuan_pre_syscall ();
- res = __assuan_waitpid (ctx, pid, action, status, options);
- _assuan_post_syscall ();
- return res;
-#endif
-}
-
-
int
_assuan_socketpair (assuan_context_t ctx, int namespace, int style,