|
Packit Service |
f629e6 |
#include <stdio.h>
|
|
Packit Service |
f629e6 |
#include <stdlib.h>
|
|
Packit Service |
f629e6 |
#include <io.h>
|
|
Packit Service |
f629e6 |
#include <string.h>
|
|
Packit Service |
f629e6 |
#include <process.h>
|
|
Packit Service |
f629e6 |
#include <errno.h>
|
|
Packit Service |
f629e6 |
#include "popen.h"
|
|
Packit Service |
f629e6 |
#undef popen
|
|
Packit Service |
f629e6 |
#undef pclose
|
|
Packit Service |
f629e6 |
#undef system
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#ifndef _NFILE
|
|
Packit Service |
f629e6 |
#define _NFILE 40
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static struct {
|
|
Packit Service |
f629e6 |
char *command;
|
|
Packit Service |
f629e6 |
char *name;
|
|
Packit Service |
f629e6 |
char pmode[4];
|
|
Packit Service |
f629e6 |
} pipes[_NFILE];
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* For systems where system() and popen() do not follow SHELL:
|
|
Packit Service |
f629e6 |
* 1. Write command to temp file. Temp filename must have slashes
|
|
Packit Service |
f629e6 |
* compatible with SHELL (if set) or COMSPEC.
|
|
Packit Service |
f629e6 |
* 2. Convert slashes in SHELL (if present) to be compatible with COMSPEC.
|
|
Packit Service |
f629e6 |
* Currently, only MSC (running under DOS) and MINGW versions are managed.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#if defined(__MINGW32__)
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#define WIN32_LEAN_AND_MEAN
|
|
Packit Service |
f629e6 |
#include <windows.h>
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#if 0
|
|
Packit Service |
f629e6 |
static int
|
|
Packit Service |
f629e6 |
unixshell(char *p)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
static char *shell[] = {"sh", "bash", "csh", "tcsh", "sh32", "sh16", "ksh", NULL};
|
|
Packit Service |
f629e6 |
char **shellp = shell, *s, *q;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (p == NULL) return (0);
|
|
Packit Service |
f629e6 |
s = p = strdup(p);
|
|
Packit Service |
f629e6 |
if ((q = strrchr(p, '\\')) != NULL)
|
|
Packit Service |
f629e6 |
p = q + 1;
|
|
Packit Service |
f629e6 |
if ((q = strrchr(p, '/')) != NULL)
|
|
Packit Service |
f629e6 |
p = q + 1;
|
|
Packit Service |
f629e6 |
if ((q = strchr(p, '.')) != NULL)
|
|
Packit Service |
f629e6 |
*q = '\0';
|
|
Packit Service |
f629e6 |
strlwr(p);
|
|
Packit Service |
f629e6 |
do {
|
|
Packit Service |
f629e6 |
if (strcmp(*shellp, p) == 0) break;
|
|
Packit Service |
f629e6 |
} while (*++shellp);
|
|
Packit Service |
f629e6 |
free(s);
|
|
Packit Service |
f629e6 |
return(*shellp ? 1 : 0);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static char *
|
|
Packit Service |
f629e6 |
slashify(char *p, char *s)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
if (unixshell(s))
|
|
Packit Service |
f629e6 |
while (s = strchr(p, '\\')) *s = '/';
|
|
Packit Service |
f629e6 |
else
|
|
Packit Service |
f629e6 |
while (s = strchr(p, '/')) *s = '\\';
|
|
Packit Service |
f629e6 |
return(p);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static char *
|
|
Packit Service |
f629e6 |
scriptify(const char *command)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
FILE *fp;
|
|
Packit Service |
f629e6 |
char *cmd, *name, *s, *p;
|
|
Packit Service |
f629e6 |
int i;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if((name = tempnam(".", "pip")) == NULL) return(NULL);
|
|
Packit Service |
f629e6 |
p = getenv("COMSPEC"); s = getenv("SHELL");
|
|
Packit Service |
f629e6 |
cmd = malloc(strlen(name) + (s ? strlen(s) : 0) + 9); *cmd = '\0';
|
|
Packit Service |
f629e6 |
if (s) {
|
|
Packit Service |
f629e6 |
slashify(strcpy(cmd, s), p);
|
|
Packit Service |
f629e6 |
p = s;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
slashify(name, p);
|
|
Packit Service |
f629e6 |
if (! (i = unixshell(p))) {
|
|
Packit Service |
f629e6 |
char *p = (char *) realloc(name, strlen(name) + 5);
|
|
Packit Service |
f629e6 |
if (p == NULL) {
|
|
Packit Service |
f629e6 |
free(cmd);
|
|
Packit Service |
f629e6 |
return NULL;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
name = p;
|
|
Packit Service |
f629e6 |
strcat(name, ".bat");
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
if (s) sprintf(cmd + strlen(cmd), " %cc ", unixshell(s) ? '-' : '/');
|
|
Packit Service |
f629e6 |
strcpy(p = cmd + strlen(cmd), name); free(name);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if ((fp = fopen(p, i ? "wb" : "w")) != NULL) {
|
|
Packit Service |
f629e6 |
if (! i) fputs("@echo off\n", fp);
|
|
Packit Service |
f629e6 |
i = strlen(command);
|
|
Packit Service |
f629e6 |
if ((fwrite(command, 1, i, fp) < i) || (fputc('\n', fp) == EOF)) {
|
|
Packit Service |
f629e6 |
free(cmd);
|
|
Packit Service |
f629e6 |
cmd = NULL;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
} else {
|
|
Packit Service |
f629e6 |
free(cmd);
|
|
Packit Service |
f629e6 |
cmd = NULL;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
if (fp) fclose(fp);
|
|
Packit Service |
f629e6 |
return(cmd);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
unlink_and_free(char *cmd)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
char *s;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (s = strrchr(cmd, ' '))
|
|
Packit Service |
f629e6 |
s++;
|
|
Packit Service |
f629e6 |
else
|
|
Packit Service |
f629e6 |
s = cmd;
|
|
Packit Service |
f629e6 |
unlink(s); free(cmd);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
int
|
|
Packit Service |
f629e6 |
os_system(const char *cmd)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
char *cmdexe = getenv("ComSpec");
|
|
Packit Service |
f629e6 |
char *cmd1 = quote_cmd(cmd);
|
|
Packit Service |
f629e6 |
int i = spawnl(P_WAIT, cmdexe, "cmd.exe", "/c", cmd1, NULL);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
free(cmd1);
|
|
Packit Service |
f629e6 |
return(i);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#ifndef PIPES_SIMULATED
|
|
Packit Service |
f629e6 |
int
|
|
Packit Service |
f629e6 |
kill (int pid, int sig)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
HANDLE ph;
|
|
Packit Service |
f629e6 |
int retval = 0;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* We only support SIGKILL. */
|
|
Packit Service |
f629e6 |
if (sig != SIGKILL)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
errno = ENOSYS;
|
|
Packit Service |
f629e6 |
return -1;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
ph = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
|
|
Packit Service |
f629e6 |
if (ph)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
BOOL status = TerminateProcess(ph, -1);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (!status)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
errno = EPERM;
|
|
Packit Service |
f629e6 |
retval = -1;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
else
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
/* If we cannot open the process, it means we eaither aren't
|
|
Packit Service |
f629e6 |
allowed to (e.g., a process of another user), or such a
|
|
Packit Service |
f629e6 |
process doesn't exist. */
|
|
Packit Service |
f629e6 |
switch (GetLastError ())
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
case ERROR_ACCESS_DENIED:
|
|
Packit Service |
f629e6 |
errno = EPERM;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
default:
|
|
Packit Service |
f629e6 |
errno = ESRCH;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
retval = -1;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
CloseHandle (ph);
|
|
Packit Service |
f629e6 |
return retval;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
char *
|
|
Packit Service |
f629e6 |
quote_cmd(const char *cmd)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
char *quoted;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* The command will be invoked via cmd.exe, whose behavior wrt
|
|
Packit Service |
f629e6 |
quoted commands is to remove the first and the last quote
|
|
Packit Service |
f629e6 |
characters, and leave the rest (including any quote characters
|
|
Packit Service |
f629e6 |
inside the outer pair) intact. */
|
|
Packit Service |
f629e6 |
quoted = malloc(strlen (cmd) + 2 + 1);
|
|
Packit Service |
f629e6 |
sprintf(quoted, "\"%s\"", cmd);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
return quoted;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#else /* !__MINGW32__ */
|
|
Packit Service |
f629e6 |
#define os_system(cmd) system(cmd)
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
FILE *
|
|
Packit Service |
f629e6 |
os_popen(const char *command, const char *mode )
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
FILE *current;
|
|
Packit Service |
f629e6 |
char *name;
|
|
Packit Service |
f629e6 |
int cur;
|
|
Packit Service |
f629e6 |
char curmode[4];
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (*mode != 'r' && *mode != 'w')
|
|
Packit Service |
f629e6 |
return NULL;
|
|
Packit Service |
f629e6 |
strncpy(curmode, mode, 3); curmode[3] = '\0';
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#if defined(__MINGW32__)
|
|
Packit Service |
f629e6 |
current = popen(command, mode);
|
|
Packit Service |
f629e6 |
cur = fileno(current);
|
|
Packit Service |
f629e6 |
strcpy(pipes[cur].pmode, curmode);
|
|
Packit Service |
f629e6 |
return(current);
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
** get a name to use.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
if((name = tempnam(".","pip"))==NULL)
|
|
Packit Service |
f629e6 |
return NULL;
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
** If we're reading, just call system to get a file filled with
|
|
Packit Service |
f629e6 |
** output.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
if (*curmode == 'r') {
|
|
Packit Service |
f629e6 |
FILE *fp;
|
|
Packit Service |
f629e6 |
if ((cur = dup(fileno(stdout))) == -1)
|
|
Packit Service |
f629e6 |
return NULL;
|
|
Packit Service |
f629e6 |
*curmode = 'w';
|
|
Packit Service |
f629e6 |
if ((current = freopen(name, curmode, stdout)) == NULL)
|
|
Packit Service |
f629e6 |
return NULL;
|
|
Packit Service |
f629e6 |
os_system(command);
|
|
Packit Service |
f629e6 |
if (dup2(cur, fileno(stdout)) == -1)
|
|
Packit Service |
f629e6 |
return NULL;
|
|
Packit Service |
f629e6 |
close(cur);
|
|
Packit Service |
f629e6 |
*curmode = 'r';
|
|
Packit Service |
f629e6 |
if ((current = fopen(name, curmode)) == NULL)
|
|
Packit Service |
f629e6 |
return NULL;
|
|
Packit Service |
f629e6 |
} else {
|
|
Packit Service |
f629e6 |
if ((current = fopen(name, curmode)) == NULL)
|
|
Packit Service |
f629e6 |
return NULL;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
cur = fileno(current);
|
|
Packit Service |
f629e6 |
pipes[cur].name = name;
|
|
Packit Service |
f629e6 |
strcpy(pipes[cur].pmode, curmode);
|
|
Packit Service |
f629e6 |
pipes[cur].command = strdup(command);
|
|
Packit Service |
f629e6 |
return current;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
int
|
|
Packit Service |
f629e6 |
os_pclose( FILE * current)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
int cur = fileno(current);
|
|
Packit Service |
f629e6 |
int fd, rval;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#if defined(__MINGW32__)
|
|
Packit Service |
f629e6 |
rval = pclose(current);
|
|
Packit Service |
f629e6 |
*pipes[cur].pmode = '\0';
|
|
Packit Service |
f629e6 |
return rval;
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
** check for an open file.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
switch (*pipes[cur].pmode) {
|
|
Packit Service |
f629e6 |
case 'r':
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
** input pipes are just files we're done with.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
rval = fclose(current);
|
|
Packit Service |
f629e6 |
unlink(pipes[cur].name);
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case 'w':
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
** output pipes are temporary files we have
|
|
Packit Service |
f629e6 |
** to cram down the throats of programs.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
fclose(current);
|
|
Packit Service |
f629e6 |
rval = -1;
|
|
Packit Service |
f629e6 |
if ((fd = dup(fileno(stdin))) != -1) {
|
|
Packit Service |
f629e6 |
char *mode = pipes[cur].pmode; *mode = 'r';
|
|
Packit Service |
f629e6 |
if (current = freopen(pipes[cur].name, mode, stdin)) {
|
|
Packit Service |
f629e6 |
rval = os_system(pipes[cur].command);
|
|
Packit Service |
f629e6 |
fclose(current);
|
|
Packit Service |
f629e6 |
if (dup2(fd, fileno(stdin)) == -1) rval = -1;
|
|
Packit Service |
f629e6 |
close(fd);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
unlink(pipes[cur].name);
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
default:
|
|
Packit Service |
f629e6 |
return -1;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
** clean up current pipe.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
*pipes[cur].pmode = '\0';
|
|
Packit Service |
f629e6 |
free(pipes[cur].name);
|
|
Packit Service |
f629e6 |
free(pipes[cur].command);
|
|
Packit Service |
f629e6 |
return rval;
|
|
Packit Service |
f629e6 |
}
|