diff options
Diffstat (limited to 'mit-pthreads/gen/popen.c')
-rw-r--r-- | mit-pthreads/gen/popen.c | 117 |
1 files changed, 0 insertions, 117 deletions
diff --git a/mit-pthreads/gen/popen.c b/mit-pthreads/gen/popen.c deleted file mode 100644 index c15fbdce1fe..00000000000 --- a/mit-pthreads/gen/popen.c +++ /dev/null @@ -1,117 +0,0 @@ -#include <pthread.h> -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/wait.h> - -static pid_t *pids = NULL; -static int pids_size = 0; -static int pids_top = 0; -static pthread_mutex_t pids_lock = PTHREAD_MUTEX_INITIALIZER; - -FILE *popen(const char *cmd, const char *mode) -{ - int fds[2], parent_fd, child_fd, child_target, new_size, i; - pid_t pid, *new_pids; - - /* Verify the mode. */ - if ((*mode != 'r' && *mode != 'w') || mode[1] != 0) - return NULL; - - /* Generate fds, and choose the parent and child fds. */ - if (pipe(fds) < 0) - return NULL; - parent_fd = (*mode == 'r') ? fds[0] : fds[1]; - child_fd = (*mode == 'r') ? fds[1] : fds[0]; - - /* Ensure that there is space in the pid table. */ - pthread_mutex_lock(&pids_lock); - if (pids_size <= parent_fd) { - new_size = parent_fd + 1; - if ((new_pids = malloc(new_size * sizeof(pid_t))) == NULL) { - pthread_mutex_unlock(&pids_lock); - close(parent_fd); - close(child_fd); - return NULL; - } - if (pids) { - memcpy(new_pids, pids, pids_size * sizeof(pid_t)); - free(pids); - } - while (pids_size < new_size) - new_pids[pids_size++] = -1; - pids = new_pids; - } - pthread_mutex_unlock(&pids_lock); - - /* Fork off a child process. */ - switch (pid = fork()) { - case -1: /* Failed to fork. */ - close(parent_fd); - close(child_fd); - return NULL; - break; - case 0: /* Child */ - /* - * Set the child fd to stdout or stdin as appropriate, - * and close the parent fd. - */ - child_target = (*mode == 'r') ? STDOUT_FILENO : STDIN_FILENO; - if (child_fd != child_target) { - dup2(child_fd, child_target); - close(child_fd); - } - close(parent_fd); - - /* Close all parent fds from previous popens(). */ - for (i = 0; i < pids_top; i++) { - if (pids[i] != -1) - close(i); - } - - execl("/bin/sh", "sh", "-c", cmd, NULL); - exit(1); - default: - break; - } - - /* Record the parent fd in the pids table. */ - pthread_mutex_lock(&pids_lock); - pids[parent_fd] = pid; - if (pids_top < parent_fd + 1) - pids_top = parent_fd + 1; - pthread_mutex_unlock(&pids_lock); - - /* Close the child fd and return a stdio buffer for the parent fd. */ - close(child_fd); - return fdopen(parent_fd, mode); -} - -int pclose(fp) - FILE *fp; -{ - pid_t pid, result; - int fd, pstat; - - fd = fileno(fp); - pthread_mutex_lock(&pids_lock); - /* Make sure this is a popened file. */ - if ((pids_top <= fd) || ((pid = pids[fd]) == -1)) { - pthread_mutex_unlock(&pids_lock); - return -1; - } - pids[fd] = -1; - while (pids_top > 0 && pids[pids_top - 1] == -1) - pids_top--; - pthread_mutex_unlock(&pids_lock); - - fclose(fp); - - /* Wait for the subprocess to quit. */ - return (((result = waitpid(pid, &pstat, 0)) == -1) ? -1 : pstat); -} - |