Реализация функции «system» в Unix
А. Вылиток
Функция
int system (char* cmd) из библиотеки
передает свой аргумент-строку
cmd на выполнение стандартному командному интерпретатору системы.
В Unix стандартный интерпретатор
shell (
sh) хранится в файле «/bin/sh».
Команда
cmd может представлять собой простую команду
shell или состоять из серии команд, разделенных точкой с запятой или символами канала, можно также задавать переназначение ввода/вывода.
Вызвавший функцию
system() процесс ожидает исполнения команды.
После выполнения
cmd порожденный процесс
sh завершается, и его статус завершения передается в родительский процесс как результат функции
system().
Программу-интерпретатор
sh можно вызывать с двумя параметрами: флагом «–c» и параметром-командой, которую нужно выполнить, например:
$ sh –c "ls | cat –n"
В результате будет запущен процесс
sh, он выполнит переданную ему как параметр команду «
ls | cat –n» и завершится.
Используем возможность опции «–с» для реализации
system().
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
/* эмуляция функции system () */
int MySystem ( const char* cmd )
{
pid_t pid;
int status;
switch ( pid=fork() )
{
case (pid_t) -1:
/* fork не удался */
return -1;
case (pid_t) 0:
execl ( "/bin/sh", "sh", "-c", cmd, 0 );
perror ( "execl" );
exit ( errno );
default:
/* nothing */;
}
if ( pid == waitpid ( pid, &status, 0 ) && WIFEXITED ( status ) )
return ( WEXITSTATUS ( status ) );
return -1;
}
int main ()
{
int return_code=0;
char buf[1024];
do
{
printf ( "sh> " );
fflush ( stdout );
if ( !fgets ( buf, 1024, stdin ) )
break;
return_code = MySystem(buf);
}
while ( !return_code );
return (return_code);
}
В настоящей
system() игнорируются сигналы
SIGINT и
SIGQUIT и блокируется
SIGCHLD.