diff options
Diffstat (limited to 'src/appl/gssftp/ftp/pclose.c')
-rw-r--r-- | src/appl/gssftp/ftp/pclose.c | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/src/appl/gssftp/ftp/pclose.c b/src/appl/gssftp/ftp/pclose.c new file mode 100644 index 0000000..e1e13e4 --- /dev/null +++ b/src/appl/gssftp/ftp/pclose.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 1980 Regents of the University of California. + * All rights reserved. The Berkeley software License Agreement + * specifies the terms and conditions for redistribution. + */ + +#ifndef lint +static char sccsid[] = "@(#)pclose.c 1.1 90/04/28 SMI"; /* from UCB 1.2 3/7/86 */ +#endif /* not lint */ + +#include <stdio.h> +#include <signal.h> +#include <sys/param.h> +#include <sys/wait.h> +#ifdef HAVE_VFORK_H +#include <vfork.h> +#endif +#define sig_t my_sig_t +#define sigtype krb5_sigtype +typedef sigtype (*sig_t)(); + +#define tst(a,b) (*mode == 'r'? (b) : (a)) +#define RDR 0 +#define WTR 1 + +static int *popen_pid; +static int nfiles; + +#ifndef HAVE_GETDTABLESIZE +#include <sys/resource.h> +int getdtablesize() { + struct rlimit rl; + getrlimit(RLIMIT_NOFILE, &rl); + return rl.rlim_cur; +} +#endif + +FILE * +mypopen(cmd,mode) + char *cmd; + char *mode; +{ + int p[2]; + int myside, hisside, pid; + + if (nfiles <= 0) + nfiles = getdtablesize(); + if (popen_pid == NULL) { + popen_pid = (int *)malloc((unsigned) nfiles * sizeof *popen_pid); + if (popen_pid == NULL) + return (NULL); + for (pid = 0; pid < nfiles; pid++) + popen_pid[pid] = -1; + } + if (pipe(p) < 0) + return (NULL); + myside = tst(p[WTR], p[RDR]); + hisside = tst(p[RDR], p[WTR]); + if ((pid = vfork()) == 0) { + /* myside and hisside reverse roles in child */ + (void) close(myside); + if (hisside != tst(0, 1)) { + (void) dup2(hisside, tst(0, 1)); + (void) close(hisside); + } + execl("/bin/sh", "sh", "-c", cmd, (char *)NULL); + _exit(127); + } + if (pid == -1) { + (void) close(myside); + (void) close(hisside); + return (NULL); + } + popen_pid[myside] = pid; + (void) close(hisside); + return (fdopen(myside, mode)); +} + +sigtype +pabort(sig) + int sig; +{ + extern int mflag; + + mflag = 0; +} + +mypclose(ptr) + FILE *ptr; +{ + int child, pid; +#ifdef USE_SIGPROCMASK + sigset_t old, new; +#else + int omask; +#endif + sigtype pabort(), (*istat)(); +#ifdef WAIT_USES_INT + int status; +#else + union wait status; +#endif + + child = popen_pid[fileno(ptr)]; + popen_pid[fileno(ptr)] = -1; + (void) fclose(ptr); + if (child == -1) + return (-1); + istat = signal(SIGINT, pabort); +#ifdef USE_SIGPROCMASK + sigemptyset(&old); + sigemptyset(&new); + sigaddset(&new,SIGQUIT); + sigaddset(&new,SIGHUP); + sigprocmask(SIG_BLOCK, &new, &old); + while ((pid = wait(&status)) != child && pid != -1) + ; + sigprocmask(SIG_SETMASK, &old, NULL); +#else + omask = sigblock(sigmask(SIGQUIT)|sigmask(SIGHUP)); + while ((pid = wait(&status)) != child && pid != -1) + ; + sigsetmask(omask); +#endif + (void) signal(SIGINT, istat); + return (pid == -1 ? -1 : 0); +} |