Мне нужно создать функцию, которая, помимо прочего, порождает дочерний процесс.
Я хотел бы передать этой функции дополнительный список файловых дескрипторов, чтобы, в зависимости от потребностей пользователя, ввод / вывод дочернего процесса можно было перенаправить.
Я видел, как десятки людей говорили о том, как сделать это, используя dup2
примерно так:
if( pid < 0 ) // error forking.
{
//...
}
else if( pid != 0 ) // Parent process.
{
ret = waitpid( pid, &status, 0 );
return WEXITSTATUS( status );
}
else // Child process.
{
dup2( fd, STDIN_FILENO ); // Clone passed file discriptor.
close( fd ); // Close the passed one, since we have already cloned.
execvp( arglist[ 0 ], arglist );
}
Хорошо. Все это есть в интернете.
Теперь у меня вопрос: как (или как лучше всего) перенаправить на /dev/null
?
Должен ли я заставить пользователя open( /dev/null)
и передать его как fd
или есть какой-нибудь лучший способ?
EDIT:
Это не так красиво, как мне хотелось, но я не мог найти лучшего способа, поэтому я в итоге передал массив имен файлов туда, куда пользователь мог захотеть перенаправить, соответственно, STDIN, STDOUT и STDERR:
static int do_exec( arglist_t arglist, const char *fio[ 3 ] )
{
DEBUG__( OSU_DEBUG_LEVEL_1, "fio = %p\n", fio );
if ( fio )
{
if ( fio[ STDIN_FILENO ] )
{
int fd = open( fio[ STDIN_FILENO ], O_RDONLY );
if ( -1 < fd )
{
dup2( fd, STDIN_FILENO );
close( fd );
}
}
if ( fio[ STDOUT_FILENO ] )
{
int fd = open( fio[ STDOUT_FILENO ], O_WRONLY | O_CREAT | O_APPEND );
if ( -1 < fd )
{
dup2( fd, STDOUT_FILENO );
close( fd );
}
}
if ( fio[ STDERR_FILENO ] )
{
int fd = open( fio[ STDERR_FILENO ], O_WRONLY | O_CREAT | O_APPEND );
if ( -1 < fd )
{
dup2( fd, STDERR_FILENO );
close( fd );
}
}
}
return execvp( arglist[ 0 ], arglist );
}
- Я еще не полностью протестировал его, поэтому в нем могут быть некоторые ошибки.
Действительно благодаря @Zack и @ gbulmer.