home *** CD-ROM | disk | FTP | other *** search
- static char sccs_id[] = "@(#) popen.c 2.0 " __DATE__ " HJR";
-
- /* popen.c (c) Copyright 1990 H.Rogers */
-
- #include <errno.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
-
- #include "sys/param.h"
-
- extern int execl (char *,...);
- extern int wait (int *);
- extern int vfork (void);
- extern int fork (void);
- extern int pipe (int *);
- extern int close (int);
- extern int dup2 (int, int);
- extern void _exit (int);
-
- __STDIOLIB__
-
- #ifdef ARCH
- struct pwr
- {
- FILE *f;
- int p0;
- char *command;
- struct pwr *next;
- };
-
- static struct pwr *__pwr = 0;
-
- #define fork() vfork()
- #endif
-
- static void
- __pexec (const char *command)
- {
- char *shell, *path;
-
- #ifdef ARCH
- if (!(path = getenv ("SHELL")))
- if (execl ((char *) command, "", 0))
- _exit (1);
- #else
- if (!(path = getenv ("SHELL")))
- path = "/bin/sh";
- #endif
- shell = strrchr (path, '/');
- if (shell)
- shell++;
- else
- shell = path;
- if (execl (path, shell, "-c", (char *) command, 0))
- _exit (1);
- }
-
- FILE *
- popen (const char *command, const char *mode)
- {
- FILE *f;
- int p[2];
-
- if (pipe (p) < 0)
- return (0);
-
- if (*mode == 'r')
- switch (fork ())
- {
- case -1:
- close (p[0]);
- close (p[1]);
- return (0);
- break;
- case 0:
- close (p[0]);
- dup2 (p[1], 1);
- close (p[1]);
- __pexec (command);
- break;
- default:
- close (p[1]);
- if (!(f = fdopen (p[0], mode)))
- return (0);
- f->flag |= _IOPIPE;
- return (f);
- break;
- }
- else
- #ifndef ARCH
- switch (fork ())
- {
- case -1:
- close (p[0]);
- close (p[1]);
- return (0);
- break;
- case 0:
- close (p[1]);
- dup2 (p[0], 0);
- close (p[0]);
- __pexec (command);
- break;
- default:
- close (p[0]);
- if (!(f = fdopen (p[1], mode)))
- return (0);
- f->flag |= _IOPIPE;
- return (f);
- break;
- }
- #else
- {
- FILE *f;
- struct pwr *pwr;
-
- if (!(pwr = malloc (sizeof (struct pwr))))
- return (0);
- if (!(pwr->command = strdup (command)))
- {
- free (pwr);
- return (0);
- }
- if (!(f = fdopen (p[1], mode)))
- {
- free (pwr);
- free (pwr->command);
- return (0);
- }
- f->flag |= _IOPIPE;
- pwr->f = f;
- pwr->p0 = p[0];
- pwr->next = __pwr;
- __pwr = pwr;
- return (f);
- }
- #endif
-
- /* never reached */
-
- return (0);
- }
-
- int
- pclose (FILE * f)
- {
- int r;
-
- if (!fispipe (f))
- return (-1);
-
- #ifdef ARCH
- if ((f->flag & _IOOMASK) == _IOWRITE)
- {
- struct pwr *pwr = __pwr, *pwr_ = 0;
-
- while (pwr)
- {
- if (pwr->f == f)
- break;
- pwr_ = pwr;
- pwr = pwr->next;
- }
- if (!pwr)
- return (-1);
- if (pwr_)
- pwr_->next = pwr->next;
- else
- __pwr = pwr->next;
- fflush (f);
- switch (fork ())
- {
- case -1:
- close (pwr->p0);
- close (f->fd);
- return (-1);
- break;
- case 0:
- close (f->fd);
- dup2 (pwr->p0, 0);
- close (pwr->p0);
- __pexec (pwr->command);
- break;
- default:
- close (pwr->p0);
- break;
- }
- free (pwr->command);
- free (pwr);
- }
- #endif
-
- r = (wait (0) >> 8);
-
- if (fclose (f))
- return (-1);
-
- return (r);
- }
-