home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / CLIPPER / MISC / EMXLIB8F.ZIP / EMX / LIB / IO / POPEN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-03  |  2.7 KB  |  121 lines

  1. /* popen.c (emx+gcc) -- Copyright (c) 1992-1993 by Eberhard Mattes */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <process.h>
  7. #include <io.h>
  8. #include <unistd.h>
  9. #include <fcntl.h>
  10. #include <errno.h>
  11.  
  12. static void restore (int org_handle, int org_private, int handle)
  13. {
  14.   int saved_errno;
  15.  
  16.   saved_errno = errno;
  17.   close (handle);
  18.   dup (org_handle);
  19.   close (org_handle);
  20.   fcntl (handle, F_SETFD, org_private);
  21.   errno = saved_errno;
  22. }
  23.  
  24. static FILE *make_pipe (int pipe_local, int pipe_remote, int handle,
  25.                         const char *command, const char *mode)
  26. {
  27.   int i, org_handle, org_private;
  28.   FILE *f;
  29.   const char *sh, *add = " /c ";
  30.   char *tmp, **argv;
  31.  
  32.   fcntl (pipe_local, F_SETFD, 1);
  33.   org_private = fcntl (handle, F_GETFD, 0);
  34.   if (org_private == -1)
  35.     return (NULL);
  36.   org_handle = dup (handle);
  37.   if (org_handle == -1)
  38.     return (NULL);
  39.   fcntl (org_handle, F_SETFD, 1);
  40.   if (close (handle) == -1)
  41.     return (NULL);
  42.   i = dup (pipe_remote);
  43.   if (i != handle)
  44.     {
  45.       restore (org_handle, org_private, handle);
  46.       errno = EBADF;
  47.       return (NULL);
  48.     }
  49.   if (close (pipe_remote) == -1)
  50.     {
  51.       restore (org_handle, org_private, handle);
  52.       return (NULL);
  53.     }
  54.   f = fdopen (pipe_local, mode);
  55.   if (f == NULL)
  56.     {
  57.       restore (org_handle, org_private, handle);
  58.       return (NULL);
  59.     }
  60.   sh = getenv ("COMSPEC");
  61.   if (sh == NULL)
  62.     {
  63.       fclose (f);
  64.       restore (org_handle, org_private, handle);
  65.       errno = ENOENT;
  66.       return (NULL);
  67.     }
  68.   tmp = malloc (strlen (sh) + strlen (add) + strlen (command) + 1);
  69.   if (tmp == NULL)
  70.     {
  71.       errno = ENOMEM;
  72.       return (NULL);
  73.     }
  74.   strcpy (tmp, sh);
  75.   strcat (tmp, add);
  76.   strcat (tmp, command);
  77.   argv = _splitargs (tmp, NULL);
  78.   free (tmp);
  79.   if (argv == NULL)
  80.     return (NULL);
  81.   i = spawnvp (P_NOWAIT, argv[0], (char const * const *)argv);
  82.   free (argv);
  83.   if (i == -1)
  84.     {
  85.       fclose (f);
  86.       f = NULL;
  87.     }
  88.   f->pid = i;
  89.   restore (org_handle, org_private, handle);
  90.   return (f);
  91. }
  92.  
  93.  
  94. FILE *popen (const char *command, const char *mode)
  95. {
  96.   int ph[2];
  97.   FILE *stream;
  98.  
  99.   if (mode[0] != 'r' && mode[0] != 'w')
  100.     {
  101.       errno = EINVAL;
  102.       return (NULL);
  103.     }
  104.   if (pipe (ph) == -1)
  105.     return (NULL);
  106.   if (fcntl (ph[0], F_SETFD, 1) == -1)
  107.     return (NULL);
  108.   if (fcntl (ph[1], F_SETFD, 1) == -1)
  109.     return (NULL);
  110.   if (mode[0] == 'r')
  111.     stream = make_pipe (ph[0], ph[1], STDOUT_FILENO, command, mode);
  112.   else
  113.     stream = make_pipe (ph[1], ph[0], STDIN_FILENO, command, mode);
  114.   if (stream == NULL)
  115.     {
  116.       close (ph[0]);
  117.       close (ph[1]);
  118.     }
  119.   return (stream);
  120. }
  121.