1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
| #include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/wait.h>
#define MAX_FD 1024
static pid_t *childPid = NULL;
FILE *popen_cmd(const char *pCmd, const char *pType)
{
int index;
pid_t pid;
int pipeFd[2];
FILE *pFile;
if (pCmd != NULL && *pType != 'r' && *pType != 'w' && pType[1] != '\0')
{
errno = EINVAL;
return NULL;
}
if (childPid == NULL)
{
childPid = (pid_t *)calloc(MAX_FD, sizeof(pid_t));
if (childPid == NULL)
{
return NULL;
}
}
if (pipe(pipeFd) < 0)
{
return NULL;
}
if ((pid = fork()) < 0)
{
return NULL;
}
else if (pid == 0)
{
//type是对父进程而言,当为'r'时,子进程应该关闭读端.
if (*pType == 'r')
{
close(pipeFd[0]);
// 把STDOUT_FILENO重定向pipeFd[1]
dup2(pipeFd[1], STDOUT_FILENO);
close(pipeFd[1]);
}
else
{
close(pipeFd[1]);
dup2(pipeFd[0], STDIN_FILENO);
close(pipeFd[0]);
}
for (index = 0; index < MAX_FD; index++)
{
if (childPid[index] > 0)
{
close(index);
}
}
execl("/bin/sh", "sh", "-c", pCmd, (char *)0);
_exit(127);
}
else
{
if (*pType == 'r')
{
close(pipeFd[1]);
if ((pFile = fdopen(pipeFd[0], pType)) == NULL)
{
return NULL;
}
}
else
{
close(pipeFd[0]);
if ((pFile = fdopen(pipeFd[1], pType)) == NULL)
{
return NULL;
}
}
}
childPid[fileno(pFile)] = pid;
return pFile;
}
int pclose_cmd(FILE *pFile)
{
int fd, status;
pid_t pid;
if (childPid == NULL || pFile == NULL)
{
goto error;
}
fd = fileno(pFile);
if ((pid = childPid[fd]) == 0)
{
goto error;
}
childPid[fd] = 0;
if (fclose(pFile) == EOF)
{
return -1;
}
while (waitpid(pid, &status, 0) < 0)
{
if (errno != EINTR)
{
return -1;
}
}
error:
errno = EINVAL;
return -1;
}
int main(int argc, char **argv)
{
char line[256] = {0};
FILE *pFile;
pFile = popen_cmd("ifconfig eth0", "r");
if (pFile != NULL)
{
while (fgets(line, 256, pFile) != NULL)
{
printf("%s", line);
}
pclose_cmd(pFile);
}
return 0;
}
|