summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2022-03-13 13:48:55 -0400
committerJakob Kaivo <jkk@ung.org>2022-03-13 13:48:55 -0400
commit710cfa9ab7284499ce57b07a5525f8e8e1d884d5 (patch)
treedead83275a581a52e054c5de6f6fe986f8e24619
parent9af2c490ad435ddb61b9d79174ffa7c05a1399dd (diff)
implement precisely the algorithm from POSIX
-rw-r--r--touch.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/touch.c b/touch.c
index fd9e6ef..97da03a 100644
--- a/touch.c
+++ b/touch.c
@@ -39,20 +39,26 @@ enum times {
static int touch(const char *path, struct timespec times[2], int create)
{
- int fd = open(path, (create ? O_CREAT : 0), 0644);
+ if (access(path, F_OK) == 0) {
+ return utimensat(AT_FDCWD, path, times, 0);
+ }
+
+ if (!create) {
+ return 0;
+ }
+
+ int fd = creat(path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if (fd == -1) {
- if (!create && errno == ENOENT) {
- return 0;
- }
fprintf(stderr, "touch: %s: %s\n", path, strerror(errno));
return 1;
}
+
if (futimens(fd, times) != 0) {
fprintf(stderr, "touch: %s: %s\n", path, strerror(errno));
close(fd);
return 1;
}
- close(fd);
+
return 0;
}
@@ -117,7 +123,7 @@ int main(int argc, char *argv[])
switch (how) {
case CURRENT:
times[0].tv_nsec = UTIME_NOW;
- times[0].tv_nsec = UTIME_NOW;
+ times[1].tv_nsec = UTIME_NOW;
break;
case DATE:
/* TODO */