參考popen, pclose源碼進行了修改
第一次的問題已解決
如下圖
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <dirent.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
#define SHELL "/bin/bash"
pid_t *childpid = NULL;
int maxfd;
int open_max() {
struct rlimit limit;
if(getrlimit(RLIMIT_NOFILE,&limit) == -1) {
perror("getrlimit");
return -1;
}
return (int)limit.rlim_cur;
}
FILE *mpopen(const char* cmdstr, const char *mode) {
int pipefd[2];
pid_t pid;
FILE *fp;
if ((mode[0] != 'r' && mode[0] != 'w') || mode[1] != 0) {
fprintf(stderr, "Only Support r or w !\n");
return NULL;
}
if (childpid == NULL) {
maxfd = open_max();
if ((childpid = calloc(maxfd, sizeof(pid_t))) == NULL) return NULL;
}
if (pipe(pipefd) < 0) return NULL;
if ((pid = fork()) < 0) {
return NULL;
}
else if (pid == 0) {
if (*mode == 'r') {
close(pipefd[0]);
if (pipefd[1] != STDOUT_FILENO) {
dup2(pipefd[1], STDOUT_FILENO);
close(pipefd[1]);
}
}
else {
close(pipefd[1]);
if (pipefd[0] != STDIN_FILENO) {
dup2(pipefd[0], STDIN_FILENO);
close(pipefd[0]);
}
}
for (int i = 0; i < maxfd; i++) {
if (childpid[i]) close(i);
}
execl(SHELL, "sh", "-c", cmdstr, (char *)0);
}
if (*mode == 'r') {
close(pipefd[1]);
if ((fp = fdopen(pipefd[0], mode)) == NULL) return NULL;
}
else {
close(pipefd[0]);
if ((fp = fdopen(pipefd[1], mode)) == NULL) return NULL;
}
childpid[fileno(fp)] = pid;
return fp;
}
int mpclose(FILE *fp) {
int fd, stat;
pid_t pid;
if (childpid == NULL) return -1;
fd = fileno(fp);
if ((pid = childpid[fd]) == 0) return -1;
waitpid(pid, &stat, 0);
return stat;
}
int main() {
FILE * fp;
char buff[1024];
//char *str = "cat /etc/passwd";
char *str = "ls";
//char *str = "ifconfig eth0";
printf("cmdstr = %s\n", str);
printf("My Popen and Pclose: \n");
fp = mpopen(str, "r");
fgets(buff, sizeof(buff), fp);
printf("%s", buff, strlen(buff));
mpclose(fp);
printf("System Popen and Pclose: \n");
fp = popen(str, "r");
fgets(buff, sizeof(buff), fp);
printf("%s", buff, strlen(buff));
pclose(fp);
return 0;
}