2

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

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

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

4

2 回答 2

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"
于 2013-06-19T12:44:24.093 回答
2

正如我所评论的,system(3)库函数返回等待系统调用的结果,例如 waitpid(2)。(请按照手册页的链接进行操作)。

所以你应该改进你的程序WIFEXITED,在调用结果上使用标准(Posix)宏(除非结果是WIFSIGNALED,然后使用)。WEXITSTATUSWTERMSIGsystem-1errno

编码

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

顺便说一句,使用system("rm -rf /some/dir");被认为是不好的做法(如果用户自己rm在他的$PATH. (例如,您可以将nftw(3)unlink(2)一起使用)或至少/bin/rm -rf;但是目录名称中的空格或肮脏的IFS技巧呢?)

于 2013-06-19T13:43:33.937 回答