Skip to content

Commit

Permalink
Add option to avoid following symlinks (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
Delgan committed Jan 22, 2022
1 parent 7a0219b commit d595506
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 3 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ pip install win32-setctime
```python
from win32_setctime import setctime

setctime("my_file.txt", 1561675987.509)
setctime("my_file.txt", 1561675987.509, follow_symlinks=True)
```
23 changes: 23 additions & 0 deletions tests/test_setctime.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,26 @@ def test_fix_file_tunneling(tmp_path):
assert getctime(filepath) == before
setctime(filepath, timestamp)
assert getctime(filepath) == timestamp


@pytest.mark.parametrize("follow_symlinks", [True, False])
def test_with_symlinks(tmp_path, follow_symlinks):
target_path = tmp_path / "target.txt"
symlink_path = tmp_path / "symlink.txt"
timestamp = 123456789
target_path.touch()
time.sleep(0.1)
symlink_path.symlink_to(target_path)
target_ctime = target_path.lstat().st_ctime
symlink_ctime = symlink_path.lstat().st_ctime

assert target_ctime != symlink_ctime

setctime(symlink_path, timestamp, follow_symlinks=follow_symlinks)

if follow_symlinks:
assert symlink_path.lstat().st_ctime == symlink_ctime
assert target_path.lstat().st_ctime == timestamp
else:
assert symlink_path.lstat().st_ctime == timestamp
assert target_path.lstat().st_ctime == target_ctime
9 changes: 7 additions & 2 deletions win32_setctime.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
__all__ = ["setctime"]


def setctime(filepath, timestamp):
def setctime(filepath, timestamp, *, follow_symlinks=True):
"""Set the "ctime" (creation time) attribute of a file given an unix timestamp (Windows only)."""
if not SUPPORTED:
raise OSError("This function is only available for the Windows platform.")
Expand All @@ -55,7 +55,12 @@ def setctime(filepath, timestamp):
mtime = wintypes.FILETIME(0xFFFFFFFF, 0xFFFFFFFF)
ctime = wintypes.FILETIME(timestamp & 0xFFFFFFFF, timestamp >> 32)

handle = wintypes.HANDLE(CreateFileW(filepath, 256, 0, None, 3, 128 | 0x02000000, None))
flags = 128 | 0x02000000

if not follow_symlinks:
flags |= 0x00200000

handle = wintypes.HANDLE(CreateFileW(filepath, 256, 0, None, 3, flags, None))
if handle.value == wintypes.HANDLE(-1).value:
raise WinError(get_last_error())

Expand Down

0 comments on commit d595506

Please sign in to comment.