#include "cvs.h"
#include "os2inc.h"
#include <process.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <io.h>
#define STDIN 0
#define STDOUT 1
#define STDERR 2
static void run_add_arg( const char *s );
static void run_init_prog( void );
extern char *strtok ();
static char **run_argv;
static int run_argc;
static int run_argc_allocated;
void
run_setup (const char *prog)
{
int i;
char *run_prog;
char *buf, *d, *s;
size_t length;
size_t doff;
char inquotes;
int dolastarg;
for (i = 0; i < run_argc; i++)
{
if (run_argv[i])
{
free (run_argv[i]);
run_argv[i] = (char *) 0;
}
}
run_argc = 0;
run_prog = xstrdup (prog);
s = run_prog;
d = buf = NULL;
length = 0;
dolastarg = 1;
inquotes = '\0';
doff = d - buf;
expand_string(&buf, &length, doff + 1);
d = buf + doff;
while (*d = *s++)
{
switch (*d)
{
case '\\':
if (*s) *d = *s++;
d++;
break;
case '"':
case '\'':
if (inquotes == *d) inquotes = '\0';
else inquotes = *d;
break;
case ' ':
case '\t':
if (inquotes) d++;
else
{
*d = '\0';
run_add_arg (buf);
d = buf;
while (isspace(*s)) s++;
if (!*s) dolastarg = 0;
}
break;
default:
d++;
break;
}
doff = d - buf;
expand_string(&buf, &length, doff + 1);
d = buf + doff;
}
if (dolastarg) run_add_arg (buf);
if (buf) free (buf);
free (run_prog);
free (run_prog);
if (buf) free (buf);
}
void
run_arg (s)
const char *s;
{
run_add_arg (s);
}
static char *
quote (const char *s)
{
size_t s_len = strlen (s);
char *copy = xmalloc (s_len + 3);
char *scan = copy;
*scan++ = '"';
strcpy (scan, s);
scan += s_len;
*scan++ = '"';
*scan++ = '\0';
return copy;
}
static void
run_add_arg (s)
const char *s;
{
if (run_argc >= run_argc_allocated)
{
run_argc_allocated += 50;
run_argv = (char **) xrealloc ((char *) run_argv,
run_argc_allocated * sizeof (char **));
}
if (s)
{
run_argv[run_argc] = (run_argc ? quote (s) : xstrdup (s));
run_argc++;
}
else
run_argv[run_argc] = (char *) 0;
}
int
run_exec (stin, stout, sterr, flags)
char *stin;
char *stout;
char *sterr;
int flags;
{
int shin, shout, sherr;
int sain, saout, saerr;
int mode_out, mode_err;
int status = -1;
int rerrno = 0;
int rval = -1;
void (*old_sigint) (int);
if (trace)
{
(void) fprintf (stderr, "-> system(");
run_print (stderr);
(void) fprintf (stderr, ")\n");
}
if (noexec && (flags & RUN_REALLY) == 0)
return (0);
run_add_arg ((char *) 0);
shin = 0;
shout = 1;
sherr = 2;
mode_out = mode_err = O_WRONLY | O_CREAT;
mode_out |= ((flags & RUN_STDOUT_APPEND) ? O_APPEND : O_TRUNC);
mode_err |= ((flags & RUN_STDERR_APPEND) ? O_APPEND : O_TRUNC);
if (stin && (shin = open (stin, O_RDONLY)) == -1)
{
rerrno = errno;
error (0, errno, "cannot open %s for reading (prog %s)",
stin, run_argv[0]);
goto out0;
}
if (stout && (shout = open (stout, mode_out, 0666)) == -1)
{
rerrno = errno;
error (0, errno, "cannot open %s for writing (prog %s)",
stout, run_argv[0]);
goto out1;
}
if (sterr && (flags & RUN_COMBINED) == 0)
{
if ((sherr = open (sterr, mode_err, 0666)) == -1)
{
rerrno = errno;
error (0, errno, "cannot open %s for writing (prog %s)",
sterr, run_argv[0]);
goto out2;
}
}
sain = saout = saerr = -1;
sain = dup( 0);
saout = dup( 1);
saerr = dup( 2);
if (shin != 0)
{
(void) dup2 (shin, 0);
(void) close (shin);
}
if (shout != 1)
{
(void) dup2 (shout, 1);
(void) close (shout);
}
if (flags & RUN_COMBINED)
(void) dup2 (1, 2);
else if (sherr != 2)
{
(void) dup2 (sherr, 2);
(void) close (sherr);
}
old_sigint = signal (SIGINT, SIG_IGN);
rval = spawnvp ( P_WAIT, run_argv[0], run_argv);
signal (SIGINT, old_sigint);
if (sain != -1) {
(void) dup2( sain, 0);
(void) close( sain);
}
if (saout != -1) {
(void) dup2( saout, 1);
(void) close( saout);
}
if (saerr != -1) {
(void) dup2( saerr, 2);
(void) close( saerr);
}
if (rval == -1)
return 2;
else
return rval;
out2:
if (stout)
(void) close (shout);
out1:
if (stin)
(void) close (shin);
out0:
if (rerrno)
errno = rerrno;
return (status);
}
void
run_print (fp)
FILE *fp;
{
int i;
for (i = 0; i < run_argc; i++)
{
(void) fprintf (fp, "'%s'", run_argv[i]);
if (i != run_argc - 1)
(void) fprintf (fp, " ");
}
}
static char *
requote (const char *cmd)
{
char *requoted = xmalloc (strlen (cmd) + 1);
char *p = requoted;
strcpy (requoted, cmd);
while ((p = strchr (p, '\'')) != NULL)
{
*p++ = '"';
}
return requoted;
}
FILE *
run_popen (cmd, mode)
const char *cmd;
const char *mode;
{
TRACE( TRACE_FUNCTION, "run_popen(%s,%s)", cmd, mode );
if (noexec)
return (NULL);
{
char *requoted = requote (cmd);
TRACE( TRACE_DATA, "Executing popen(%s,%s)", requoted, mode );
FILE *result = popen (requoted, mode);
free (requoted);
return result;
}
}
static int
my_pipe (int *readwrite)
{
fprintf (stderr,
"Error: my_pipe() is unimplemented.\n");
exit (1);
}
static int
start_child (char *command, int in, int out)
{
fprintf (stderr,
"Error: start_child() is unimplemented.\n");
exit (1);
}
static char *
build_command (char **argv)
{
int len;
{
int i;
len = 0;
for (i = 0; argv[i]; i++)
{
char *p;
len += 2;
for (p = argv[i]; *p; p++)
{
if (*p == '"')
len += 2;
else
len++;
}
}
len++;
}
{
char *command = (char *) xmalloc (len);
int i;
char *p;
if (! command)
{
errno = ENOMEM;
return command;
}
p = command;
for (i = 0; argv[i]; i++)
{
char *a;
*p++ = '"';
for (a = argv[i]; *a; a++)
{
if (*a == '"')
*p++ = '\\', *p++ = '"';
else
*p++ = *a;
}
*p++ = '"';
*p++ = ' ';
}
p[-1] = '\0';
return command;
}
}
int
piped_child (char **argv, int *to, int *from)
{
fprintf (stderr,
"Error: piped_child() is unimplemented.\n");
exit (1);
}
int
filter_stream_through_program (int oldfd, int dir,
char **prog, int *pidp)
{
int newfd;
HFILE from, to;
HFILE Old0 = -1, Old1 = -1, Old2 = -1, Tmp;
if (DosCreatePipe (&from, &to, 4096))
return FALSE;
DosDupHandle (STDIN, &Old0);
DosSetFHState (Old1, OPEN_FLAGS_NOINHERIT);
DosDupHandle (STDOUT, &Old1);
DosSetFHState (Old2, OPEN_FLAGS_NOINHERIT);
DosDupHandle (STDERR, &Old2);
DosSetFHState (Old2, OPEN_FLAGS_NOINHERIT);
if (dir)
{
Tmp = STDIN;
DosDupHandle (oldfd, &Tmp);
Tmp = STDOUT;
DosDupHandle (to, &Tmp);
Tmp = STDERR;
DosDupHandle (to, &Tmp);
newfd = from;
_setmode (newfd, O_BINARY);
DosClose (oldfd);
DosClose (to);
DosSetFHState (from, OPEN_FLAGS_NOINHERIT);
}
else
{
Tmp = STDIN;
DosDupHandle (from, &Tmp);
Tmp = STDOUT;
DosDupHandle (oldfd, &Tmp);
Tmp = STDERR;
DosDupHandle (oldfd, &Tmp);
newfd = to;
_setmode (newfd, O_BINARY);
DosClose (oldfd);
DosClose (from);
DosSetFHState (to, OPEN_FLAGS_NOINHERIT);
}
*pidp = spawnvp (P_NOWAIT, prog[0], prog);
Tmp = STDIN;
DosDupHandle (Old0, &Tmp);
DosClose (Old0);
Tmp = STDOUT;
DosDupHandle (Old1, &Tmp);
DosClose (Old1);
Tmp = STDERR;
DosDupHandle (Old2, &Tmp);
DosClose (Old2);
if(*pidp < 0)
{
DosClose (from);
DosClose (to);
error (1, 0, "error spawning %s", prog[0]);
}
return newfd;
}
int
pipe (int *filedesc)
{
fprintf (stderr,
"Error: pipe() should not have been called in client.\n");
exit (1);
}
void
close_on_exec (int fd)
{
}
#ifndef sleep
unsigned int
sleep (unsigned int seconds)
{
time_t base;
time_t tick;
int i;
time (&base);
time (&tick);
while (difftime (tick, base) < seconds)
{
for (i = 0; i < 10000; i++)
;
time (&tick);
}
return 0;
}
#endif