link(link_target, hardlink_tmp); rename(hardlink_tmp, hardlink);
내 코드는 항상 유효한 dentry 를 갖는 것을 목표로 비슷한 작업을 수행하고 있습니다 hardlink
. 나는 그것이 계속 작동 dentries
하고 결코 뒤처지지 않기를 바랍니다 hardlink_tmp
.
그런데 오늘 남은 hardlink_tmp
파일이 많이 발견되었습니다. 검색 rename(2)
결과:
If oldpath and newpath are existing hard links referring to the same file, then rename() does nothing, and returns a success status.
다음과 같은 문구가 약간 다릅니다 rename(3p)
.
If the old argument and the new argument resolve to either the same existing directory entry or different directory entries for the same existing file, rename() shall return successfully and perform no other action.
unlink(hardlink_tmp);
이제 오래되었을 가능성이 있는 디렉터리 항목을 마지막으로 삭제해야 합니다 .
이것이 바람직한 행동인 이유는 무엇입니까?
답변1
두 이름을 동일한 파일로 바꾸는 것에 대한 POSIX 사양에도 제한 사항이 있습니다."이유" 섹션에는 다음과 같이 나와 있습니다.:
이전 파일과 새 파일이 동일한 파일을 참조하는 경우 사양은 다음을 보장합니다.
rename("x", "x");
파일은 삭제되지 않습니다.
이것은 다소 단순하지만 이론적 근거에서 rename()
+에 대한 대안도 언급했다는 점을 고려하면 다음과 같습니다. link()
unlink()
——순전히 추측입니다——간단한 구현은 rename(x, y)
으로 구현할 수 있습니다 unlink(y) && link(x, y) && unlink(x)
. 그러나 과 의 이름 x
이 y
같으면 첫 번째 단계에서 파일이 사라집니다.
rename("../foo/x", "x")
또한 두 이름이 완전히 동일한 문자열인지 확인하는 것만으로는 충분하지 않습니다. 비슷한 상황 (앉아 있을 때 foo/
) 또는 더 나쁜 상황 rename("/dir/symlink/x", "x")
(심볼릭 링크로 인해 다시 돌아가는 경우 .
) 이 발생할 수 있기 때문입니다 . 두 문자열의 결과가 동일한 파일 이름인지 확인하는 것은 쉽지 않지만, stat()
두 문자열을 모두 호출하고 장치 및 inode 번호를 확인하여 동일한 inode인지 확인하는 것이 더 쉽습니다. 그런 다음 두 개의 파일 이름이 다르지만 동일한 파일인 경우에도 이름 바꾸기를 거부합니다.
rename()
이는 예상한 대로 최신 스마트 구현이 더 나은 성능을 발휘할 수 없다는 의미는 아니지만 "항상 작동하는 방식"을 기반으로 코딩되었을 수 있습니다. (추측 끝.)