home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / emacs-19.28-src.tgz / tar.out / fsf / emacs / unixlib / src / exec.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  3KB  |  144 lines

  1. #include "amiga.h"
  2. #include "processes.h"
  3. #include <amiga/ioctl.h>
  4. #include <exec/memory.h>
  5. #include <dos/dosextens.h>
  6. #include <dos/dostags.h>
  7. #include <string.h>
  8.  
  9. int eexec(char *program, char **argv, int input, int output, int error,
  10.       char *dir, int stacksize)
  11. /* input = -1 -> inherit Input()
  12.    output = -1 -> inherit Output()
  13.    error = -1 -> inherit pr_CES
  14.    error = -2 -> stderr = stdout */
  15. {
  16.   int index, comsize, close_input, close_output, close_error;
  17.   char *combuf, *bp;
  18.   BPTR in, out, err, dirlock;
  19.   int _pseudo_close(int fd);
  20.  
  21.   comsize = 256;
  22.   combuf = malloc(comsize);
  23.  
  24.   if (input == -1)
  25.     {
  26.       in = Input();
  27.       close_input = FALSE;
  28.     }
  29.   else
  30.     {
  31.       if (ioctl(input, _AMIGA_GET_FH, &in) == -1) in = 0;
  32.       close_input = TRUE;
  33.       _pseudo_close(input);
  34.     }
  35.  
  36.   if (output == -1)
  37.     {
  38.       out = Output();
  39.       close_output = FALSE;
  40.     }
  41.   else if (input == output)
  42.     {
  43.       out = in;
  44.       close_output = FALSE;
  45.     }
  46.   else
  47.     {
  48.       if (ioctl(output, _AMIGA_GET_FH, &out) == -1) out = 0;
  49.       close_output = out != in;
  50.       _pseudo_close(output);
  51.     }
  52.  
  53.   if (error == -1)
  54.     {
  55.       err = _us->pr_CES;
  56.       close_error = FALSE;
  57.     }
  58.   else if (error == -2)
  59.     {
  60.       err = out;
  61.       close_error = FALSE;
  62.     }
  63.   else
  64.     {
  65.       if (ioctl(error, _AMIGA_GET_FH, &err) == -1) err = 0;
  66.       close_error = err != out && err != in;
  67.       _pseudo_close(error);
  68.     }
  69.  
  70.   /* pr_CES is not always defined */
  71.   if (in && out && (err || error == -1))
  72.     if (combuf)
  73.       {
  74.     bp = combuf;
  75.     for (index = 0; argv[index] != 0; index++)
  76.       {
  77.         /* Use program as argv[0]. This loses some information, but ... */
  78.         char *arg = index == 0 ? program : argv[index];
  79.         char *s;
  80.         int len;
  81.  
  82.         len = 3;
  83.         s = arg;
  84.         while (*s)
  85.           {
  86.         len++;
  87.         if (*s == '*' || *s == '"' || *s == '\n') len++;
  88.         s++;
  89.           }
  90.         if (bp + len + 1 >= combuf + comsize)
  91.           {
  92.         char *newbuf;
  93.  
  94.         comsize += comsize + len;
  95.         newbuf = realloc(combuf, comsize);
  96.         if (!newbuf) { errno = ENOMEM; goto error; }
  97.         bp = newbuf + (bp - combuf);
  98.         combuf = newbuf;
  99.           }
  100.         *bp++ = ' ';
  101.         *bp++ = '"';
  102.         s = arg;
  103.         while (*s)
  104.           {
  105.         if (*s == '"' || *s == '*') *bp++ = '*';
  106.         else if (*s == '\n') *bp++ = '+';
  107.         *bp++ = *s++;
  108.           }
  109.         *bp++ = '"';
  110.       }
  111.     *bp = '\0';
  112.     if (dir) dirlock = Lock(dir, SHARED_LOCK);
  113.     else dirlock = 0;
  114.  
  115.     if (dirlock || !dir)
  116.       {
  117.         int pid = _start_process(combuf, in, close_input, out, close_output,
  118.                      err, close_error, dirlock, stacksize);
  119.  
  120.         if (pid != -1)
  121.           {
  122.         free(combuf);
  123.         return pid;
  124.           }
  125.       }
  126.     else errno = convert_oserr(IoErr());
  127.     if (dirlock) UnLock(dirlock);
  128.       }
  129.     else errno = ENOMEM;
  130.  
  131.  error:
  132.   if (in && close_input) Close(in);
  133.   if (out && close_output) Close(out);
  134.   if (err && close_error) Close(err);
  135.   if (combuf) free(combuf);
  136.   return -1;
  137. }
  138.  
  139. int exec(char *program, char **argv, int input, int output, 
  140.       char *dir, int stacksize)
  141. {
  142.   return eexec(program, argv, input, output, -1, dir, stacksize);
  143. }
  144.