home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 2 / crawlyvol2.bin / apps / text_ed / elv16b2 / st / sysdos.c < prev    next >
C/C++ Source or Header  |  1992-05-13  |  5KB  |  233 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. #if MSDOS || MINT
  31. #include <process.h>
  32. # if MSDOS
  33. extern unsigned char _osmajor;
  34. # endif
  35. #endif
  36. #if TOS || MINT
  37. #include <osbind.h>
  38. #endif
  39. #if MINT
  40. #include <stdio.h>
  41. #endif
  42.  
  43. #if MSDOS || TOS || MINT
  44. #include <string.h>
  45.  
  46. /*
  47.  * Calling command is a bit nasty because of the undocumented yet sometimes
  48.  * used feature to change the option char to something else than /.
  49.  * Versions 2.x and 3.x support this, 4.x doesn't.
  50.  *
  51.  * For Atari, some shells define a shortcut entry which is faster than
  52.  * shell -c. Also, Mark Williams uses a special ARGV environment variable
  53.  * to pass more than 128 chars to a called command.
  54.  * We try to support all of these features here.
  55.  */
  56.  
  57. int system(cmd)
  58.     const char    *cmd;
  59. {
  60. #if MSDOS || MINT
  61. # if MINT
  62.     static char *extensions[] = { "ttp", "prg", "tos", NULL };
  63.     extern char *findfile (char *, char *, char **);
  64.     extern char *getenv();
  65.  
  66.     char **argv = 0, *cmdcopy = 0, **argp, *path, *p;
  67.     int ret;
  68.     size_t clen;
  69.     static char cmdpath[FILENAME_MAX];
  70.  
  71.     long    ssp;
  72.     int    (*shell)();
  73.  
  74.     if (cmd == o_shell)
  75.         return spawnlp(P_WAIT, o_shell, o_shell, (char *)0);
  76.  
  77.     if (!getenv("NO_SHELLP")) {
  78.         ssp = Super(0L);
  79.         shell = *((int (**)())0x4F6);
  80.         (void) Super(ssp);
  81.         if (shell)
  82.             return (*shell)(cmd);
  83.     }
  84.  
  85.     /* see if cmd is simple enough so that we don't need a shell */
  86.     if ((path = getenv("PATH")) && (clen = strlen(cmd)) &&
  87.         !strpbrk(cmd, "'\"`><;$~[*?&|(){}") &&
  88.         (argv = (char **) malloc((clen/2+2) * sizeof(char *))) &&
  89.         (cmdcopy = strdup(cmd)) &&
  90.         (p = findfile(strtok(cmdcopy, " \t"), path, extensions))) {
  91.         argp = argv;
  92.         *argp++ = strcpy(cmdpath, p);
  93.         while (*argp++ = strtok((char *) NULL, " \t"))
  94.             ;
  95.         errno = 0;
  96.         ret = spawnv(P_WAIT, p, argv);
  97.         free(argv);
  98.         free(cmdcopy);
  99.         if (ret != -1 || errno != ENOEXEC)
  100.             return ret;
  101.     }
  102.     if (argv)
  103.         free(argv);
  104.     if (cmdcopy)
  105.         free(cmdcopy);
  106.     return spawnlp(P_WAIT, o_shell, o_shell, "-c", cmd, (char *)0);
  107. # else
  108.     char *cmdswitch="/c";
  109.     if (_osmajor<4)
  110.         cmdswitch[0]=switchar();
  111.     return spawnle(P_WAIT, o_shell, o_shell, cmdswitch, cmd, (char *)0, environ);
  112. # endif
  113. #else
  114.     long    ssp;
  115.     int    (*shell)();
  116.     char    line[130];
  117.     char    env[4096], *ep=env;
  118.     int    i;
  119.  
  120. /* does our shell have a shortcut, that we can use? */
  121.  
  122.     ssp = Super(0L);
  123.     shell = *((int (**)())0x4F6);
  124.     Super(ssp);
  125.     if (shell)
  126.         return (*shell)(cmd);
  127.  
  128. /* else we'll have to call a shell ... */
  129.  
  130.     for (i=0; environ[i] && strncmp(environ[i], "ARGV=", 5); i++)
  131.     {    strcpy(ep, environ[i]);
  132.         ep+=strlen(ep)+1;
  133.     }
  134.     if (environ[i])
  135.     {
  136.         strcpy(ep, environ[i]); ep+=strlen(ep)+1;
  137.         strcpy(ep, o_shell); ep+=strlen(ep)+1;
  138.         strcpy(ep, "-c"); ep+=3;
  139.         strcpy(ep, cmd); ep+=strlen(ep)+1;
  140.     }
  141.     *ep='\0';
  142.     strcpy(line+1, "-c ");
  143.     strncat(line+1, cmd, 126);
  144.     line[0]=strlen(line+1);
  145.     return Pexec(0, o_shell, line, env);
  146. #endif
  147. }
  148.  
  149. /* This private function opens a pipe from a filter.  It is similar to the
  150.  * system() function above, and to popen(cmd, "r").
  151.  * sorry - i cant use cmdstate until rpclose, but get it from spawnle.
  152.  */
  153.  
  154. static int cmdstate;
  155. static char output[80];
  156.  
  157. #if MINT
  158. /* MiNT uses real pipes if it can... (wich means unless running vanilla TOS.) */
  159. int trpipe(cmd, in)
  160. #else
  161. int rpipe(cmd, in)
  162. #endif
  163.     char    *cmd;    /* the filter command to use */
  164.     int    in;    /* the fd to use for stdin */
  165. {
  166.     int    fd, old0, old1, old2;
  167.  
  168.     /* create the file that will collect the filter's output */
  169.     strcpy(output, o_directory);
  170.     if ((fd=strlen(output)) && !strchr("/\\:", output[fd-1]))
  171.         output[fd++]=SLASH;
  172.     strcpy(output+fd, SCRATCHIN+3);
  173.     mktemp(output);
  174.     close(creat(output, 0666));
  175.     if ((fd=open(output, O_RDWR))==-1)
  176.     {
  177.         unlink(output);
  178.         return -1;
  179.     }
  180.  
  181.     /* save and redirect stdin, stdout, and stderr */
  182.     old0=dup(0);
  183.     old1=dup(1);
  184. #if MINT
  185.     /* ... and stderr :-) */
  186.     old2=dup(2);
  187. #endif
  188.     if (in)
  189.     {
  190.         dup2(in, 0);
  191.         close(in);
  192.     }
  193.     dup2(fd, 1);
  194. #if MINT
  195.     dup2(fd, 2);
  196. #endif
  197.  
  198.     /* call command */
  199.     cmdstate=system(cmd);
  200.  
  201.     /* restore old std... */
  202.     dup2(old0, 0); close(old0);
  203.     dup2(old1, 1); close(old1);
  204. #if MINT
  205.     dup2(old2, 2); close(old2);
  206. #endif
  207.  
  208.     /* rewind command output */
  209. #if TOS || MINT
  210.     /* GEMDOS redirection bugs department... */
  211.     close(fd);
  212.     fd=open(output, O_RDWR);
  213. #else
  214.     lseek(fd, 0L, 0);
  215. #endif
  216.     return fd;
  217. }
  218.  
  219. /* This function closes the pipe opened by rpipe(), and returns 0 for success */
  220. #if MINT
  221. int trpclose(fd)
  222. #else
  223. int rpclose(fd)
  224. #endif
  225.     int    fd;
  226. {
  227.     close(fd);
  228.     unlink(output);
  229.     return cmdstate;
  230. }
  231.  
  232. #endif
  233.