logo

utils

~/.local/bin tools and git-hooks git clone https://hacktivis.me/git/utils.git
commit: 0c0a6d40e26ff63dbd1d3410e485d21bc2ec3a83
parent ef38ed2082a808feca4448acb8c32fbe161cdd77
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Sat,  3 Jun 2023 05:00:37 +0200

cmd/touch: Remove usage of access(3)

Diffstat:

Mcmd/touch.14+++-
Mcmd/touch.c73++++++++++++++++++++++++++++---------------------------------------------
2 files changed, 31 insertions(+), 46 deletions(-)

diff --git a/cmd/touch.1 b/cmd/touch.1 @@ -76,6 +76,8 @@ is mostly compliant with the .St -p1003.1-2008 specification ( .Fl t -is intentionally missing) +is intentionally missing and +.Xr futimens 3 +is always used) .Sh AUTHORS .An Haelwenn (lanodan) Monnier Aq Mt contact@hacktivis.me diff --git a/cmd/touch.c b/cmd/touch.c @@ -2,16 +2,17 @@ // SPDX-FileCopyrightText: 2023 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me> // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only -#define _DEFAULT_SOURCE // tm_gmtoff/tm_zone -#define _XOPEN_SOURCE // strptime -#include <fcntl.h> /* open */ -#include <stdbool.h> /* bool */ -#include <stdio.h> /* perror, sscanf */ -#include <stdlib.h> /* exit */ -#include <string.h> /* memset */ -#include <sys/stat.h> /* futimens, stat */ -#include <time.h> /* strptime, tm */ -#include <unistd.h> /* access */ +#define _DEFAULT_SOURCE // tm_gmtoff/tm_zone +#define _XOPEN_SOURCE // strptime +#include <errno.h> /* errno */ +#include <fcntl.h> /* open */ +#include <stdbool.h> /* bool */ +#include <stdio.h> /* perror, sscanf */ +#include <stdlib.h> /* exit */ +#include <string.h> /* memset */ +#include <sys/stat.h> /* futimens, stat */ +#include <time.h> /* strptime, tm */ +#include <unistd.h> /* access */ // Calls exit() on failure struct timespec @@ -63,13 +64,14 @@ iso_parse(char *arg) int main(int argc, char *argv[]) { - bool ch_atime = false, ch_mtime = false, no_create = false; + bool ch_atime = false, ch_mtime = false; char *ref_file = NULL; struct timespec times[2] = { {.tv_sec = 0, .tv_nsec = UTIME_OMIT}, // access {.tv_sec = 0, .tv_nsec = UTIME_OMIT} // modification }; struct timespec target = {0, UTIME_NOW}; + int open_flags = O_WRONLY | O_CREAT | O_NOCTTY; int c = 0; while((c = getopt(argc, argv, ":acmr:t:d:")) != -1) @@ -80,7 +82,7 @@ main(int argc, char *argv[]) ch_atime = true; break; case 'c': - no_create = true; + open_flags ^= O_CREAT; break; case 'm': ch_mtime = true; @@ -136,42 +138,23 @@ main(int argc, char *argv[]) for(int i = 0; i < argc; i++) { - if(access(argv[i], F_OK) != 0) + int fd = open(argv[i], open_flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + if(fd == -1) { - if(no_create) - { - // Undefined return value in POSIX - return 1; - } - - // File doesn't exists - int fd = creat(argv[i], S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); - - if(fd == -1) - { - perror("touch: open"); - return 1; - } - - if(futimens(fd, times) != 0) - { - perror("touch: futimens"); - return 1; - } - - if(close(fd) != 0) - { - perror("touch: close"); - return 1; - } + if(errno != ENOENT) perror("touch: open"); + return 1; } - else + + if(futimens(fd, times) != 0) { - if(utimensat(AT_FDCWD, argv[i], times, 0) != 0) - { - perror("touch: utimensat"); - return 1; - } + perror("touch: futimens"); + return 1; + } + + if(close(fd) != 0) + { + perror("touch: close"); + return 1; } }