home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume10 / ease / part01 / maketd / nshpopen.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-07-09  |  2.2 KB  |  96 lines

  1. /* @(#)popen.c    4.5 (Berkeley) 7/6/84
  2.  * Modified from 4.2, 2.9 BSD popen by Stephen Uitti, PUCC, Nov '85
  3.  * Doesn't invoke shell, saving time, becoming more secure.
  4.  * Calls breakargs to break line into command line arguments,
  5.  * delimited by white space, but ignores globing and quoting
  6.  * characters.  For use where you don't need shell meta character
  7.  * expansion or filename globbing.
  8.  */
  9. #ifdef BSD2_9
  10. #include <sys/types.h>
  11. #endif
  12. #include <stdio.h>
  13. #include <signal.h>
  14.  
  15. #define    tst(a,b)    (*mode == 'r'? (b) : (a))
  16. #define    RDR    0
  17. #define    WTR    1
  18. #define SPC '\040'            /* ascii space */
  19.  
  20. static    int popen_pid[20];
  21. extern char **environ;
  22. char **breakargs();
  23.  
  24. /* no-shell popen */
  25. FILE *
  26. nshpopen(cmd, mode)
  27. char *cmd;
  28. char *mode;
  29. {
  30.     int p[2];
  31.     int myside, hisside, pid;
  32.     char **elist;                /* the execv list */
  33.  
  34.     elist = breakargs(cmd);
  35.     if (pipe(p) < 0)
  36.         return (NULL);
  37.     myside = tst(p[WTR], p[RDR]);
  38.     hisside = tst(p[RDR], p[WTR]);
  39.     if ((pid = vfork()) == 0) {
  40.         /* myside and hisside reverse roles in child */
  41.         close(myside);
  42.         if (hisside != tst(0, 1)) {    /* 0, 1 => stdin, stdout */
  43.             dup2(hisside, tst(0, 1));
  44.             close(hisside);
  45.         }
  46.         execve(elist[0], elist, environ);
  47.         perror("execv");
  48.         _exit(1);            /* bombed execv, child dies */
  49.     }
  50.     free(elist);                /* discard the broken args */
  51.     if (pid == -1) {
  52.         close(myside);
  53.         close(hisside);
  54.         return (NULL);
  55.     }
  56.     popen_pid[myside] = pid;
  57.     close(hisside);
  58.     return (fdopen(myside, mode));
  59. }
  60.  
  61. /* close for nshpopen */
  62. int *
  63. nshpclose(ptr)
  64. FILE *ptr;
  65. {
  66. #ifdef    BSD4_2
  67.     int child, pid, status, omask;
  68.  
  69.     child = popen_pid[fileno(ptr)];
  70.     fclose(ptr);
  71. #define    mask(s)    (1 << ((s)-1))
  72.     omask = sigblock(mask(SIGINT)|mask(SIGQUIT)|mask(SIGHUP));
  73.     while ((pid = wait(&status)) != child && pid != -1)
  74.         /* empty */;
  75.     (void) sigsetmask(omask);
  76.     return (int *)(pid == -1 ? -1 : status);
  77. #else        /* 2.9 BSD, at least */
  78.     register f, r, (*hstat)(), (*istat)(), (*qstat)();
  79.     int status;
  80.  
  81.     f = fileno(ptr);
  82.     fclose(ptr);
  83.     istat = signal(SIGINT, SIG_IGN);
  84.     qstat = signal(SIGQUIT, SIG_IGN);
  85.     hstat = signal(SIGHUP, SIG_IGN);
  86.     while((r = wait(&status)) != popen_pid[f] && r != -1)
  87.         ;
  88.     if(r == -1)
  89.         status = -1;
  90.     signal(SIGINT, istat);
  91.     signal(SIGQUIT, qstat);
  92.     signal(SIGHUP, hstat);
  93.     return (int *)(status);
  94. #endif    BSD4_2
  95. }
  96.