在我维护的软件基线中,有150个语句分布在各种C语言应用程序中,这些语句使用rm -rf ...
调用另一个Linux命令(例如status = system(cmd)/256
)或自定义应用程序。调用其中任何一个时,从Linux命令或自定义应用程序返回的状态代码除以 256 。因此,当状态代码大于0时,我们知道存在问题。但是,软件的编写方式并不总是记录哪个命令或应用程序返回了状态代码。因此,如果状态代码为32768,则除以256时,报告的状态代码为 128 。
软件很旧,虽然我可以进行更改,但如果调用的任何命令或应用程序调用其他地方的原始状态代码,那将会很好。
有没有办法确定标准Linux日志文件中的原始状态代码以及返回它的应用程序?
答案 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
的结果使用WIFSIGNALED
,WEXITSTATUS
,WTERMSIG
,system
标准(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呢?)