2016-03-16 3 views
0

Я в основном создаю функцию, которая вызывает встроенную функцию unix и перенаправляет ее вывод на "myexec.txt". Поэтому я вызвал open и dup2 в дочернем процессе. Они перенаправляют вывод execve на "myexec.txt". При вызове execve дочерний процесс завершается, и каждый другой стандартный вывод после выполнения execve теперь будет перенаправлен на терминал. Я ищу способ прекратить дочерний процесс в случае неуспешного вызова execve, чтобы остановить перенаправление вывода до myexec.txt. Я знаю, что работает exit, но есть ли способ убить этот процесс, не возвращая значения? Моя функция должна вернуть void.Завершение дочернего процесса без возврата значения

Вот мой кусок кода. Я намеренно даю execve несуществующий путь.

void myexec() 
{ 
    pid_t pid; 
    pid = fork(); 
    if(pid == 0) 
    { 
     printf("executing ls\n"); 
     char *argv[] = {"ls", 0}; 
     int fd = open("myexec.txt", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); 
     dup2(fd, 1); 
     dup2(fd, 2); 
     close(fd); 
     execve("/bsin/ls", &argv[0], NULL); 
     fprintf(stderr, "Failed to execute"); 
     ...... 
    } 
    wait(NULL); 
    printf("Function execution have been attempted"); 
} 
+0

Знаете ли вы разницу между «функцией, возвращающей значение» и «процессом, возвращающим значение»? – immibis

+0

Я считаю, что знаю. 'myexec' - это функция, которая не возвращает значения. при запуске функции он создает процесс. fork создает два процесса. 'execve' переводит вызывающий дочерний процесс. Все, что возвращается этим новым процессом, - это процесс, возвращающий значение. Поправьте меня, если я ошибаюсь – TheValars

+0

Конечно. Но вы сказали, что вам нужен * процесс *, чтобы не возвращать значение, потому что функция * возвращает void. Это немного похоже на вопрос: «Я знаю, что могу использовать ручку громкости на своих динамиках, но как я могу убедиться, что они не станут громче, чем 600 литров? Мой холодильник имеет объем 600 литров». – immibis

ответ

1

Не звоните exit. Это серьезная ошибка, которая привела к серьезным ошибкам в прошлом со значительными последствиями для безопасности.

Звоните _exit. Вы можете передать ему нуль, не имеет значения, не заботится ли родитель, не удалось или нет. Поскольку _exit гарантированно не вернется, после этого вам не нужно ничего ставить.

if(pid == 0) 
{ 
    printf("executing ls\n"); 
    char *argv[] = {"ls", 0}; 
    int fd = open("myexec.txt", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); 
    dup2(fd, 1); 
    dup2(fd, 2); 
    close(fd); 
    execve("/bsin/ls", &argv[0], NULL); 
    fprintf(stderr, "Failed to execute"); 
    _exit(EXIT_FAILURE); 
} 
+0

Можете ли вы предоставить некоторые ссылки на подробности ошибок, вызванных использованием 'exit'? – immibis

+0

После того, как вы закончили форк, но перед успешным исполнением у вас есть две копии всего, что было в памяти: две копии каждого выходного потока, который должен быть очищен при выходе, две копии каждой функции очистки, зарегистрированной с помощью 'atexit', которая вот-вот появится когда вы выходите. Обычно '_exit' - это выход * без * выполнения каких-либо действий по очистке. –

+0

@immibis Что сказал Стив. Представьте себе, например, что родитель написал какой-то чувствительный к безопасности вывод в поток и удерживается в буфере потока. Ребенок закрывает дескриптор файла потока и открывает новый файловый дескриптор, который получает тот же номер, скажем, серверу регистрации. Когда вы вызываете 'exit', обработчик' atexit' может очищать чувствительный к безопасности вывод к файловому дескриптору, который теперь указывает на сервер регистрации. К сожалению. Ты только что записал секрет. (Да, это действительно произошло.) –

Смежные вопросы