mirror of https://github.com/vitalif/e2fsprogs
92 lines
1.3 KiB
C
92 lines
1.3 KiB
C
/*
|
|
* fpopen.c --- unlike the libc popen, it directly executes the
|
|
* command instead of call out to the shell.
|
|
*/
|
|
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
|
|
#define MAX_ARGV 256
|
|
|
|
extern FILE *fpopen(const char *cmd, const char *mode);
|
|
|
|
FILE *fpopen(const char *cmd, const char *mode)
|
|
{
|
|
char *argv[MAX_ARGV];
|
|
int i = 0;
|
|
char *buf, *prog = 0;
|
|
char *p;
|
|
int do_stdin;
|
|
int fds[2];
|
|
pid_t pid;
|
|
|
|
if (!mode) {
|
|
errno = EFAULT;
|
|
return NULL;
|
|
}
|
|
|
|
switch (*mode) {
|
|
case 'r':
|
|
do_stdin = 0;
|
|
break;
|
|
case 'w':
|
|
do_stdin = 1;
|
|
break;
|
|
default:
|
|
errno = EINVAL;
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* Create the argv vector....
|
|
*/
|
|
buf = malloc(strlen(cmd)+1);
|
|
if (!buf)
|
|
return NULL;
|
|
strcpy(buf, cmd);
|
|
p = buf;
|
|
while (p && *p) {
|
|
if (isspace(*p)) {
|
|
p++;
|
|
continue;
|
|
}
|
|
if (i == 0)
|
|
prog = p;
|
|
argv[i++] = p;
|
|
p = strchr(p, ' ');
|
|
if (p)
|
|
*p++ = 0;
|
|
}
|
|
|
|
argv[i] = 0;
|
|
|
|
/*
|
|
* Get the pipe
|
|
*/
|
|
if (pipe(fds) < 0)
|
|
return NULL;
|
|
|
|
/* Fork and execute the correct program. */
|
|
if ((pid = fork()) < 0) {
|
|
perror("fork");
|
|
return NULL;
|
|
} else if (pid == 0) {
|
|
if (do_stdin) {
|
|
close(fds[1]);
|
|
dup2(fds[0], 0);
|
|
} else {
|
|
close(fds[0]);
|
|
dup2(fds[1], 1);
|
|
}
|
|
(void) execvp(prog, argv);
|
|
perror(prog);
|
|
exit(1);
|
|
}
|
|
return fdopen(do_stdin ? fds[1] : fds[0], mode);
|
|
}
|
|
|