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 >
Wrap
C/C++ Source or Header
|
1996-09-28
|
3KB
|
144 lines
#include "amiga.h"
#include "processes.h"
#include <amiga/ioctl.h>
#include <exec/memory.h>
#include <dos/dosextens.h>
#include <dos/dostags.h>
#include <string.h>
int eexec(char *program, char **argv, int input, int output, int error,
char *dir, int stacksize)
/* input = -1 -> inherit Input()
output = -1 -> inherit Output()
error = -1 -> inherit pr_CES
error = -2 -> stderr = stdout */
{
int index, comsize, close_input, close_output, close_error;
char *combuf, *bp;
BPTR in, out, err, dirlock;
int _pseudo_close(int fd);
comsize = 256;
combuf = malloc(comsize);
if (input == -1)
{
in = Input();
close_input = FALSE;
}
else
{
if (ioctl(input, _AMIGA_GET_FH, &in) == -1) in = 0;
close_input = TRUE;
_pseudo_close(input);
}
if (output == -1)
{
out = Output();
close_output = FALSE;
}
else if (input == output)
{
out = in;
close_output = FALSE;
}
else
{
if (ioctl(output, _AMIGA_GET_FH, &out) == -1) out = 0;
close_output = out != in;
_pseudo_close(output);
}
if (error == -1)
{
err = _us->pr_CES;
close_error = FALSE;
}
else if (error == -2)
{
err = out;
close_error = FALSE;
}
else
{
if (ioctl(error, _AMIGA_GET_FH, &err) == -1) err = 0;
close_error = err != out && err != in;
_pseudo_close(error);
}
/* pr_CES is not always defined */
if (in && out && (err || error == -1))
if (combuf)
{
bp = combuf;
for (index = 0; argv[index] != 0; index++)
{
/* Use program as argv[0]. This loses some information, but ... */
char *arg = index == 0 ? program : argv[index];
char *s;
int len;
len = 3;
s = arg;
while (*s)
{
len++;
if (*s == '*' || *s == '"' || *s == '\n') len++;
s++;
}
if (bp + len + 1 >= combuf + comsize)
{
char *newbuf;
comsize += comsize + len;
newbuf = realloc(combuf, comsize);
if (!newbuf) { errno = ENOMEM; goto error; }
bp = newbuf + (bp - combuf);
combuf = newbuf;
}
*bp++ = ' ';
*bp++ = '"';
s = arg;
while (*s)
{
if (*s == '"' || *s == '*') *bp++ = '*';
else if (*s == '\n') *bp++ = '+';
*bp++ = *s++;
}
*bp++ = '"';
}
*bp = '\0';
if (dir) dirlock = Lock(dir, SHARED_LOCK);
else dirlock = 0;
if (dirlock || !dir)
{
int pid = _start_process(combuf, in, close_input, out, close_output,
err, close_error, dirlock, stacksize);
if (pid != -1)
{
free(combuf);
return pid;
}
}
else errno = convert_oserr(IoErr());
if (dirlock) UnLock(dirlock);
}
else errno = ENOMEM;
error:
if (in && close_input) Close(in);
if (out && close_output) Close(out);
if (err && close_error) Close(err);
if (combuf) free(combuf);
return -1;
}
int exec(char *program, char **argv, int input, int output,
char *dir, int stacksize)
{
return eexec(program, argv, input, output, -1, dir, stacksize);
}