e2fsprogs/lib/fpopen.c
Theodore Ts'o d1154eb460 Shorten compile commands run by the build system
The DEFS line in MCONFIG had gotten so long that it exceeded 4k, and
this was starting to cause some tools heartburn.  It also made "make
V=1" almost useless, since trying to following the individual commands
run by make was lost in the noise of all of the defines.

So fix this by putting the configure-generated defines in lib/config.h
and the directory pathnames to lib/dirpaths.h.

In addition, clean up some vestigal defines in configure.in and in the
Makefiles to further shorten the cc command lines.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
2011-09-18 17:34:37 -04:00

117 lines
2.4 KiB
C

/*
* fpopen.c --- unlike the libc popen, it directly executes the
* command instead of call out to the shell.
*
* Copyright Theodore Ts'o, 1996-1999.
*
* Permission to use this file is granted for any purposes, as long as
* this copyright statement is kept intact and the author is not held
* liable for any damages resulting from the use of this program.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
* WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE.
*/
#include "config.h"
#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, do_stderr = 0;
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;
}
switch (*(mode+1)) {
case '&':
do_stderr = 1;
}
/*
* 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);
if (do_stderr)
dup2(fds[1], 2);
}
(void) execvp(prog, argv);
perror(prog);
exit(1);
}
return fdopen(do_stdin ? fds[1] : fds[0], mode);
}