summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2013-09-11 09:58:33 (GMT)
committer Denys Vlasenko <vda.linux@googlemail.com>2013-09-11 09:58:33 (GMT)
commitb5352078a7eb16c33404a8b079aaa9c2b994546c (patch)
treef84b3969a1fc2559d639d5d55a710ccc9482420a
parenta613aa1b4c26be1567a59e9216c83d21d4be122b (diff)
downloadbusybox-b5352078a7eb16c33404a8b079aaa9c2b994546c.tar.gz
busybox-b5352078a7eb16c33404a8b079aaa9c2b994546c.tar.bz2
touch: add conditional support for -h
Based on a patch by Andy <andy.padavan@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--coreutils/touch.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/coreutils/touch.c b/coreutils/touch.c
index 1216ca2..293a968 100644
--- a/coreutils/touch.c
+++ b/coreutils/touch.c
@@ -26,6 +26,14 @@
//config: touch is used to create or change the access and/or
//config: modification timestamp of specified files.
//config:
+//config:config FEATURE_TOUCH_NODEREF
+//config: bool "Add support for -h"
+//config: default y
+//config: depends on TOUCH
+//config: help
+//config: Enable touch to have the -h option.
+//config: This requires libc support for lutimes() function.
+//config:
//config:config FEATURE_TOUCH_SUSV3
//config: bool "Add support for SUSV3 features (-d -t -r)"
//config: default y
@@ -42,6 +50,9 @@
//usage:#define touch_full_usage "\n\n"
//usage: "Update the last-modified date on the given FILE[s]\n"
//usage: "\n -c Don't create files"
+//usage: IF_FEATURE_TOUCH_NODEREF(
+//usage: "\n -h Don't follow links"
+//usage: )
//usage: IF_FEATURE_TOUCH_SUSV3(
//usage: "\n -d DT Date/time to use"
//usage: "\n -t DT Date/time to use"
@@ -65,6 +76,7 @@
* parse STRING and use it instead of current time
* -f (ignored, BSD compat)
* -m change only the modification time
+ * -h, --no-dereference
* -r, --reference=FILE
* use this file's times instead of current time
* -t STAMP
@@ -79,6 +91,13 @@ int touch_main(int argc UNUSED_PARAM, char **argv)
int fd;
int status = EXIT_SUCCESS;
int opts;
+ enum {
+ OPT_c = (1 << 0),
+ OPT_r = (1 << 1) * ENABLE_FEATURE_TOUCH_SUSV3,
+ OPT_d = (1 << 2) * ENABLE_FEATURE_TOUCH_SUSV3,
+ OPT_t = (1 << 3) * ENABLE_FEATURE_TOUCH_SUSV3,
+ OPT_h = (1 << 4) * ENABLE_FEATURE_TOUCH_NODEREF,
+ };
#if ENABLE_FEATURE_TOUCH_SUSV3
# if ENABLE_LONG_OPTS
static const char touch_longopts[] ALIGN1 =
@@ -86,6 +105,7 @@ int touch_main(int argc UNUSED_PARAM, char **argv)
"no-create\0" No_argument "c"
"reference\0" Required_argument "r"
"date\0" Required_argument "d"
+ IF_FEATURE_TOUCH_NODEREF("no-dereference\0" No_argument "h")
;
# endif
char *reference_file = NULL;
@@ -105,13 +125,13 @@ int touch_main(int argc UNUSED_PARAM, char **argv)
* accepted data format differs a bit between -d and -t.
* We accept the same formats for both */
opts = getopt32(argv, "c" IF_FEATURE_TOUCH_SUSV3("r:d:t:")
+ IF_FEATURE_TOUCH_NODEREF("h")
/*ignored:*/ "fma"
IF_FEATURE_TOUCH_SUSV3(, &reference_file)
IF_FEATURE_TOUCH_SUSV3(, &date_str)
IF_FEATURE_TOUCH_SUSV3(, &date_str)
);
- opts &= 1; /* only -c bit is left */
argv += optind;
if (!*argv) {
bb_show_usage();
@@ -121,6 +141,10 @@ int touch_main(int argc UNUSED_PARAM, char **argv)
struct stat stbuf;
xstat(reference_file, &stbuf);
timebuf[1].tv_sec = timebuf[0].tv_sec = stbuf.st_mtime;
+ /* Can use .st_mtim.tv_nsec
+ * (or is it .st_mtimensec?? see date.c)
+ * to set microseconds too.
+ */
}
if (date_str) {
@@ -141,9 +165,16 @@ int touch_main(int argc UNUSED_PARAM, char **argv)
}
do {
- if (utimes(*argv, (reference_file || date_str) ? timebuf : NULL) != 0) {
- if (errno == ENOENT) { /* no such file */
- if (opts) { /* creation is disabled, so ignore */
+ int result;
+ result = (
+#if ENABLE_FEATURE_TOUCH_NODEREF
+ (opts & OPT_h) ? lutimes :
+#endif
+ utimes)(*argv, (reference_file || date_str) ? timebuf : NULL);
+ if (result != 0) {
+ if (errno == ENOENT) { /* no such file? */
+ if (opts & OPT_c) {
+ /* Creation is disabled, so ignore */
continue;
}
/* Try to create the file */