2014-09-21 2 views
0

그래서 교수님이 나에게 준 코드를 실행하려고합니다. 그것은 간단합니다. 포크 (fork)는 포크가 제대로 작동하는지 확인한 다음 별도의 파일에서 다른 코드를 실행합니다.프로세스 포크가 원하는 코드를 실행하지 않습니다.

내 OS X 10.9.5 시스템에서 두 번째 코드가 실행되지 않습니다. 다음은 프로그램의 모두 :

exercise.c

#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/wait.h> 


int main() { 
    pid_t child = fork(); 
    if ((int)child < 0) { 
    fprintf(stderr, "fork error!\n"); 
    exit(0); 
    } else if ((int)child > 0) { 
    int status; 
    (void) waitpid(child, &status, 0); 
    if (WIFEXITED(status)) { 
     printf("child %d exited normally and returned %d\n", 
     child, WEXITSTATUS(status)); 
    } else if (WIFSIGNALED(status)) { 
     printf("\nchild %d was killed by signal number %d and %s leave a core dump\n", 
     child, WTERMSIG(status), (WCOREDUMP(status) ? "did" : "didn't")); 
    } else { 
     printf("child %d is dead and I don't know why!\n", child); 
    } 
    } else { 
    char *argv[] = { "./getcode" }; 
    execve(argv[0], argv, NULL); 
    } 

    return 0; 
} 

그리고 getcode.c

#include <stdio.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <stdlib.h> 


int main() { 
    int rc = 256; 
    printf("I am child process %d\n", getpid()); 
    while ((rc > 255) || (rc < 0)) { 
    printf("please type an integer from 0 to 255: "); 
    scanf("%d", &rc); 
    } 
    exit(rc); 
} 

는 내가 명령을 모두 컴파일 :

gcc -Wall -pedantic-errors exercise.c -o exercise 

gcc -Wall -pedantic-errors getcode.c -o getcode 

불행하게도, 난 다시 자식 프로세스에서 얻을 수있는 유일한 것은 내가 당황 해요 0

./exercise 
child 903 exited normally and returned 0 

의 리턴 코드입니다. 누구든지 도와 줄 수 있습니까?

EDIT : 좋아요, 요청에 따라 perror("execve")을 포함 시켰으며, execve: Bad address을 반환합니다. 어떻게 해결할 수 있습니까?

EDIT2 : 좋습니다. 나는 그것을 고쳤다. 위 코드의 내용을 다음과 같이 변경했습니다.

char *argv[] = { "./getcode",NULL }; 
execve(argv[0], argv, NULL); 

null 종료로 인해 argv 문제가 해결되었습니다.

+0

'char * argv [] = { "./getcode", NULL};' – wildplasser

답변

1

argv를 NULL 요소로 종료해야합니다. execve 맨 페이지에서 :

Both argv and envp must be terminated by a NULL pointer. 

또한 NULL이 envp 인수에 유효하지 않은지는 분명하지 않습니다. Linux 매뉴얼 페이지에

이 있습니다. Linux에서는 argv를 NULL로 지정할 수 있습니다.이 인수는이 인수를 단일 NULL 포인터를 포함하는 목록에 대한 포인터로 지정하는 것과 동일한 효과가 있습니다. 이 위조를 이용하지 마십시오! 이것은 비표준이며 이식성이 없습니다 : 대부분의 다른 UNIX 시스템에서이 작업을 수행하면 오류가 발생합니다 (EFAULT).

아마도 envp를 NULL로 지정하는 것은 비표준 일 수 있습니다. 환경을 지정할 필요가 없으면 execve가 아닌 execv를 사용하십시오.

execve의 반환 값을 확인해야합니다. 그리고 원인을 결정하기 위해 errno를 사용하십시오. 예 : perror("execve")을 사용하십시오. 불평 할 수 있습니다.

+1

알았어, 혼란에 죄송합니다. 널 포인터로 argv를 종료 한 후 미안합니다. 도와 줘서 고마워. 나는 그것을 더 일찍 시도했을 것이다. 그러나 그것은 실제로 초기에 작동했고, 약간의 수정 작업 후에 작동을 멈췄다. 다시 한 번 감사드립니다! – mike10010100

+0

차가움.불특정 행동으로 인한 데이터 종속 버그는 더러운 것입니다. –

1

execve 호출의 결과를 확인하지 않아서 실패한 것 같아서 하위 프로세스가 main의 끝에 return 0에 도달했습니다.

관련 문제