实现linux 中c 函数popen( ),pclose( ); 进程通信、匿名管道

my_popen(), my_pclose()代码

my_popen.c

#include "head.h"

static pid_t *childpid = 0;
static int maxsize = 0;

FILE *my_popen(const char *cmd, const char *type) {
    FILE *fp;
    int pipefd[2];
    pid_t pid;

    if ((type[0] != 'r' && type[0] != 'w') || type[1] != 0) {
        errno = EINVAL;
        return 0;
    }

    if (!childpid) {
        maxsize = sysconf(_SC_OPEN_MAX);
        printf("maxsize = %d\n", maxsize);
        if (!(childpid = (pid_t *)calloc(maxsize, sizeof(pid_t)))) {
            return 0;
        }
    }
    if (pipe(pipefd) < 0) return 0;

    if ((pid = fork()) < 0) return 0;

    if (!pid) {
        if (type[0] == '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]);
            }
        }
        execl("/bin/sh", "sh", "-c", cmd, NULL);
    }

    if (type[0] == 'r') {
        close(pipefd[1]);
        if ((fp = fdopen(pipefd[0], type)) == 0) {
            return 0;
        }
    } else {
        close(pipefd[0]);
        if ((fp = fdopen(pipefd[1], type)) == 0) {
            return 0;
        }
    }
    childpid[fileno(fp)] = pid;
    return fp;
}

int my_pclose(FILE *fp) {
    int status, pid, fd;
    fd = fileno(fp);
    pid = childpid[fd];
    if (!pid) {
        errno = EINVAL;
        return -1;
    }
    fflush(fp);
    close(fd);
    wait4(pid, &status, WUNTRACED, 0);
    return status;
}

head.h

#ifndef _HEAD_H
#define _HEAD_H
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <errno.h>
 #include <sys/time.h>
#include <time.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <pthread.h>

FILE *my_popen(const char *cmd, const char *type);
int my_pclose(FILE *fp);
#endif

posted @ 2022-02-25 23:05  代码附体  阅读(248)  评论(0编辑  收藏  举报