home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / CLISP / CLISPSRC.TAR / clisp-1995-01-01 / os2 / popenrw.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-21  |  2.9 KB  |  105 lines

  1. /* popenrw.c (emx+gcc) -- Copyright (c) 1993 by Bruno Haible */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <process.h>
  7. #include <unistd.h>
  8. #include <io.h>
  9. #include <fcntl.h>
  10. #include <errno.h>
  11.  
  12. int popenrw (const char *command, FILE **rpipe, FILE **wpipe)
  13. {
  14.   int iph[2], oph[2];
  15.   FILE *istream, *ostream;
  16.   const char *sh, *base, *opt;
  17.   int stdin_private, stdout_private, stdin_handle, stdout_handle, saved_errno;
  18.   int i;
  19.  
  20.   /*        write        system        read        */
  21.   /* parent  <-   iph[0]   <-   iph[1]  <-   child */
  22.   /* parent  ->   oph[1]   ->   oph[0]  ->   child */
  23.   /*        read         system        write       */
  24.  
  25.   if (pipe (iph) == -1 || pipe (oph) == -1)
  26.     return -1;
  27.   if (fcntl (iph[0], F_SETFD, 1) == -1 || fcntl (iph[1], F_SETFD, 1) == -1
  28.       || fcntl (oph[0], F_SETFD, 1) == -1 || fcntl (oph[1], F_SETFD, 1) == -1)
  29.     goto fail1;
  30.   stdin_private = fcntl (STDIN_FILENO, F_GETFD, 0);
  31.   stdout_private = fcntl (STDOUT_FILENO, F_GETFD, 0);
  32.   if (stdin_private == -1 || stdout_private == -1)
  33.     goto fail1;
  34.   stdin_handle = dup (STDIN_FILENO);
  35.   if (stdin_handle == -1)
  36.     goto fail1;
  37.   stdout_handle = dup (STDOUT_FILENO);
  38.   if (stdout_handle == -1)
  39.     goto fail1;
  40.   fcntl (stdin_handle, F_SETFD, 1);
  41.   fcntl (stdout_handle, F_SETFD, 1);
  42.   if (close (STDIN_FILENO) == -1 || close (STDOUT_FILENO) == -1)
  43.     goto fail2;
  44.   i = dup (oph[0]);
  45.   if (i != STDIN_FILENO)
  46.     { errno = EBADF; goto fail2; }
  47.   i = dup (iph[1]);
  48.   if (i != STDOUT_FILENO)
  49.     { errno = EBADF; goto fail2; }
  50.   if (close (oph[0]) == -1)
  51.     goto fail2;
  52.   if (close (iph[1]) == -1)
  53.     goto fail2;
  54.   istream = fdopen (iph[0], "r");
  55.   if (istream == NULL)
  56.     goto fail2;
  57.   ostream = fdopen (oph[1], "w");
  58.   if (ostream == NULL)
  59.     { fclose (istream); goto fail2; }
  60.   sh = getenv ("EMXSHELL");
  61.   if (sh == NULL)
  62.     sh = getenv ("COMSPEC");
  63.   if (sh == NULL)
  64.     { fclose(istream); fclose(ostream); errno = ENOENT; goto fail2; }
  65.   base = _getname (sh);
  66.   if (stricmp (base, "cmd.exe") == 0 || stricmp (base, "4os2.exe") == 0)
  67.     opt = "/c";
  68.   else
  69.     opt = "-c";
  70.   i = spawnlp (P_NOWAIT, sh, sh, opt, command, NULL);
  71.   if (i == -1)
  72.     { fclose(istream); fclose(ostream); goto fail2; }
  73.   istream->pid = ostream->pid = i;
  74.   close (STDIN_FILENO);
  75.   close (STDOUT_FILENO);
  76.   dup (stdin_handle);
  77.   dup (stdout_handle);
  78.   close (stdin_handle);
  79.   close (stdout_handle);
  80.   fcntl (STDIN_FILENO, F_SETFD, stdin_private);
  81.   fcntl (STDOUT_FILENO, F_SETFD, stdout_private);
  82.   *rpipe = istream;
  83.   *wpipe = ostream;
  84.   return 0;
  85. fail2:
  86.   saved_errno = errno;
  87.   close (STDIN_FILENO);
  88.   close (STDOUT_FILENO);
  89.   dup (stdin_handle);
  90.   dup (stdout_handle);
  91.   close (stdin_handle);
  92.   close (stdout_handle);
  93.   fcntl (STDIN_FILENO, F_SETFD, stdin_private);
  94.   fcntl (STDOUT_FILENO, F_SETFD, stdout_private);
  95.   errno = saved_errno;
  96. fail1:
  97.   saved_errno = errno;
  98.   close (iph[0]);
  99.   close (iph[1]);
  100.   close (oph[0]);
  101.   close (oph[1]);
  102.   errno = saved_errno;
  103.   return -1;
  104. }
  105.