#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 PROTO((const char *s));
static void run_init_prog PROTO((void));
extern char *strtok ();
static char **run_argv;
static int run_argc;
static int run_argc_allocated;
void
run_setup (const char *prog)
{
char *cp;
int i;
char *run_prog;
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);
for (cp = strtok (run_prog, " \t"); cp; cp = strtok ((char *) NULL, " \t"))
run_add_arg (cp);
free (run_prog)
}
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;
{
if (trace)
#ifdef SERVER_SUPPORT
(void) fprintf (stderr, "%c-> run_popen(%s,%s)\n",
(server_active) ? 'S' : ' ', cmd, mode);
#else
(void) fprintf (stderr, "-> run_popen(%s,%s)\n", cmd, mode);
#endif
if (noexec)
return (NULL);
{
char *requoted = requote (cmd);
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 *) malloc (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