home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- *
- * $Source: /unixb/home/unixlib/source/unixlib37/src/stdio/c/RCS/popen,v $
- * $Date: 1996/10/30 21:59:00 $
- * $Revision: 1.3 $
- * $State: Rel $
- * $Author: unixlib $
- *
- * $Log: popen,v $
- * Revision 1.3 1996/10/30 21:59:00 unixlib
- * Massive changes made by Nick Burret and Peter Burwood.
- *
- * Revision 1.2 1996/05/06 09:01:34 unixlib
- * Updates to sources made by Nick Burrett, Peter Burwood and Simon Callan.
- * Saved for 3.7a release.
- *
- * Revision 1.1 1996/04/19 21:32:42 simon
- * Initial revision
- *
- ***************************************************************************/
-
- static const char rcs_id[] = "$Id: popen,v 1.3 1996/10/30 21:59:00 unixlib Rel $";
-
- #include <errno.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <unistd.h>
-
- #include <sys/param.h>
- #include <sys/wait.h>
-
- __STDIOLIB__
-
- struct pwr
- {
- FILE *f;
- int p0;
- char *command;
- struct pwr *next;
- };
-
- static struct pwr *__pwr = 0;
-
- static void
- __pexec (const char *command)
- {
- char *shell, *path;
-
- if (!(path = getenv ("SHELL")))
- if (execl (command, "", 0))
- _exit (1);
-
- 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
- {
- 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);
- }
-
- /* never reached */
-
- return (0);
- }
-
- int
- pclose (FILE * f)
- {
- int r;
-
- if (!fispipe (f))
- return (-1);
-
- 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);
- }
-
- r = (wait (0) >> 8);
-
- if (fclose (f))
- return (-1);
-
- return (r);
- }
-