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>
This commit is contained in:
parent
a613aa1b4c
commit
b5352078a7
@ -26,6 +26,14 @@
|
|||||||
//config: touch is used to create or change the access and/or
|
//config: touch is used to create or change the access and/or
|
||||||
//config: modification timestamp of specified files.
|
//config: modification timestamp of specified files.
|
||||||
//config:
|
//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:config FEATURE_TOUCH_SUSV3
|
||||||
//config: bool "Add support for SUSV3 features (-d -t -r)"
|
//config: bool "Add support for SUSV3 features (-d -t -r)"
|
||||||
//config: default y
|
//config: default y
|
||||||
@ -42,6 +50,9 @@
|
|||||||
//usage:#define touch_full_usage "\n\n"
|
//usage:#define touch_full_usage "\n\n"
|
||||||
//usage: "Update the last-modified date on the given FILE[s]\n"
|
//usage: "Update the last-modified date on the given FILE[s]\n"
|
||||||
//usage: "\n -c Don't create files"
|
//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: IF_FEATURE_TOUCH_SUSV3(
|
||||||
//usage: "\n -d DT Date/time to use"
|
//usage: "\n -d DT Date/time to use"
|
||||||
//usage: "\n -t 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
|
* parse STRING and use it instead of current time
|
||||||
* -f (ignored, BSD compat)
|
* -f (ignored, BSD compat)
|
||||||
* -m change only the modification time
|
* -m change only the modification time
|
||||||
|
* -h, --no-dereference
|
||||||
* -r, --reference=FILE
|
* -r, --reference=FILE
|
||||||
* use this file's times instead of current time
|
* use this file's times instead of current time
|
||||||
* -t STAMP
|
* -t STAMP
|
||||||
@ -79,6 +91,13 @@ int touch_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
int fd;
|
int fd;
|
||||||
int status = EXIT_SUCCESS;
|
int status = EXIT_SUCCESS;
|
||||||
int opts;
|
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_FEATURE_TOUCH_SUSV3
|
||||||
# if ENABLE_LONG_OPTS
|
# if ENABLE_LONG_OPTS
|
||||||
static const char touch_longopts[] ALIGN1 =
|
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"
|
"no-create\0" No_argument "c"
|
||||||
"reference\0" Required_argument "r"
|
"reference\0" Required_argument "r"
|
||||||
"date\0" Required_argument "d"
|
"date\0" Required_argument "d"
|
||||||
|
IF_FEATURE_TOUCH_NODEREF("no-dereference\0" No_argument "h")
|
||||||
;
|
;
|
||||||
# endif
|
# endif
|
||||||
char *reference_file = NULL;
|
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.
|
* accepted data format differs a bit between -d and -t.
|
||||||
* We accept the same formats for both */
|
* We accept the same formats for both */
|
||||||
opts = getopt32(argv, "c" IF_FEATURE_TOUCH_SUSV3("r:d:t:")
|
opts = getopt32(argv, "c" IF_FEATURE_TOUCH_SUSV3("r:d:t:")
|
||||||
|
IF_FEATURE_TOUCH_NODEREF("h")
|
||||||
/*ignored:*/ "fma"
|
/*ignored:*/ "fma"
|
||||||
IF_FEATURE_TOUCH_SUSV3(, &reference_file)
|
IF_FEATURE_TOUCH_SUSV3(, &reference_file)
|
||||||
IF_FEATURE_TOUCH_SUSV3(, &date_str)
|
IF_FEATURE_TOUCH_SUSV3(, &date_str)
|
||||||
IF_FEATURE_TOUCH_SUSV3(, &date_str)
|
IF_FEATURE_TOUCH_SUSV3(, &date_str)
|
||||||
);
|
);
|
||||||
|
|
||||||
opts &= 1; /* only -c bit is left */
|
|
||||||
argv += optind;
|
argv += optind;
|
||||||
if (!*argv) {
|
if (!*argv) {
|
||||||
bb_show_usage();
|
bb_show_usage();
|
||||||
@ -121,6 +141,10 @@ int touch_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
struct stat stbuf;
|
struct stat stbuf;
|
||||||
xstat(reference_file, &stbuf);
|
xstat(reference_file, &stbuf);
|
||||||
timebuf[1].tv_sec = timebuf[0].tv_sec = stbuf.st_mtime;
|
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) {
|
if (date_str) {
|
||||||
@ -141,9 +165,16 @@ int touch_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (utimes(*argv, (reference_file || date_str) ? timebuf : NULL) != 0) {
|
int result;
|
||||||
if (errno == ENOENT) { /* no such file */
|
result = (
|
||||||
if (opts) { /* creation is disabled, so ignore */
|
#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;
|
continue;
|
||||||
}
|
}
|
||||||
/* Try to create the file */
|
/* Try to create the file */
|
||||||
|
Loading…
Reference in New Issue
Block a user