Определить код статуса исходного выхода

На базовом уровне программного обеспечения, который я поддерживаю, существует 150 заявлений, распространенных среди различных приложений на C, которые делают вызов другой команде Linux (например, rm -rf ... ) или настраиваемому приложению, используя status = system(cmd)/256 . Когда вызывается либо, код состояния, возвращаемый из команды Linux или пользовательского приложения, делится на 256 . Так что, когда код состояния больше 0, мы знаем, что была проблема. Однако, как написано программное обеспечение, он не всегда регистрирует, какая команда или приложение вернули код состояния. Так что, если код состояния был указан 32768, когда он делится на 256, код состояния – 128 .

Программное обеспечение является старым, и, хотя я могу вносить изменения, было бы неплохо, если бы какая-либо из названных команд или приложений называла их исходный код состояния в другом месте.

Есть ли способ определить исходный код состояния в стандартном файле журнала Linux и приложении, которое вернуло его?

Как написать обертку

Следуя примеру применения обертки в libc function 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  /* 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" 

Как я уже говорил, системная (3) функция библиотеки возвращает результат ожидания syscall, например waitpid (2) . (Пожалуйста, перейдите по ссылкам на страницы руководства).

Поэтому вы должны улучшить свою программу, чтобы использовать WIFEXITED , WIFSIGNALED , WEXITSTATUS , WTERMSIG (Posix) macros в результате вызовов в 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"); считается плохой практикой (что, если пользователь сделал свой собственный rm в своей $PATH ) и не очень эффективен. (Например, вы можете использовать nftw (3) с отключением (2) ) или по крайней мере /bin/rm -rf ; но как насчет пробелов в имени каталога или грязных IFS трюках ?)