commit 23160db9e0b545cead16ac48f23dc31eff2f1b1b
parent 004a51426e42d42150a746dc113ad86fb3fbed3c
Author: Michael Forney <mforney@mforney.org>
Date: Tue, 17 Mar 2026 01:09:29 -0700
touch: prevent file creation race between utimensat() and open()
If another process creates the file after we determined it was
missing, touch would fail on open() due to O_EXCL. This failure
doesn't serve any purpose; we want to update the mtime either way.
Diffstat:
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/tests/0052-touch.sh b/tests/0052-touch.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+tmp1=tmp1.$$
+tmp2=tmp2.$$
+
+trap 'rm -f $tmp1 $tmp2' EXIT
+trap 'exit $?' HUP INT TERM
+
+../touch -t 200711121015 $tmp1
+
+echo 'Modify: 2007-11-12 10:15:00.000000000' > $tmp2
+
+stat $tmp1 | awk '/^Modify:/ {$4 = ""; print}' | diff -wu - $tmp2
diff --git a/touch.c b/touch.c
@@ -26,7 +26,7 @@ touch(const char *file)
eprintf("utimensat %s:", file);
if (cflag)
return;
- if ((fd = open(file, O_WRONLY | O_CREAT | O_EXCL, 0666)) < 0)
+ if ((fd = open(file, O_WRONLY | O_CREAT, 0666)) < 0)
eprintf("open %s:", file);
ret = futimens(fd, times);
close(fd);