确定原始退出状态代码

在我所维护的一个软件基线中,有150个语句分布在各种C应用程序中,这些应用程序使用status = system(cmd)/256调用另一个Linux命令(例如rm -rf ... )或自定义应用程序。 当被调用时,从Linux命令或自定义应用程序返回的状态代码除以256 。 所以当状态码大于0时,我们知道有问题。 但是,软件写入的方式并不总是logging返回状态码的命令或应用程序。 因此,如果状态代码是32768,除以256,则报告的状态代码是128

该软件是旧的,而我可以做出改变,如果任何被调用的命令或应用程序称为其他地方的原始状态代码将是很好的。

有没有一种方法来确定在一个标准的Linux日志文件中的原始状态码和返回它的应用程序?

Solutions Collecting From Web of "确定原始退出状态代码"

如何写一个包装

以下是关于如何在libc函数system()应用一个包装的例子。

创建一个名为system_wrapper.c的新模块(翻译单元),如下所示:

头文件system_wrapper.h

 #ifndef _SYSTEM_WRAPPER #define _SYSTEM_WRAPPER #define system(cmd) system_wrapper(cmd) int system_wrapper(const char *); #endif 

模块system_wrapper.c

 #include <stdlib.h> /* to prototype the original function, that is libc's system() */ #include "system_wrapper.h" #undef system int system_wrapper(const char * cmd) { int result = system(cmd); /* Log result here. */ return result; } 

将这一行添加到使用system()所有模块中:

 #include "system_wrapper.h" 

正如我所说的, system(3)库函数返回waitpid(2)等wait系统调用的结果。 (请按照手册页的链接)。

所以你应该改善你的程序,使用WIFEXITEDWIFSIGNALEDWEXITSTATUSWTERMSIG标准(Posix)宏来调用system的结果(除非结果是-1 ,然后使用errno )。

编码

  status = system(cmd)/256; 

对于人类开发者来说是不可读的,而且是不可移植的。

我想编码谁想要捕捉中断的命令编码器….

你应该用

  status = system(cmd); if (status < 0) /* eg fork failed */ do_something_with_error_code (errno); else if (status == 0) /* cmd run without errors */ do_something_to_tell_command_exited_ok (); else if (WIFEXITED(status)) /* cmd got an error */ do_something_with_exit_code (WEXITSTATUS(status)); else if (WIFSIGNALED(status)) /* cmd or the shell got a signal */ do_something_with_terminating_signal (WTERMSIG(status)); 

BTW,使用system("rm -rf /some/dir"); 被认为是不好的做法(如果用户在他的$PATH做了他自己的rm )并且效率不高。 (你可以例如使用nftw(3)与unlink(2) )或至少/bin/rm -rf ; 但在目录名称或肮脏的IFS技巧空间呢?)