确定原始退出状态代码

时间:2013-06-19 12:29:33

标签: c linux error-code

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

软件很旧,虽然我可以进行更改,但如果调用的任何命令或应用程序调用其他地方的原始状态代码,那将会很好。

有没有办法确定标准Linux日志文件中的原始状态代码以及返回它的应用程序?

2 个答案:

答案 0 :(得分:5)

如何撰写包装

以下示例介绍如何在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"

答案 1 :(得分:2)

正如我评论的那样,system(3)库函数返回等待系统调用的结果 waitpid(2)。 (请点击手册页的链接)。

因此,您应该改进您的计划,以便对调用WIFEXITED的结果使用WIFSIGNALEDWEXITSTATUSWTERMSIGsystem标准(Posix)宏(当结果为-1时除外,请使用errno)。

编码

 status = system(cmd)/256;

对于人类开发人员来说是不可读的并且是不可移植的。

我想编码的编码员想要捕捉被打断的命令......

您应该用

替换它
 status = system(cmd);
 if (status < 0) /* e.g. 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");被视为不良做法(如果用户在其rm中创建了自己的$PATH并且效率不高,该怎么办? (例如,您可以nftw(3)使用unlink(2))或至少使用/bin/rm -rf;但是目录名中的空格或脏IFS tricks呢?)