簡體   English   中英

在C中編寫我自己的管道功能

[英]Writing my own piping function in C

我正在嘗試編寫自己的C管道功能。首先,一旦我已經分叉並且在孩子身上,我檢查以檢測管道輸入的位置,如下所示。 我循環遍歷我自己創建的StringArray(sa),然后將令牌復制到char cmd1 [64](先前已初始化),然后將令牌復制到char cmd2 [64]之后。 int管道被賦予下一步的值。

if(strcmp(sa[i], "|") == 0)
        {
            printf("got to the pipe\n"); 
            sa[i]=NULL; 
            strcpy(cmd1, sa[i-1]); 
            strcpy(cmd2, sa[i+1]); 
            piping=2; 
        }

然后,程序到達此聲明:

if (piping)
{
    if (pipe(fd) != 0){
        perror("Failed to create pipe"); 
    } 
    if ((cpPid = fork()) == -1){
        perror("Failed to fork"); 
    }
    if (cpPid == 0){
        dup2(fd[1], 1);
        close(fd[0]);
        close(fd[1]);
        execvp(cmd1, sa);
        error("failed to exec command 1");  
    }
     else
    {
        dup2(fd[0], 0);
        close(fd[0]);
        close(fd[1]);
        execvp(cmd2, sa);
        error("failed to exec command 2");
    }
}

我的程序完全崩潰,只發出未知錯誤10275024.有人可以幫我弄清楚出了什么問題嗎?

請看一下這個可以幫助您使用C執行管道的工作示例。

#include <assert.h>
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <memory.h>
#include <errno.h>

typedef int Pipe[2];

/* exec_nth_command() and exec_pipe_command() are mutually recursive */
static void exec_pipe_command(int ncmds, char ***cmds, Pipe output);

static void err_vsyswarn(char const *fmt, va_list args) {
    int errnum = errno;
    vfprintf(stderr, fmt, args);
    if (errnum != 0)
        fprintf(stderr, " (%d: %s)", errnum, strerror(errnum));
    putc('\n', stderr);
}

static void err_syswarn(char const *fmt, ...) {
    va_list args;
    err_vsyswarn(fmt, args);;
}

static void err_sysexit(char const *fmt, ...) {
    va_list args;
    err_vsyswarn(fmt, args);
    exit(1);
}

/* With the standard output plumbing sorted, execute Nth command */
static void exec_nth_command(int ncmds, char ***cmds) {
    assert(ncmds >= 1);
    if (ncmds > 1) {
        pid_t pid;
        Pipe input;
        if (pipe(input) != 0)
            err_sysexit("Failed to create pipe");
        if ((pid = fork()) < 0)
            err_sysexit("Failed to fork");
        if (pid == 0) {
            /* Child */
            exec_pipe_command(ncmds - 1, cmds, input);
        }
        /* Fix standard input to read end of pipe */
        dup2(input[0], 0);
        close(input[0]);
        close(input[1]);
    }
    execvp(cmds[ncmds - 1][0], cmds[ncmds - 1]);
    err_sysexit("Failed to exec %s", cmds[ncmds - 1][0]);
    /*NOTREACHED*/
}
/* exec_nth_command() and exec_pipe_command() are mutually recursive */
/* Given pipe, plumb it to standard output, then execute Nth command */
static void exec_pipe_command(int ncmds, char ***cmds, Pipe output) {
    assert(ncmds >= 1);
    /* Fix stdout to write end of pipe */
    dup2(output[1], 1);
    close(output[0]);
    close(output[1]);
    exec_nth_command(ncmds, cmds);
}

/* Execute the N commands in the pipeline */
static void exec_pipeline(int ncmds, char ***cmds) {
    assert(ncmds >= 1);
    pid_t pid;
    if ((pid = fork()) < 0)
        err_syswarn("Failed to fork");
    if (pid != 0)
        return;
    exec_nth_command(ncmds, cmds);
}

/*  who | awk '{print $1}' | sort | uniq -c | sort -n */
static char *cmd0[] = {"who", 0};
static char *cmd1[] = {"awk", "{print $1}", 0};
static char *cmd2[] = {"sort", 0};
static char *cmd3[] = {"uniq", "-c", 0};
static char *cmd4[] = {"sort", "-n", 0};

static char **cmds[] = {cmd0, cmd1, cmd2, cmd3, cmd4};
static int ncmds = sizeof(cmds) / sizeof(cmds[0]);

int main(int argc, char **argv) {
    exec_pipeline(ncmds, cmds);
    return (0);
}

代碼中的管道示例是

who | awk '{print $1}' | sort | uniq -c | sort -n

您可以使用任何管道。

測試:

dac@dac-Latitude-E7450 ~/C/> 
who | awk '{print $1}' | sort | uniq -c | sort -n 
      1 dac
dac@dac-Latitude-E7450 ~/C/> gcc main.c 
dac@dac-Latitude-E7450 ~/C/> ./a.out 
    1 dac

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM