Я пытаюсь запустить процесс login(1)
как сопроцесс моей программы.
Программа должна получить приглашение для входа и написать имя для входа.
login
процесс запускается как сопроцесс.
Но он завершается непосредственно перед написанием приглашения на вход.
Упрощенная версия программы (удалено написание материала и т. Д.):
int main( int argc, char** argv )
{
int fd1[2];
int fd2[2];
if(( pipe(fd1) != -1 ) && ( pipe(fd2) != -1 ))
{
const pid_t child_pid = fork();
if( child_pid == 0 )
{
dup2( fd2[0], STDIN_FILENO );
dup2( fd1[1], STDOUT_FILENO );
close( fd1[0] );
close( fd1[1] );
close( fd2[0] );
close( fd2[1] );
execl( "/bin/login", "login", (char*)NULL );
fprintf( stderr, "execl failed\n" );
}
else if( child_pid )
{
char buffer[1000];
ssize_t len;
close( fd1[1] );
close( fd2[0] );
len = read( fd1[0], buffer, sizeof(buffer) - 1 );
if( len > 0 )
fprintf( stderr, "%zd bytes received\n", len );
else if( len == 0 )
fprintf( stderr, "read return zero \n" );
else
fprintf( stderr, "read failed: %V \n", errno );
}
else
{
fprintf( stderr, "Fork failed: %V", errno );
}
}
else
{
fprintf( stderr, "Can not open pipes: %V", errno );
}
return 0;
}
Когда я запускаю программу, результат:
~ # my_program
read return zero
~ #
Если я запускаю его с помощью strace, я получаю следующие результаты (удалено множество ненужных строк)
~ # strace -f my_program
[pid 4028] read(3, <unfinished ...>
[pid 4030] execve("/bin/login", ["login"], [/* 12 vars */]) = 0
[pid 4030] ioctl(0, TCGETS or SNDCTL_TMR_TIMEBASE, 0x7bc28aec) = -1 EINVAL (Invalid argument)
[pid 4030] exit_group(1) = ?
Process 4030 detached
[pid 4028] <... read resumed> ""..., 999) = 0
[pid 4028] --- SIGCHLD (Child exited) @ 0 (0) ---
[pid 4028] write(2, "read return zero \n"..., 18) = 18
Процесс login
завершает работу после неудачного вызова ioctl(STDIN_FILENO, TCGETS,)
.
login
похоже ожидает, что вход fd является терминалом или последовательной линией.
Есть ли способ исправить мою программу?