2014-02-18 3 views
1

하나의 HTTP 요청을 처리하는 여러 스레드를 생성하는 데몬 프로세스가 있습니다. 데몬 프로세스가 상대 경로를 통해 지정된 파일을 찾을 수 없습니다.

void * read_file_ex(char *file_name, int32_t *data_len) { 
    FILE *fp; 
    fp = fopen(file_name, "r"); 
    ... // more code to fetch file contents 
    fclose(fp); 
} 

void * read_file(char *file_name){ 
    return read_file_ex(file_name, NULL); 
} 

그리고 스레드에서

, 내가 전화 :

read_file("resources/html/index.html");  

코드가 함께 충돌 핸들러는 나는 다음과 같은 코드가

resources/html/index.html 

에있는 파일을 반환하기위한 것입니다 해당 파일에 대한 요청이있을 때 "분할 오류"오류가 발생합니다.

fopen에서 깨기 위해 GDB를 사용할 때 NULL이 반환되고 errno이 2 (파일을 찾을 수 없음)로 설정되어 있음을 확인합니다. 또한

, 나는 파일의 절대 경로를 사용하는 코드를 변경할 때 :

/usr/sbin/app/resources/html/index.html 

다음`는 fopen() 인덱스 파일을 찾을 수 있으며, 모든 것이 잘 작동합니다.

또 다른 언급 할 점은 데비안 리눅스에서 실행할 때이 오류가 발생하지만 우분투 12.04에서는 내 질문이 멍청한 것처럼 보일 수 있다는 것입니다.

'resources'폴더가 들어있는 동일한 폴더에서 프로그램을 실행하고 있다는 것을 잊어 버렸습니다.

+0

'read_file_ex() '를 호출 할 때 현재 작업 디렉토리는 무엇입니까? –

+0

왜'fopen'의 직후에 파일을'fclose'할까요? 'fclose' 다음에 파일을 읽을 수 없습니다; 이것이'SegFault'의 원인입니다. – ahmad

+0

'resources' 폴더가 들어있는 동일한 폴더에서 프로그램을 실행합니다. GDB에서 현재 디렉토리가 프로그램을 시작한 디렉토리와 동일하다는 것을 알았습니다. 스레드의 현재 디렉토리가 무엇인지 확인할 수있는 다른 방법이 있는지 확실하지 않습니다. –

답변

3

프로세스의 현재 디렉토리가 /usr/sbin/app이 아니며 (현재 디렉토리가 /usr/bin/app 일 가능성은 희박합니다) 상대 경로 이름이 작동하지 않습니다. 항상이어야합니다. 사용하기 전에 fopen()에서 반품 결과를 확인하십시오. 올바른 디렉토리에 있어도 열려있는 작업이 실패 할 수있는 수많은 이유가 있습니다.

프로세스가 daemon()과 같은 기능을 사용하거나 daemonize 프로그램을 통해 실행되는 경우 다른 위치에있을 것으로 예상하더라도 현재 디렉터리를 /으로 변경할 수 있습니다.

프로세스의 현재 디렉토리를 확인해야하는 경우 (프로세스에 모든 스레드에 공통된 단일 현재 디렉토리가 있음) getcwd()을 사용하여 현재 작업 디렉토리를 가져올 수 있습니다.

프로세스를 디몬 처리 한 후에 디렉토리를 다시 변경해야하는 경우 chdir()을 사용하면됩니다. 또한 fchdir()이 있는데이 디렉토리에 대한 파일 설명자가 열려 있으면 디렉토리로 다시 변경할 수 있습니다.

+0

방금'getcwd()'를 추가했는데 작업 디렉토리가 실제로/usr/sbin/app /가 아니라는 것을 알았습니다. cwd를 실행하는 방법이 있습니까? –

+3

@RockyInde'chdir()'을 사용하여 cwd를 변경할 수 있습니다. –

관련 문제