如何处理execvp错误? [英] How to handle errors in execvp?

查看:506
本文介绍了如何处理execvp错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个小程序(与SO code),有利于 printenv |排序|少。现在,我想实现的错误处理,我开始execvp。难道只是为了检查返回值和什么呢?据我所知我刚刚检查返回值,如果它在这个函数是0 返回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){
            dup2(出,1);
            关闭(出);
        }
        返回execvp(CMD->的argv [0],(char * const的*)CMD->的argv);
    }
    返回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);
}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);
}


解决方案

手动 execvp 您进程的程序映像更改为另一种。所以,如果有一个返回值的话,那将是很明显-1,因为这将有明显失败。

对于任何系统调用或调用系统调用,execvp与errno设置为一个适当的错误code,你可以用的 PERROR 知道为什么你的函数失败。 (顺便说一句,你应该做同样的任何系统调用:至少叉,钢管和dup2)

那么,如果错误处理,你的意思是处理从您启动程序中的错误,你可以用的等待或waitpid函数。它可以让你知道程序是如何结束,它由一个信号返回值,如果结束了,如果是至极之一,等等。

I've written a small program (with code from SO) that facilitates printenv | sort | less. Now I want to implement error-handling and I start with execvp. Is it just to check the return value and what more? AFAIK I just check the return value if it was 0 in this function return execvp (cmd [i].argv [0], (char * const *)cmd [i].argv);. Is that correct?

#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) {
            dup2 (in, 0);
            close (in);
        }
        if (out != 1) {
            dup2 (out, 1);
            close (out);
        }
        return execvp (cmd->argv [0], (char * const *)cmd->argv);
    }
    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);
}

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

解决方案

Look at the manual : execvp change your process's program image to another. So if there is a return value at all, it will be obviously -1, because it will have obviously failed.

As for any syscall or functions calling syscall, execvp with set errno for an appropriate error code, that you can use with perror to know why your function failed. (By the way, you should do the same to any syscall: fork, pipe and dup2 at least.)

Then, if by "error handling", you mean handle errors from the program that you launched, you can make it with wait or waitpid. It will allow you to know how the program ended, it return value, if it ended by a signal, if yes wich one, etc.

这篇关于如何处理execvp错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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