]> git.ipfire.org Git - thirdparty/e2fsprogs.git/blame - lib/fpopen.c
libext2fs: add checks for block number wrapping for bitmap range functions
[thirdparty/e2fsprogs.git] / lib / fpopen.c
CommitLineData
f3db3566
TT
1/*
2 * fpopen.c --- unlike the libc popen, it directly executes the
3 * command instead of call out to the shell.
e2e69ba4
TT
4 *
5 * Copyright Theodore Ts'o, 1996-1999.
6 *
7 * Permission to use this file is granted for any purposes, as long as
8 * this copyright statement is kept intact and the author is not held
9 * liable for any damages resulting from the use of this program.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
13 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
14 * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
15 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
16 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
17 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
18 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
19 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
21 * USE OF THIS SOFTWARE.
f3db3566
TT
22 */
23
d1154eb4 24#include "config.h"
f3db3566
TT
25#include <unistd.h>
26#include <stdlib.h>
27#include <stdio.h>
28#include <errno.h>
29#include <string.h>
30#include <ctype.h>
31
32#define MAX_ARGV 256
33
34extern FILE *fpopen(const char *cmd, const char *mode);
35
36FILE *fpopen(const char *cmd, const char *mode)
37{
38 char *argv[MAX_ARGV];
39 int i = 0;
40 char *buf, *prog = 0;
41 char *p;
e2e69ba4 42 int do_stdin, do_stderr = 0;
f3db3566
TT
43 int fds[2];
44 pid_t pid;
45
46 if (!mode) {
47 errno = EFAULT;
48 return NULL;
49 }
efc6f628 50
f3db3566
TT
51 switch (*mode) {
52 case 'r':
53 do_stdin = 0;
54 break;
55 case 'w':
56 do_stdin = 1;
57 break;
58 default:
59 errno = EINVAL;
60 return NULL;
61 }
e2e69ba4
TT
62 switch (*(mode+1)) {
63 case '&':
64 do_stderr = 1;
65 }
f3db3566
TT
66
67 /*
68 * Create the argv vector....
69 */
70 buf = malloc(strlen(cmd)+1);
71 if (!buf)
72 return NULL;
73 strcpy(buf, cmd);
74 p = buf;
75 while (p && *p) {
76 if (isspace(*p)) {
77 p++;
78 continue;
79 }
80 if (i == 0)
81 prog = p;
82 argv[i++] = p;
83 p = strchr(p, ' ');
84 if (p)
85 *p++ = 0;
86 }
87
88 argv[i] = 0;
89
90 /*
91 * Get the pipe
92 */
93 if (pipe(fds) < 0)
94 return NULL;
efc6f628 95
f3db3566
TT
96 /* Fork and execute the correct program. */
97 if ((pid = fork()) < 0) {
98 perror("fork");
99 return NULL;
100 } else if (pid == 0) {
101 if (do_stdin) {
102 close(fds[1]);
103 dup2(fds[0], 0);
104 } else {
105 close(fds[0]);
106 dup2(fds[1], 1);
e2e69ba4
TT
107 if (do_stderr)
108 dup2(fds[1], 2);
f3db3566
TT
109 }
110 (void) execvp(prog, argv);
111 perror(prog);
112 exit(1);
113 }
114 return fdopen(do_stdin ? fds[1] : fds[0], mode);
115}
116