10f66f451Sopenharmony_ci/* touch.c : change timestamp of a file 20f66f451Sopenharmony_ci * 30f66f451Sopenharmony_ci * Copyright 2012 Choubey Ji <warior.linux@gmail.com> 40f66f451Sopenharmony_ci * 50f66f451Sopenharmony_ci * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/touch.html 60f66f451Sopenharmony_ci * 70f66f451Sopenharmony_ci * -f is ignored for BSD/macOS compatibility. busybox/coreutils also support 80f66f451Sopenharmony_ci * this, but only coreutils documents it in --help output. 90f66f451Sopenharmony_ci 100f66f451Sopenharmony_ciUSE_TOUCH(NEWTOY(touch, "<1acd:fmr:t:h[!dtr]", TOYFLAG_BIN)) 110f66f451Sopenharmony_ci 120f66f451Sopenharmony_ciconfig TOUCH 130f66f451Sopenharmony_ci bool "touch" 140f66f451Sopenharmony_ci default y 150f66f451Sopenharmony_ci help 160f66f451Sopenharmony_ci usage: touch FILE... 170f66f451Sopenharmony_ci 180f66f451Sopenharmony_ci Update the access and modification times of each FILE to the current time. 190f66f451Sopenharmony_ci 200f66f451Sopenharmony_ci*/ 210f66f451Sopenharmony_ci 220f66f451Sopenharmony_ci#define FOR_touch 230f66f451Sopenharmony_ci#include "toys.h" 240f66f451Sopenharmony_ci 250f66f451Sopenharmony_ciGLOBALS( 260f66f451Sopenharmony_ci char *t, *r, *d; 270f66f451Sopenharmony_ci) 280f66f451Sopenharmony_ci 290f66f451Sopenharmony_civoid touch_main(void) 300f66f451Sopenharmony_ci{ 310f66f451Sopenharmony_ci struct timespec ts[2]; 320f66f451Sopenharmony_ci char **ss; 330f66f451Sopenharmony_ci int fd, i; 340f66f451Sopenharmony_ci 350f66f451Sopenharmony_ci // use current time if no -t or -d 360f66f451Sopenharmony_ci ts[0].tv_nsec = UTIME_NOW; 370f66f451Sopenharmony_ci 380f66f451Sopenharmony_ci if (FLAG(t) || FLAG(d)) { 390f66f451Sopenharmony_ci time_t t = time(0); 400f66f451Sopenharmony_ci unsigned nano; 410f66f451Sopenharmony_ci 420f66f451Sopenharmony_ci xparsedate(TT.t ? TT.t : TT.d, &t, &nano, 0); 430f66f451Sopenharmony_ci ts->tv_sec = t; 440f66f451Sopenharmony_ci ts->tv_nsec = nano; 450f66f451Sopenharmony_ci } 460f66f451Sopenharmony_ci ts[1]=ts[0]; 470f66f451Sopenharmony_ci 480f66f451Sopenharmony_ci if (TT.r) { 490f66f451Sopenharmony_ci struct stat st; 500f66f451Sopenharmony_ci 510f66f451Sopenharmony_ci xstat(TT.r, &st); 520f66f451Sopenharmony_ci ts[0] = st.st_atim; 530f66f451Sopenharmony_ci ts[1] = st.st_mtim; 540f66f451Sopenharmony_ci } 550f66f451Sopenharmony_ci 560f66f451Sopenharmony_ci // Which time(s) should we actually change? 570f66f451Sopenharmony_ci i = toys.optflags & (FLAG_a|FLAG_m); 580f66f451Sopenharmony_ci if (i && i!=(FLAG_a|FLAG_m)) ts[i!=FLAG_m].tv_nsec = UTIME_OMIT; 590f66f451Sopenharmony_ci 600f66f451Sopenharmony_ci // Loop through files on command line 610f66f451Sopenharmony_ci for (ss = toys.optargs; *ss;) { 620f66f451Sopenharmony_ci char *s = *ss++; 630f66f451Sopenharmony_ci 640f66f451Sopenharmony_ci if (!strcmp(s, "-")) { 650f66f451Sopenharmony_ci if (!futimens(1, ts)) continue; 660f66f451Sopenharmony_ci } else { 670f66f451Sopenharmony_ci // cheat: FLAG_h is rightmost flag, so its value is 1 680f66f451Sopenharmony_ci if (!utimensat(AT_FDCWD, s, ts, FLAG(h)*AT_SYMLINK_NOFOLLOW)) continue; 690f66f451Sopenharmony_ci if (FLAG(c)) continue; 700f66f451Sopenharmony_ci if (access(s, F_OK) && (-1!=(fd = open(s, O_CREAT, 0666)))) { 710f66f451Sopenharmony_ci close(fd); 720f66f451Sopenharmony_ci if (toys.optflags) ss--; 730f66f451Sopenharmony_ci continue; 740f66f451Sopenharmony_ci } 750f66f451Sopenharmony_ci } 760f66f451Sopenharmony_ci perror_msg("'%s'", s); 770f66f451Sopenharmony_ci } 780f66f451Sopenharmony_ci} 79