2017-01-08 5 views
2

"File2가 없으면 File1의 이름을 File2로 바꾸십시오. 그렇지 않으면 오류가 발생합니다"라는 어 플 플랫폼 특정 방법이 있습니까? File2가 존재하는지 여부를 확인한 다음 파일 이름을 변경하지 않으면 파일의 이름을 바꿀 수 있다는 것을 알았지 만 다른 프로세스가 수표와 rename() 사이에 File2를 만들면 잠재적 인 경쟁 조건이 발생합니다.C 플랫폼 간 renameat2() rename-if-not-exists 기능

리눅스에서는 정확히 RENAME_NOREPLACE 플래그가 설정된 renameat2() 기능이 있습니다. 불행하게도 맨 페이지에 의하면

renameat2()는 Linux에만 해당합니다.

모든 libc 구현이이 호출을 지원하는지 또는 glibc 만 지원하는지 알지 못합니다.

내 용도로는 같은 디렉토리에서 이름을 바꾸면 충분하지만 완전히 다른 경로로 이동할 필요는 없습니다.

이 잠재적으로 https://stackoverflow.com/a/230581/5562035 관련되어 Atomically swap contents of two files on Linux

+0

어떤 의미에서 원자입니까? 특히'rename()'과'renameat()'에 대한 리눅스 문서는 "oldpath와 newpath 둘 다 이름이 바뀌는 파일을 가리키는 창이있을 것입니다." –

+0

상식을 사용하십시오. –

+0

대상 파일의 존재 여부와 다른 프로세스가 대상 파일을 만들 수있는 이름 바꾸기 사이에 시간 창이 없어야합니다. 이 조건이 없으면'if (! file_exists (path_2)) {rename (path_1, path_2)}' – buggy3

답변

2

원자를하는 비 플랫폼 별 방법이 있나요 "있는 File2이 존재하지 않는 경우 File1을 File2로 이름을 변경, 그렇지 않으면 오류를 줄?"

은 C 표준 라이브러리는 rename() 파일 이름을 변경 제공하며, 표준은 그 기능에 대해이 말한다 : "문자열이라는 이름의 파일이 new가 가리키는 경우 rename 함수를 호출하기 전에 존재의 행동은 구현에 따라 정의됩니다. " 따라서 "비 플랫폼 특정"이 "C 표준에 의해 지정됨"으로 해석되면 아니오, 그러한 메커니즘이 없습니다. 우리가 POSIX에 의해 지정된 시설을 허용하는 "비 플랫폼 별"의 범위를 확장하면

그러나, 당신은, link()에 의존 할 수있는

는 원자 기존 파일의 새 링크를 생성해야

파일의 링크 카운트는 1 씩 증가한다. [... 두 번째 인수]가 기존 디렉토리 항목으로 해석되거나 기호 링크를 참조하는 경우 [[및] 이 실패합니다.

따라서 지정된 경로 이름이 기존 파일 또는 심볼릭 링크를 지정하면 실패하고 새로운 링크는 성공할 때 원본 링크를 제거 할 수 있습니다.

당신이 관심을 가질만한 가장 눈에 띄는 비 POSIX 플랫폼은 Windows입니다. Windows에서 묻는 것을 할 수있는 방법이 있는지 확실하지 않지만,있을 경우 POSIX 또는 Windows 구현을 선택하기 위해 조건부 컴파일을 사용하는 래퍼 함수를 ​​작성하는 것이 좋습니다.