home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / gnu / perl-4.036.tar.gz / perl-4.036.tar / perl-4.036 / os2 / popen.c < prev    next >
C/C++ Source or Header  |  1993-02-08  |  5KB  |  242 lines

  1. /* added real/protect mode branch at runtime and real mode version
  2.  * names changed for perl
  3.  * Kai Uwe Rommel
  4.  */
  5.  
  6. /*
  7. Several people in the past have asked about having Unix-like pipe
  8. calls in OS/2.  The following source file, adapted from 4.3 BSD Unix,
  9. uses a #define to give you a pipe(2) call, and contains function
  10. definitions for popen(3) and pclose(3).  Anyone with problems should
  11. send mail to me; they seem to work fine.
  12.  
  13. Mark Towfigh
  14. Racal Interlan, Inc.
  15. ----------------------------------cut-here------------------------------------
  16. */
  17.  
  18. /*
  19.  * The following code segment is derived from BSD 4.3 Unix.  See
  20.  * copyright below.  Any bugs, questions, improvements, or problems
  21.  * should be sent to Mark Towfigh (towfiq@interlan.interlan.com).
  22.  *
  23.  * Racal InterLan Inc.
  24.  */
  25.  
  26. /*
  27.  * Copyright (c) 1980 Regents of the University of California.
  28.  * All rights reserved.  The Berkeley software License Agreement
  29.  * specifies the terms and conditions for redistribution.
  30.  */
  31.  
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <io.h>
  35. #include <string.h>
  36. #include <process.h>
  37. #include <errno.h>
  38.  
  39. #define INCL_NOPM
  40. #define    INCL_DOS
  41. #include <os2.h>
  42.  
  43. static FILE *dos_popen(const char *cmd, const char *flags);
  44. static int dos_pclose(FILE *pipe);
  45.  
  46. /*
  47.  * emulate Unix pipe(2) call
  48.  */
  49.  
  50. #define    tst(a,b)    (*mode == 'r'? (b) : (a))
  51. #define READH           0
  52. #define WRITEH          1
  53.  
  54. static  int       popen_pid[20];
  55.  
  56. FILE *mypopen(char *cmd, char *mode)
  57. {
  58.     int p[2];
  59.         register myside, hisside, save_stream;
  60.         char *shell = getenv("COMPSPEC");
  61.  
  62.         if ( shell == NULL )
  63.           shell = "C:\\OS2\\CMD.EXE";
  64.  
  65.         if ( _osmode == DOS_MODE )
  66.           return dos_popen(cmd, mode);
  67.  
  68.         if ( _pipe(p, 4096, 0) )
  69.                 return NULL;
  70.  
  71.         myside = tst(p[WRITEH], p[READH]);
  72.         hisside = tst(p[READH], p[WRITEH]);
  73.  
  74.     /* set up file descriptors for remote function */
  75.     save_stream = dup(tst(0, 1));        /* don't lose stdin/out! */
  76.         if (dup2(hisside, tst(0, 1)) < 0)
  77.         {
  78.         perror("dup2");
  79.         return NULL;
  80.     }
  81.         close(hisside);
  82.  
  83.     /*
  84.      * make sure that we can close our side of the pipe, by
  85.      * preventing it from being inherited!
  86.      */
  87.  
  88.     /* set no-inheritance flag */
  89.     DosSetFHandState(myside, OPEN_FLAGS_NOINHERIT);
  90.  
  91.     /* execute the command:  it will inherit our other file descriptors */
  92.         popen_pid[myside] = spawnlp(P_NOWAIT, shell, shell, "/C", cmd, NULL);
  93.  
  94.     /* now restore our previous file descriptors */
  95.         if (dup2(save_stream, tst(0, 1)) < 0)   /* retrieve stdin/out */
  96.         {
  97.         perror("dup2");
  98.         return NULL;
  99.     }
  100.         close(save_stream);
  101.  
  102.     return fdopen(myside, mode);        /* return a FILE pointer */
  103. }
  104.  
  105. int mypclose(FILE *ptr)
  106. {
  107.     register f;
  108.         int status;
  109.  
  110.         if ( _osmode == DOS_MODE )
  111.           return dos_pclose(ptr);
  112.  
  113.     f = fileno(ptr);
  114.         fclose(ptr);
  115.  
  116.     /* wait for process to terminate */
  117.     cwait(&status, popen_pid[f], WAIT_GRANDCHILD);
  118.  
  119.     return status;
  120. }
  121.  
  122.  
  123. int pipe(int *filedes)
  124. {
  125.   int res;
  126.  
  127.   if ( res = _pipe(filedes, 4096, 0) )
  128.     return res;
  129.  
  130.   DosSetFHandState(filedes[0], OPEN_FLAGS_NOINHERIT);
  131.   DosSetFHandState(filedes[1], OPEN_FLAGS_NOINHERIT);
  132.   return 0;
  133. }
  134.  
  135.  
  136. /* this is the MS-DOS version */
  137.  
  138. typedef enum { unopened = 0, reading, writing } pipemode;
  139.  
  140. static struct
  141. {
  142.     char *name;
  143.     char *command;
  144.     pipemode pmode;
  145. }
  146. pipes[_NFILE];
  147.  
  148. static FILE *dos_popen(const char *command, const char *mode)
  149. {
  150.     FILE *current;
  151.     char name[128];
  152.     char *tmp = getenv("TMP");
  153.     int cur;
  154.     pipemode curmode;
  155.  
  156.     /*
  157.     ** decide on mode.
  158.     */
  159.     if(strchr(mode, 'r') != NULL)
  160.         curmode = reading;
  161.     else if(strchr(mode, 'w') != NULL)
  162.         curmode = writing;
  163.     else
  164.         return NULL;
  165.  
  166.     /*
  167.     ** get a name to use.
  168.     */
  169.     strcpy(name, tmp ? tmp : "\\");
  170.     if ( name[strlen(name) - 1] != '\\' )
  171.       strcat(name, "\\");
  172.     strcat(name, "piXXXXXX");
  173.     mktemp(name);
  174.  
  175.     /*
  176.     ** If we're reading, just call system to get a file filled with
  177.     ** output.
  178.     */
  179.     if(curmode == reading)
  180.     {
  181.         char cmd[256];
  182.         sprintf(cmd,"%s > %s", command, name);
  183.         system(cmd);
  184.  
  185.         if((current = fopen(name, mode)) == NULL)
  186.             return NULL;
  187.     }
  188.     else
  189.     {
  190.         if((current = fopen(name, mode)) == NULL)
  191.             return NULL;
  192.     }
  193.  
  194.     cur = fileno(current);
  195.     pipes[cur].name = strdup(name);
  196.     pipes[cur].command = strdup(command);
  197.     pipes[cur].pmode = curmode;
  198.  
  199.     return current;
  200. }
  201.  
  202. static int dos_pclose(FILE * current)
  203. {
  204.     int cur = fileno(current), rval;
  205.     char command[256];
  206.  
  207.     /*
  208.     ** check for an open file.
  209.     */
  210.     if(pipes[cur].pmode == unopened)
  211.         return -1;
  212.  
  213.     if(pipes[cur].pmode == reading)
  214.     {
  215.         /*
  216.         ** input pipes are just files we're done with.
  217.         */
  218.         rval = fclose(current);
  219.         unlink(pipes[cur].name);
  220.     }
  221.     else
  222.     {
  223.         /*
  224.         ** output pipes are temporary files we have
  225.         ** to cram down the throats of programs.
  226.         */
  227.         fclose(current);
  228.         sprintf(command,"%s < %s", pipes[cur].command, pipes[cur].name);
  229.         rval = system(command);
  230.         unlink(pipes[cur].name);
  231.     }
  232.  
  233.     /*
  234.     ** clean up current pipe.
  235.     */
  236.     free(pipes[cur].name);
  237.     free(pipes[cur].command);
  238.     pipes[cur].pmode = unopened;
  239.  
  240.     return rval;
  241. }
  242.