home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 4 / DATAFILE_PDCD4.iso / unix / unixlib36d / src / stdio / c / popen < prev    next >
Encoding:
Text File  |  1994-03-08  |  2.9 KB  |  201 lines

  1. static char sccs_id[] = "@(#) popen.c 2.0 " __DATE__ " HJR";
  2.  
  3. /* popen.c (c) Copyright 1990 H.Rogers */
  4.  
  5. #include <errno.h>
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9.  
  10. #include "sys/param.h"
  11.  
  12. extern int execl (char *,...);
  13. extern int wait (int *);
  14. extern int vfork (void);
  15. extern int fork (void);
  16. extern int pipe (int *);
  17. extern int close (int);
  18. extern int dup2 (int, int);
  19. extern void _exit (int);
  20.  
  21. __STDIOLIB__
  22.  
  23. #ifdef ARCH
  24. struct pwr
  25.   {
  26.     FILE *f;
  27.     int p0;
  28.     char *command;
  29.     struct pwr *next;
  30.   };
  31.  
  32. static struct pwr *__pwr = 0;
  33.  
  34. #define fork() vfork()
  35. #endif
  36.  
  37. static void
  38. __pexec (const char *command)
  39. {
  40.   char *shell, *path;
  41.  
  42. #ifdef ARCH
  43.   if (!(path = getenv ("SHELL")))
  44.     if (execl ((char *) command, "", 0))
  45.       _exit (1);
  46. #else
  47.   if (!(path = getenv ("SHELL")))
  48.     path = "/bin/sh";
  49. #endif
  50.   shell = strrchr (path, '/');
  51.   if (shell)
  52.     shell++;
  53.   else
  54.     shell = path;
  55.   if (execl (path, shell, "-c", (char *) command, 0))
  56.     _exit (1);
  57. }
  58.  
  59. FILE *
  60. popen (const char *command, const char *mode)
  61. {
  62.   FILE *f;
  63.   int p[2];
  64.  
  65.   if (pipe (p) < 0)
  66.     return (0);
  67.  
  68.   if (*mode == 'r')
  69.     switch (fork ())
  70.       {
  71.       case -1:
  72.     close (p[0]);
  73.     close (p[1]);
  74.     return (0);
  75.     break;
  76.       case 0:
  77.     close (p[0]);
  78.     dup2 (p[1], 1);
  79.     close (p[1]);
  80.     __pexec (command);
  81.     break;
  82.       default:
  83.     close (p[1]);
  84.     if (!(f = fdopen (p[0], mode)))
  85.       return (0);
  86.     f->flag |= _IOPIPE;
  87.     return (f);
  88.     break;
  89.       }
  90.   else
  91. #ifndef ARCH
  92.     switch (fork ())
  93.       {
  94.       case -1:
  95.     close (p[0]);
  96.     close (p[1]);
  97.     return (0);
  98.     break;
  99.       case 0:
  100.     close (p[1]);
  101.     dup2 (p[0], 0);
  102.     close (p[0]);
  103.     __pexec (command);
  104.     break;
  105.       default:
  106.     close (p[0]);
  107.     if (!(f = fdopen (p[1], mode)))
  108.       return (0);
  109.     f->flag |= _IOPIPE;
  110.     return (f);
  111.     break;
  112.       }
  113. #else
  114.     {
  115.       FILE *f;
  116.       struct pwr *pwr;
  117.  
  118.       if (!(pwr = malloc (sizeof (struct pwr))))
  119.       return (0);
  120.       if (!(pwr->command = strdup (command)))
  121.     {
  122.       free (pwr);
  123.       return (0);
  124.     }
  125.       if (!(f = fdopen (p[1], mode)))
  126.     {
  127.       free (pwr);
  128.       free (pwr->command);
  129.       return (0);
  130.     }
  131.       f->flag |= _IOPIPE;
  132.       pwr->f = f;
  133.       pwr->p0 = p[0];
  134.       pwr->next = __pwr;
  135.       __pwr = pwr;
  136.       return (f);
  137.     }
  138. #endif
  139.  
  140. /* never reached */
  141.  
  142.   return (0);
  143. }
  144.  
  145. int
  146. pclose (FILE * f)
  147. {
  148.   int r;
  149.  
  150.   if (!fispipe (f))
  151.     return (-1);
  152.  
  153. #ifdef ARCH
  154.   if ((f->flag & _IOOMASK) == _IOWRITE)
  155.     {
  156.       struct pwr *pwr = __pwr, *pwr_ = 0;
  157.  
  158.       while (pwr)
  159.     {
  160.       if (pwr->f == f)
  161.         break;
  162.       pwr_ = pwr;
  163.       pwr = pwr->next;
  164.     }
  165.       if (!pwr)
  166.     return (-1);
  167.       if (pwr_)
  168.     pwr_->next = pwr->next;
  169.       else
  170.     __pwr = pwr->next;
  171.       fflush (f);
  172.       switch (fork ())
  173.     {
  174.     case -1:
  175.       close (pwr->p0);
  176.       close (f->fd);
  177.       return (-1);
  178.       break;
  179.     case 0:
  180.       close (f->fd);
  181.       dup2 (pwr->p0, 0);
  182.       close (pwr->p0);
  183.       __pexec (pwr->command);
  184.       break;
  185.     default:
  186.       close (pwr->p0);
  187.       break;
  188.     }
  189.       free (pwr->command);
  190.       free (pwr);
  191.     }
  192. #endif
  193.  
  194.   r = (wait (0) >> 8);
  195.  
  196.   if (fclose (f))
  197.     return (-1);
  198.  
  199.   return (r);
  200. }
  201.