#include "types.h" #include <signal.h> #include <stdio.h> #ifdef BSD #define strchr(a,b) index(a,b) #endif #ifdef sun typedef short uid_t; #endif /* Maximum size of command */ #define ARGSPACESIZE 1000 extern char *strchr (); static uid_t *pids; static int fds; FILE * vpopen (program, type) char *program, *type; { FILE *iop; int argc, pdes[2], pid; char argspace[ARGSPACESIZE]; char *argv[15]; if (*type != 'r' && *type != 'w' || type[1]) return (NULL); if (!pids) { if ((fds = getdtablesize ()) <= 0) return (NULL); if (!(pids = (uid_t *) malloc ((u_int) (fds * sizeof (uid_t))))) return (NULL); bzero (pids, fds * sizeof (uid_t)); } if (pipe (pdes) < 0) return (NULL); /* break up string into pieces, put into argv, and \0 delimit */ strncpy (argspace, program, ARGSPACESIZE); argv[0] = argspace; argc = 1; while (argv[argc] = strchr (argv[argc - 1], ' ')) *(argv[argc++]++) = '\0'; iop = NULL; switch (pid = vfork ()) { case -1: /* error */ (void) close (pdes[0]); (void) close (pdes[1]); return iop; /* NOTREACHED */ case 0: /* child */ /* (bub) if (*type == 'r') { if (pdes[1] != 1) { dup2 (pdes[1], 1); (void) close (pdes[1]); } * Try to get stderr piped as well. * pdes[2] = 1; (void) close (pdes[0]); } else { if (pdes[0] != 0) { dup2 (pdes[0], 0); (void) close (pdes[0]); } (void) close (pdes[1]); } */ execv (argv[0], argv); _exit (1); } /* parent; assume fdopen can't fail... */ if (*type == 'r') { iop = fdopen (pdes[0], type); (void) close (pdes[1]); } else { iop = fdopen (pdes[1], type); (void) close (pdes[0]); } pids[fileno (iop)] = pid; return iop; } vpclose (iop) FILE *iop; { register int fdes; long omask; int pid, stat_loc; u_int waitpid (); /* * pclose returns -1 if stream is not associated with a * `popened' command, or, if already `pclosed'. */ if (pids[fdes = fileno (iop)] == 0) return (-1); (void) fclose (iop); /* This looks good (bub) */ omask = sigblock (SIGINT | SIGQUIT | SIGHUP); /* omask = sigblock (sigmask (SIGINT) | sigmask (SIGQUIT) | sigmask (SIGHUP));*/ while ((pid = wait (&stat_loc)) != pids[fdes] && pid != -1) ; (void) sigsetmask (omask); pids[fdes] = 0; return (stat_loc); } FILE * vpopen_grep (program, arg1, arg2, arg3, type) char *program, *type, *arg1, *arg2, *arg3; { FILE *iop; int argc, pdes[3], pid; char argspace[ARGSPACESIZE]; char *argv[15]; if (*type != 'r' && *type != 'w' || type[1]) return (NULL); if (!pids) { if ((fds = getdtablesize ()) <= 0) return (NULL); if (!(pids = (uid_t *) malloc ((u_int) (fds * sizeof (uid_t))))) return (NULL); bzero (pids, fds * sizeof (uid_t)); } if (pipe (pdes) < 0) return (NULL); iop = NULL; switch (pid = vfork ()) { case -1: /* error */ (void) close (pdes[0]); (void) close (pdes[1]); return iop; /* NOTREACHED */ case 0: /* child */ if (*type == 'r') { if (pdes[1] != 1) { dup2 (pdes[1], 1); (void) close (pdes[1]); } /* Try to get stderr piped as well. */ pdes[2] = 1; (void) close (pdes[0]); } else { if (pdes[0] != 0) { dup2 (pdes[0], 0); (void) close (pdes[0]); } (void) close (pdes[1]); } execl (program, program, arg1, arg2, arg3, 0); _exit (1); } /* parent; assume fdopen can't fail... */ if (*type == 'r') { iop = fdopen (pdes[0], type); (void) close (pdes[1]); } else { iop = fdopen (pdes[1], type); (void) close (pdes[0]); } pids[fileno (iop)] = pid; return iop; }