在这种情况下PERROR用法 [英] perror usage in this case

查看:129
本文介绍了在这种情况下PERROR用法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们能确认我的PERROR用法是正确的?背景是这些问题的
如何execvp处理错误?
如何PERROR与dup2使用?
现在我有这个code这工作,但为code正确吗?

  / *辅助函数叉管* /
INT fork_pipes(INT N,结构命令* CMD){
    INT I;
    int类型,FD [2];
    对于(i = 0; I< N - 1 ++ I){
        管(FD);
        spawn_proc(中,FD [1],CMD + I);
        关闭(FD [1]);
        在= FD [0];
    }
    dup2(在0);
    / *返回execvp(CMD [I] .argv [0],(char * const的*)CMD [I] .argv); * /
    如果(execvp(CMD [I] .argv [0],(char * const的*)CMD [I] .argv)小于0){
        PERROR(execvp失败);
        出口(1);
    }其他{
        返回execvp(CMD [I] .argv [0],(char * const的*)CMD [I] .argv);
    }
}

完整的程序

 的#include< SYS / types.h中>
#包括LT&;&errno.h中GT;
#包括LT&;&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&unistd.h中GT;
#包括LT&;&string.h中GT;
结构命令
{
    为const char ** argv的;
};
/ *辅助函数,产生进程* /
INT spawn_proc(int类型,int的列,结构命令* CMD){
    将为pid_t PID;
    如果((PID =叉())== 0){
        如果(在!= 0){
            / *如果(dup2(在0)== -1){
                PERROR(dup2失败);
                出口(1);
            } * /
            dup2(在0);
            逼近);
        }
        如果(满分!= 1){
            dup2(出,1);
            关闭(出);
        }
        如果(execvp(CMD->的argv [0],(char * const的*)CMD->的argv)小于0){
            PERROR(execvp失败);
            出口(1);
        }
    }否则如果(PID℃,){
        PERROR(叉失败);
        出口(1);
    }
    返回PID;
}
/ *辅助函数叉管* /
INT fork_pipes(INT N,结构命令* CMD){
    INT I;
    int类型,FD [2];
    对于(i = 0; I< N - 1 ++ I){
        管(FD);
        spawn_proc(中,FD [1],CMD + I);
        关闭(FD [1]);
        在= FD [0];
    }
    dup2(在0);
    / *返回execvp(CMD [I] .argv [0],(char * const的*)CMD [I] .argv); * /
    如果(execvp(CMD [I] .argv [0],(char * const的*)CMD [I] .argv)小于0){
        PERROR(execvp失败);
        出口(1);
    }其他{
        返回execvp(CMD [I] .argv [0],(char * const的*)CMD [I] .argv);
    }
}INT主(INT ARGC,字符** argv的){
    INT I;
    如果(ARGC == 1){/ *有没有参数* /
        为const char * printenv [] = {printenv,0};
        为const char *排序[] = {排序,0};
        为const char *更少[] = {少,0};
        结构命令CMD [] = {{printenv},{排序},{少}};
        返回fork_pipes(3,CMD);
    }
    如果(ARGC大于1){/ *我想一个参数* /        如果(STRNCMP(的argv [1],CD,2)及和放大器; STRNCMP(的argv [1],退出,2)){
            字符* tmp目录;
            INT LEN = 1;
            对于(i = 1; I< ARGC,我++)
            {
                LEN + = strlen的(的argv [I])+ 2;
            }
            TMP =(字符*)malloc的(LEN);
            TMP [0] ='\\ 0';
            INT POS = 0;
            对于(i = 1; I< ARGC,我++)
            {
                POS + = sprintf的(TMP + POS,%s%S(我== 1:?|)的argv [I]);
            }
            为const char * printenv [] = {printenv,0};
            为const char *的grep [] = {grep的,-E,TMP,NULL};
            为const char *排序[] = {排序,0};
            为const char *更少[] = {少,0};
            结构命令CMD [] = {{printenv},{grep的},{排序},{少}};
            返回fork_pipes(4,CMD);
            免费(TMP);
        }否则如果(!STRNCMP(的argv [1],CD,2)){/ *更改目录* /
            的printf(更改目录到%s \\ n,argv的[2]);
            CHDIR(的argv [2]);
        }否则如果(!STRNCMP(的argv [1],退出,2)){/ *更改目录* /
            的printf(退出\\ n);
            出口(0);
        }
    }
    出口(0);
}


解决方案

这code:

 如果(execvp(CMD [I] .argv [0],(char * const的*)CMD [I] .argv)小于0){
    PERROR(execvp失败);
    出口(1);
 }其他{
    返回execvp(CMD [I] .argv [0],(char * const的*)CMD [I] .argv);
 }

有几个问题。


  1. execvp不回来,除非发生错误,因此,如果所有的作品,封闭功能将不会再回来。


  2. 值i是已经过去的CMD数组的结束,由于前循环,所以CMD [I] .argv [0]是不正确的。


  3. cmd是不是数组结构的命令,所以不应该被索引


  4. 在cmd.argv的第一项是一个指针数组,其中最后一个条目为空。
    在execvp将这项工作(且只有)阵列
    因此,所有其他的指向数组的指针将被忽略


Can we check that my perror usage is correct? The background is these questions How to handle errors in execvp? How to use perror with dup2? and now I have this code which works but is the code correct?

/* 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);
    }
}

The full program is

#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);
}

解决方案

this code:

 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);
 }

has several problems.

  1. execvp does not return, except if an error occurs, so if all works, the enclosing function will never return.

  2. the value 'i' is already past the end of the array in 'cmd' due to the prior loop, so 'cmd[i].argv[0] is not correct.

  3. cmd is not an array, of struct command, so should not be indexed

  4. the first entry in cmd.argv is a pointer to an array where the last entry is NULL. the execvp will work on that (and only that) array so all other pointers to arrays will be ignored

这篇关于在这种情况下PERROR用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆