home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1709 / sysdos.c < prev    next >
C/C++ Source or Header  |  1990-12-28  |  3KB  |  158 lines

  1. /* sysdos.c  -- DOS version of system.c */
  2.  
  3. /* Author:
  4.  *    Guntram Blohm
  5.  *    Buchenstrasse 19
  6.  *    7904 Erbach, West Germany
  7.  *    Tel. ++49-7305-6997
  8.  *    sorry - no regular network connection
  9.  */
  10.  
  11.  
  12. /* This file is derived from Steve Kirkendall's system.c.
  13.  *
  14.  * Entry points are:
  15.  *    system(cmd)    - run a single shell command
  16.  *    wildcard(names)    - expand wildcard characters in filanames
  17.  *
  18.  * This file is for use with DOS and TOS. For OS/2, slight modifications
  19.  * might be sufficient. For UNIX, use system.c. For Amiga, completely
  20.  * rewrite this stuff.
  21.  *
  22.  * Another system function, filter, is the same on DOS and UNIX and thus
  23.  * can be found in the original system.c.
  24.  */
  25.  
  26. #include "config.h"
  27. #include "vi.h"
  28. extern char **environ;
  29.  
  30.  
  31. #if    MSDOS
  32. #include <process.h>
  33. extern unsigned char _osmajor;
  34. #endif
  35. #if    TOS
  36. #include <osbind.h>
  37. #endif
  38.  
  39. #if    MSDOS || TOS
  40. #include <string.h>
  41.  
  42. /*
  43.  * Calling command is a bit nasty because of the undocumented yet sometimes
  44.  * used feature to change the option char to something else than /.
  45.  * Versions 2.x and 3.x support this, 4.x doesn't.
  46.  *
  47.  * For Atari, some shells define a shortcut entry which is faster than
  48.  * shell -c. Also, Mark Williams uses a special ARGV environment variable
  49.  * to pass more than 128 chars to a called command.
  50.  * We try to support all of these features here.
  51.  */
  52.  
  53. int system(cmd)
  54.     const char    *cmd;
  55. {
  56. #if    MSDOS
  57.     char *cmdswitch="/c";
  58.     if (_osmajor<4)
  59.         cmdswitch[0]=switchar();
  60.     return spawnle(P_WAIT, o_shell, o_shell, cmdswitch, cmd, (char *)0, environ);
  61. #else
  62.     long    ssp;
  63.     int    (*shell)();
  64.     char    line[130];
  65.     char    env[4096], *ep=env;
  66.     int    i;
  67.  
  68. /* does our shell have a shortcut, that we can use? */
  69.  
  70.     ssp = Super(0L);
  71.     shell = *((int (**)())0x4F6);
  72.     Super(ssp);
  73.     if (shell)
  74.         return (*shell)(cmd);
  75.  
  76. /* else we'll have to call a shell ... */
  77.  
  78.     for (i=0; environ[i] && strncmp(environ[i], "ARGV=", 5); i++)
  79.     {    strcpy(ep, environ[i]);
  80.         ep+=strlen(ep)+1;
  81.     }
  82.     if (environ[i])
  83.     {
  84.         strcpy(ep, environ[i]); ep+=strlen(ep)+1;
  85.         strcpy(ep, o_shell); ep+=strlen(ep)+1;
  86.         strcpy(ep, "-c"); ep+=3;
  87.         strcpy(ep, cmd); ep+=strlen(ep)+1;
  88.     }
  89.     *ep='\0';
  90.     strcpy(line+1, "-c ");
  91.     strncat(line+1, cmd, 126);
  92.     line[0]=strlen(line+1);
  93.     return Pexec(0, o_shell, line, env);
  94. #endif
  95. }
  96.  
  97. /* This private function opens a pipe from a filter.  It is similar to the
  98.  * system() function above, and to popen(cmd, "r").
  99.  * sorry - i cant use cmdstate until rpclose, but get it from spawnle.
  100.  */
  101.  
  102. static int cmdstate;
  103. static char output[80];
  104.  
  105. int rpipe(cmd, in)
  106.     char    *cmd;    /* the filter command to use */
  107.     int    in;    /* the fd to use for stdin */
  108. {
  109.     int    fd, old0, old1, old2;
  110.  
  111.     /* create the file that will collect the filter's output */
  112.     strcpy(output, o_directory);
  113.     if ((fd=strlen(output)) && !strchr("/\\:", output[fd-1]))
  114.         output[fd++]=SLASH;
  115.     strcpy(output+fd, SCRATCHIN+3);
  116.     mktemp(output);
  117.     close(creat(output, 0666));
  118.     if ((fd=open(output, O_RDWR))==-1)
  119.     {
  120.         unlink(output);
  121.         return -1;
  122.     }
  123.  
  124.     /* save and redirect stdin, stdout, and stderr */
  125.     old0=dup(0);
  126.     old1=dup(1);
  127.     if (in)
  128.     {
  129.         dup2(in, 0);
  130.         close(in);
  131.     }
  132.     dup2(fd, 1);
  133.  
  134.     /* call command */
  135.     cmdstate=system(cmd);
  136.  
  137.     /* restore old std... */
  138.     dup2(old0, 0); close(old0);
  139.     dup2(old1, 1); close(old1);
  140.  
  141.     /* rewind command output */
  142.     lseek(fd, 0L, 0);
  143.     return fd;
  144. }
  145.  
  146. /* This function closes the pipe opened by rpipe(), and returns 0 for success */
  147. int rpclose(fd)
  148.     int    fd;
  149. {
  150.     int    status;
  151.  
  152.     close(fd);
  153.     unlink(output);
  154.     return cmdstate;
  155. }
  156.  
  157. #endif
  158.