从main返回errno

时间:2018-06-23 18:24:31

标签: c errno

我有这样一种结构的代码:

main(){
 if(...){
  perror(... < 0);
  res = -1;
  goto cleanup;
 }
 ...
 if(... < 0){
  perror(...);
  res = -2;
  goto cleanup;
 }
 ...
cleanup:
 close(fd);
 return res;
}

我认为我会从main中返回一些有意义的错误。但是太懒了。现在,我想缩一些代码。我想通过以下方式构造代码:

...
if(... < 0){
 perror(...);
 goto cleanup;
}
...
if(... < 0){
 perror(...);
 goto cleanup;
}
cleanup:
 close(fd);
 return errno; // return from main

以这种方式进行操作是一种好习惯吗?

2 个答案:

答案 0 :(得分:4)

可以通过perrorclose修改

errno变量。如果要返回errno,则需要先保存它,因此,如果perror调用失败,则不会修改errno值:

int main() {
    int errnosav = 0;
    ...
    errno = 0;
    if (some_function_that_modifies_errno() < 0) {
     errnosav = errno;
     perror(...);
     goto cleanup;
    }
    ...
    if (some_other_function_that_modifies_errno() < 0) {
     errnosav = errno;
     perror(...);
     goto cleanup;
    }
    cleanup:
     close(fd);
     return errnosav; // return from main
}

与第一个版本相同,但是您无法控制返回的值。

  

我认为我会从main中返回一些有意义的错误。

在第一个版本中,您从main返回有意义的错误。如果程序返回-1,则说明第一个if失败了。如果程序返回-2,则说明第二个if失败了。从错误消息中,您知道errno的值。如果知道什么功能失败以及errno值是什么,则可以查看功能手册以获取errno值的解释。如果程序返回errno,则您不知道哪个调用失败。而且,在不知道哪个调用失败的情况下,您也不知道如何解释errno值。

答案 1 :(得分:4)

您可以这样做((如果您纠正了@Kamil Cuk带来的问题),但是您应该知道许多(大多数?)shell仅从程序中读取8位退出代码。这意味着,如果errno值超过255,并且您的程序返回这些错误之一,则Shell将错误地报告您的错误代码。在http://www.ioplex.com/~miallen/errcmp.html处可以看到errno代码至少达到了值252(对于HP-UX 11.22为“未实现功能”),因此这不是不合理的情况。

令人讨厌的是,shell还向用户出口代码提供128 + N,其中N是终止进程的信号编号,因此N> 127也可能是一个问题,但考虑到信号数量几乎没有增长根本我认为这没什么问题。