Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在这种情况下,它的用法是什么_C_Linux_Error Handling - Fatal编程技术网

C 在这种情况下,它的用法是什么

C 在这种情况下,它的用法是什么,c,linux,error-handling,C,Linux,Error Handling,我们可以检查一下我的perror用法是否正确吗?背景是这些问题 现在我有了这个代码,但代码正确吗 /* Helper function that forks pipes */ int fork_pipes (int n, struct command *cmd) { int i; int in, fd [2]; for (i = 0; i < n - 1; ++i) { pipe (fd); spawn_proc (in, fd [1

我们可以检查一下我的perror用法是否正确吗?背景是这些问题 现在我有了这个代码,但代码正确吗

/* Helper function that forks pipes */
int fork_pipes (int n, struct command *cmd) {
    int i;
    int in, fd [2];
    for (i = 0; i < n - 1; ++i) {
        pipe (fd);
        spawn_proc (in, fd [1], cmd + i);
        close (fd [1]);
        in = fd [0];
    }
    dup2 (in, 0);
    /*return execvp (cmd [i].argv [0], (char * const *)cmd [i].argv);*/
    if (execvp (cmd [i].argv [0], (char * const *)cmd [i].argv) < 0) {
        perror("execvp failed");
        exit(1);
    } else {
        return execvp (cmd [i].argv [0], (char * const *)cmd [i].argv);
    }
}
/*分叉管道的辅助函数*/
int fork_管道(int n,结构命令*cmd){
int i;
int-in,fd[2];
对于(i=0;i
完整的程序是

#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
struct command
{
    const char **argv;
};
/* Helper function that spawns processes */
int spawn_proc (int in, int out, struct command *cmd) {
    pid_t pid;
    if ((pid = fork ()) == 0) {
        if (in != 0) {
            /*if (dup2(in, 0) == -1) {
                perror("dup2 failed");
                exit(1);
            }*/
            dup2 (in, 0);
            close (in);
        }
        if (out != 1) {
            dup2 (out, 1);
            close (out);
        }
        if (execvp(cmd->argv [0], (char * const *)cmd->argv) < 0) {
            perror("execvp failed");
            exit(1);
        }
    } else if (pid < 0) {
        perror("fork failed");
        exit(1);
    }
    return pid;
}
/* Helper function that forks pipes */
int fork_pipes (int n, struct command *cmd) {
    int i;
    int in, fd [2];
    for (i = 0; i < n - 1; ++i) {
        pipe (fd);
        spawn_proc (in, fd [1], cmd + i);
        close (fd [1]);
        in = fd [0];
    }
    dup2 (in, 0);
    /*return execvp (cmd [i].argv [0], (char * const *)cmd [i].argv);*/
    if (execvp (cmd [i].argv [0], (char * const *)cmd [i].argv) < 0) {
        perror("execvp failed");
        exit(1);
    } else {
        return execvp (cmd [i].argv [0], (char * const *)cmd [i].argv);
    }
}

int main (int argc, char ** argv) {
    int i;
    if (argc == 1) { /* There were no arguments */
        const char *printenv[] = { "printenv", 0};
        const char *sort[] = { "sort", 0 };
        const char *less[] = { "less", 0 };
        struct command cmd [] = { {printenv}, {sort}, {less} };
        return fork_pipes (3, cmd);
    }
    if (argc > 1) { /* I'd like an argument */

        if (strncmp(argv[1], "cd", 2) && strncmp(argv[1], "exit", 2)) {
            char *tmp;
            int len = 1;
            for( i=1; i<argc; i++)
            {
                len += strlen(argv[i]) + 2;
            }
            tmp = (char*) malloc(len);
            tmp[0] = '\0';
            int pos = 0;
            for( i=1; i<argc; i++)
            {
                pos += sprintf(tmp+pos, "%s%s", (i==1?"":"|"), argv[i]);
            }
            const char *printenv[] = { "printenv", 0};
            const char *grep[] = { "grep", "-E", tmp, NULL};
            const char *sort[] = { "sort", 0 };
            const char *less[] = { "less", 0 };
            struct command cmd [] = { {printenv}, {grep}, {sort}, {less} };
            return fork_pipes (4, cmd);
            free(tmp);
        } else if (! strncmp(argv[1], "cd", 2)) { /* change directory */
            printf("change directory to %s\n" , argv[2]);
            chdir(argv[2]);
        } else if (! strncmp(argv[1], "exit", 2)) { /* change directory */
            printf("exit\n");
            exit(0);
        }
    }
    exit(0);
}
#包括
#包括
#包括
#包括
#包括
#包括
结构命令
{
常量字符**argv;
};
/*生成进程的助手函数*/
int spawn_proc(int-in,int-out,struct-command*cmd){
pid_t pid;
如果((pid=fork())==0){
如果(in!=0){
/*if(dup2(in,0)=-1){
perror(“dup2失败”);
出口(1);
}*/
dup2(in,0);
关闭(in);
}
如果(输出!=1){
dup2(out,1);
收尾;
}
if(execvp(cmd->argv[0],(char*const*)cmd->argv)<0){
perror(“execvp失败”);
出口(1);
}
}否则如果(pid<0){
perror(“fork失败”);
出口(1);
}
返回pid;
}
/*分叉管道的辅助函数*/
int fork_管道(int n,结构命令*cmd){
int i;
int-in,fd[2];
对于(i=0;i1){/*我想要一个参数*/
if(strncmp(argv[1],“cd”,2)和&strncmp(argv[1],“exit”,2)){
char*tmp;
int len=1;
对于(i=1;i此代码:

 if (execvp (cmd [i].argv [0], (char * const *)cmd [i].argv) < 0) {
    perror("execvp failed");
    exit(1);
 } else {
    return execvp (cmd [i].argv [0], (char * const *)cmd [i].argv);
 }
if(execvp(cmd[i].argv[0],(char*const*)cmd[i].argv)<0){
perror(“execvp失败”);
出口(1);
}否则{
返回execvp(cmd[i].argv[0],(char*const*)cmd[i].argv);
}
有几个问题

  • 除非发生错误,否则execvp不会返回,因此如果所有操作都正常,则封装函数将永远不会返回

  • 由于前面的循环,值“i”已超过“cmd”中数组的结尾,因此“cmd[i].argv[0]不正确

  • cmd不是struct命令的数组,因此不应编制索引

  • cmd.argv中的第一个条目是指向最后一个条目为NULL的数组的指针。 execvp将处理(并且仅处理)该数组 因此,所有其他指向数组的指针都将被忽略


  • fork
    exec
    dup2
    pipe
    ,与unix中的大多数系统调用一样返回<0(-1通常)在失败时更改
    errno
    全局变量,该变量由
    perror
    用于打印消息。因此,您的用法没有错误。顺便说一下,
    man
    是一个很好的资源,可以生成函数在失败时的操作信息。代码中有大量错误。例如,第一次通过fork_pipe()中的循环“in”包含垃圾。传递给execvp()的第二个参数需要是一个指向字符串的指针,并带有一个最终的空指针。缺少最终的空指针,还有很多problems@user3629249:关于
    中的
    的注释正确-应将其初始化为0。其他注释大多不正确;
    execvp()的第二个参数
    是指向以null结尾的
    char*
    数组的指针,尽管常量有点歪斜(因此强制转换),并且初始值设定项中的0是null指针常量。另请参见(1)测试不是必需的,但错误报告和退出是必需的;第二个
    execvp()
    从不执行。(2)这种分析是错误的;循环使用
    for(i=0;i
    而不是
    for(i=0;i
    ——后者将使您的分析正确。(3)
    cmd
    fork\u pipes()中的数组,因此对其进行索引是完全合法的。(4)这种分析完全是假的;
    struct命令cmd[]
    阵列已正确初始化。