daemon: Fix utimens so it doesn't hang on named pipes (RHBZ#761460).
[libguestfs.git] / daemon / utimens.c
index 2d0e3bf..2df6fc7 100644 (file)
@@ -13,7 +13,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
 #include <config.h>
@@ -24,7 +24,7 @@
 #include <unistd.h>
 #include <sys/stat.h>
 
-#include "../src/guestfs_protocol.h"
+#include "guestfs_protocol.h"
 #include "daemon.h"
 #include "actions.h"
 
@@ -33,22 +33,8 @@ do_utimens (const char *path,
             int64_t atsecs, int64_t atnsecs,
             int64_t mtsecs, int64_t mtnsecs)
 {
-#ifndef HAVE_FUTIMENS
-  reply_with_error ("utimens: not supported in this appliance");
-  return -1;
-#else
-  int fd;
   int r;
 
-  CHROOT_IN;
-  fd = open (path, O_WRONLY | O_NOCTTY);
-  CHROOT_OUT;
-
-  if (fd == -1) {
-    reply_with_perror ("open: %s", path);
-    return -1;
-  }
-
   if (atnsecs == -1)
     atnsecs = UTIME_NOW;
   if (atnsecs == -2)
@@ -64,18 +50,14 @@ 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;
   }
 
   return 0;
-#endif /* HAVE_FUTIMENS */
 }