나는 신호, 포크 및 execve로 놀고있다. 그리고 다른 장난감 프로그램을 호출하는 자식 프로세스를 만들기 위해 fork()
을 사용하는 장난감 프로그램을 작성했다. 그런 다음 부모는 일정 시간 (초) 후에 기능을 중지시키는 경보를 설정합니다.C : 매개 변수로 함수를 선언하면 해당 동작이 변경됩니다 ...?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <signal.h>
pid_t childPid;
pid_t Fork()
{
pid_t pid;
if ((pid = fork()) < 0)
printf("Error:\n");
return pid;
}
void killhandler(int sig)
/*This will be called when we receive a SIGALRM*/
{
int status;
printf("\nAssassin: *ksh* Received order to kill process: %d\n", (int)childPid);
if (!(status = kill(childPid, SIGKILL))) {
printf("Assassin: Clean and discreet. My work here is done. *ksh*\n");
} else {
printf("Assassin: He got away!\n");
}
}
void forkyMcFork()
{
pid_t pid;
int status;
/*Generate information for new program*/
char* argv[] = {"problem5", "Hello"};
char* envp[] = {"PANTS=JEANS"};
char* func = "problem5";
/* Create child process, child process calls executable "problem5" */
if ((pid = Fork()) == 0) {
printf("Child: I am a child! Woohoo!\n");
if (execve(func, argv, envp) < 0)
printf("Child: error, %s not found\n", func);
while(1);
}
else {
/* Parent process sets alarm, then prints a message depending on exit status*/
childPid = pid;
alarm(3);
printf("Parent: I am the parent!\n");
waitpid(-1, &status, 0);
if (!WIFEXITED(status)) {
printf("Parent: Oh no, what happened to my baby!!!\n");
exit(0);
} else {
printf("Parent: Child came home without any problems.\n");
}
}
}
int main(int argc, char const *argv[])
{
signal(SIGALRM, killhandler);
forkyMcFork();
return 0;
}
여기에 이상한 부분이있다 : 나는 매개 변수를 고려하지 않기 때문에 기능 forkyMcFork()
를 선언 한 후 수동으로 alarm()
에 대한 인수를 설정하면, 그것은 내가 기대하는 것처럼 단지 작동 : 자식 프로세스가 problem5
을 시작을 요청하는 사용자로부터 어떤 입력 한 다음 삼초, killhandler
실행 한 후, 자식 프로세스를 발견하고 그것을 죽이고 : 내가 대신 forkyMcFork(int secs)
선언하고 alarm(secs)
에 의해 호출 할 필요가 외부 프로그램을 사용하는 경우,
$ ./forkfun
Parent: I am the parent!
Child: I am a child! Woohoo!
Please type name. If finished press enter: Haha
Please type name. If finished press enter:
Assassin: *ksh* Received order to kill process: 42409
Assassin: Clean and discreet. My work here is done. *ksh*
Parent: Oh no, what happened to my baby!!!
$
그러나 execve()
하위 프로그램의 문을 찾을 수 없습니다. 알람이 예상대로 실행되므로 몇 초가 지나면 하위 프로세스가 액세 스됩니다. forkyMcFork
여부를 void
을 복용으로 선언
$ ./forkfun
Parent: I am the parent!
Child: I am a child! Woohoo!
Child: error, problem5 not found
Assassin: *ksh* Received order to kill process: 42400
Assassin: Clean and discreet. My work here is done. *ksh*
Parent: Oh no, what happened to my baby!!!
$
그래서 명확하게하기 위해, 여기에 코드 만 차이가있다 : 여기
은 비 작동 코드입니다 :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <signal.h>
pid_t childPid;
pid_t Fork()
{
pid_t pid;
if ((pid = fork()) < 0)
printf("Error:\n");
return pid;
}
void killhandler(int sig)
/*This will be called when we receive a SIGALRM*/
{
int status;
printf("\nAssassin: *ksh* Received order to kill process: %d\n", (int)childPid);
if (!(status = kill(childPid, SIGKILL))) {
printf("Assassin: Clean and discreet. My work here is done. *ksh*\n");
} else {
printf("Assassin: He got away!\n");
}
}
void forkyMcFork(int secs)
{
pid_t pid;
int status;
/*Generate information for new program*/
char* argv[] = {"problem5", "Hello"};
char* envp[] = {"PANTS=JEANS"};
char* func = "problem5";
/* Create child process, child process calls executable "problem5" */
if ((pid = Fork()) == 0) {
printf("Child: I am a child! Woohoo!\n");
if (execve(func, argv, envp) < 0)
printf("Child: error, %s not found\n", func);
while(1);
}
else {
/* Parent process sets alarm, then prints a message depending on exit status*/
childPid = pid;
alarm(secs);
printf("Parent: I am the parent!\n");
waitpid(-1, &status, 0);
if (!WIFEXITED(status)) {
printf("Parent: Oh no, what happened to my baby!!!\n");
exit(0);
} else {
printf("Parent: Child came home without any problems.\n");
}
}
}
int main(int argc, char const *argv[])
{
signal(SIGALRM, killhandler);
forkyMcFork(5);
return 0;
}
그리고 여기에 그 출력의 ,이 경우 작동하거나, int secs
을 취하는 것으로 간주합니다. 무슨 일이야?
'execve'에서 오류가 발생하면'errno'의 값을 출력하거나 ['strerror'] (http://linux.die.net/man/3/strerror)를 사용하여 에러 코드의 인쇄 가능한 텍스트 –
또한 성공한 프로그램 대신 _fails_ 프로그램을 보여주십시오. –
ForkyMcFork()의 argv 및 envp 변수 끝에 null 인수를 추가하십시오. 어느 버전의 운이 좋든 운이 좋을 수도 있습니다. – Duck