From 87e972e69487564f44b20ea5dcfc3eadf5b34c74 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 8 Dec 2011 11:39:58 +0000 Subject: [PATCH] daemon: Fix utimens so it doesn't hang on named pipes (RHBZ#761460). This also adds comprehensive tests for utimens on regular files, directories (RHBZ#761451), named pipes (RHBZ#761460), symbolic links, block and char devices. Note that there is a small change in the (previously undefined) semantics of this call: It now sets the time on a symbolic link itself, not on what the symbolic link points to. (cherry picked from commit 19e2f5aa4fd4ed70b505661d918b5575616ad441) --- daemon/utimens.c | 23 +++++------------------ generator/generator_actions.ml | 27 ++++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/daemon/utimens.c b/daemon/utimens.c index a9857db..2df6fc7 100644 --- a/daemon/utimens.c +++ b/daemon/utimens.c @@ -33,18 +33,8 @@ do_utimens (const char *path, int64_t atsecs, int64_t atnsecs, int64_t mtsecs, int64_t mtnsecs) { - int fd; int r; - CHROOT_IN; - fd = open (path, O_RDONLY | O_NOCTTY); - CHROOT_OUT; - - if (fd == -1) { - reply_with_perror ("open: %s", path); - return -1; - } - if (atnsecs == -1) atnsecs = UTIME_NOW; if (atnsecs == -2) @@ -60,15 +50,12 @@ do_utimens (const char *path, times[1].tv_sec = mtsecs; times[1].tv_nsec = mtnsecs; - r = futimens (fd, times); - if (r == -1) { - reply_with_perror ("futimens: %s", path); - close (fd); - return -1; - } + CHROOT_IN; + r = utimensat (-1, path, times, AT_SYMLINK_NOFOLLOW); + CHROOT_OUT; - if (close (fd) == -1) { - reply_with_perror ("close: %s", path); + if (r == -1) { + reply_with_perror ("utimensat: %s", path); return -1; } diff --git a/generator/generator_actions.ml b/generator/generator_actions.ml index d3fa3e0..ece471f 100644 --- a/generator/generator_actions.ml +++ b/generator/generator_actions.ml @@ -4812,10 +4812,31 @@ for the file until you write to it). To create a non-sparse file of zeroes, use C instead."); ("utimens", (RErr, [Pathname "path"; Int64 "atsecs"; Int64 "atnsecs"; Int64 "mtsecs"; Int64 "mtnsecs"], []), 201, [], + (* Test directories, named pipes etc (RHBZ#761451, RHBZ#761460) *) [InitScratchFS, Always, TestOutputStruct ( - [["touch"; "/utimens"]; - ["utimens"; "/utimens"; "12345"; "67890"; "9876"; "5432"]; - ["stat"; "/utimens"]], [CompareWithInt ("mtime", 9876)])], + [["touch"; "/utimens-file"]; + ["utimens"; "/utimens-file"; "12345"; "67890"; "9876"; "5432"]; + ["stat"; "/utimens-file"]], [CompareWithInt ("mtime", 9876)]); + InitScratchFS, Always, TestOutputStruct ( + [["mkdir"; "/utimens-dir"]; + ["utimens"; "/utimens-dir"; "12345"; "67890"; "9876"; "5432"]; + ["stat"; "/utimens-dir"]], [CompareWithInt ("mtime", 9876)]); + InitScratchFS, Always, TestOutputStruct ( + [["mkfifo"; "0o644"; "/utimens-fifo"]; + ["utimens"; "/utimens-fifo"; "12345"; "67890"; "9876"; "5432"]; + ["stat"; "/utimens-fifo"]], [CompareWithInt ("mtime", 9876)]); + InitScratchFS, Always, TestOutputStruct ( + [["ln_sf"; "/utimens-file"; "/utimens-link"]; + ["utimens"; "/utimens-link"; "12345"; "67890"; "9876"; "5432"]; + ["stat"; "/utimens-link"]], [CompareWithInt ("mtime", 9876)]); + InitScratchFS, Always, TestOutputStruct ( + [["mknod_b"; "0o644"; "8"; "0"; "/utimens-block"]; + ["utimens"; "/utimens-block"; "12345"; "67890"; "9876"; "5432"]; + ["stat"; "/utimens-block"]], [CompareWithInt ("mtime", 9876)]); + InitScratchFS, Always, TestOutputStruct ( + [["mknod_c"; "0o644"; "1"; "3"; "/utimens-char"]; + ["utimens"; "/utimens-char"; "12345"; "67890"; "9876"; "5432"]; + ["stat"; "/utimens-char"]], [CompareWithInt ("mtime", 9876)])], "set timestamp of a file with nanosecond precision", "\ This command sets the timestamps of a file with nanosecond -- 1.8.3.1