sbase

suckless unix tools
git clone git://git.suckless.org/sbase
Log | Files | Refs | README | LICENSE

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:
Atests/0052-touch.sh | 13+++++++++++++
Mtouch.c | 2+-
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);