2011-01-23 5 views
0

좋아요, 그래서 저는 게임을 쓰고 있습니다.이 게임에는 대화 형 설정 메뉴가 있습니다. 내가하고 싶은 일은 파일에 존재하지 않는 경우 파일에 쓰고 그럴 경우 파일을 읽고 파일에 지정된 설정을 적용한 다음 사용자가 설정을 변경하도록 선택한 경우 사용자의 새 설정으로 덮어 쓰고 싶습니다. . 그러면 다음과 같이 될 것입니다. (가짜 코드)fopen의 두 번째 인수

if (file does not exist) 
    write_defaults 
open settings 
read from file 
apply settings specified in file 
while (user is changing settings) 
    if (user is done) break 
write new settings to file 
apply new settings 

이제 fopen의 두 번째 인수에는 무엇을 사용할 수 있습니까? 나는 "r +"와 "w +"를 시도했지만 두 가지 모두에 문제가있었습니다.

+1

어떤 문제가 있습니까? – Davidann

답변

0

"r+"을 사용하면 첫 번째 시도에서 정확합니다. 파일이 없기 때문에 실패하면 "w+"으로 다시 시도하십시오. 이렇게하면 파일을 열어 업데이트 할 수 있지만 파일이 이미 존재하는 경우에는 파일이 손상되지 않습니다.

그러나 이것은 TOCTOU (점검 시간, 사용 시간) 취약점이 있다는 의미에서 차선책입니다. 파일이 실패한 열기 "r+"과 성공적으로 열린 파일 "w+" 사이에 생성되면 파일이 손실됩니다.

당신이 POSIX 기능에 액세스 할 수있는 경우, 당신은 open() 대신 fopen() 파일 스트림으로 파일 기술자를 변환하는 fdopen() 다음에, 하나 개의 원자 시도에서 제대로 일을 할 수 있습니다.

FILE *carefully_open(const char *file) 
{ 
    int fd = open(file, O_RDWR | O_CREAT, 0644); 
    FILE *fp = 0; 

    if (fd >= 0) 
     fp = fdopen(fd, "r+"); 
    if (fd >= 0 && fp == 0) 
     close(fd); 
    return fp; 
} 

단점은 단절된 심볼릭 링크를 통해 파일을 생성한다는 것입니다. O_EXCL 플래그로이를 피할 수 있지만 파일이 존재하면 열기가 실패합니다. 결국 open()으로 전화를 걸면 결국 O_RDRW이고 두 번째 전화는 O_RDRW | O_CREAT | O_EXCL으로 두 번 부러진 symlnks에 대해 안전합니다.

(무엇 현재 디렉토리에는 파일 pqr이없는 경우 깨진 심볼릭 링크가?, ln -s ./pqr xyzxyz 표시된 open() 호출로 파일 'PQR을'만들어 '고정'됩니다 깨진 심볼릭 링크는 것을 의미합니다.)

어떤 문제가 있습니까?

2

쓰기 작업에 대해 "w"으로 열었으며 임의의 종류의 동시 읽기/쓰기를 수행하지 않는 한 읽기 작업에 대해 "r"으로 다시 엽니 다.

@stefan이 아래 주석에서 언급 했으므로 텍스트가 아닌 원시 이진 데이터를 조작하는 경우 "rb" 또는 "wb"이 필요합니다.

+1

예, 이것은 fopen을 사용하여 필요한 것 이상으로 파일을 열어 두지 않아야하는 올바른 방법입니다. 열기 - 읽기 - 닫기. 열기 - 쓰기 - 닫기. 또한 작성중인 데이터에 따라 b를 추가해야 할 수도 있습니다. – stefan

+0

@stefan : 좋은 지적입니다. 나는 그것을 나의 대답에 추가했다. –

+0

좋아, 그걸 시도 할께. 감사. – Babkock

0

파일을 "r +"로 열면됩니다. 포인터가 NULL이 아닌 경우 반환 된 포인터를 확인하고 파일에서 설정을 읽습니다. 그런 다음 파일에 기록하십시오.