[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] cp -p doesn't work with HAVE_FUTIMENS and without /proc
From: |
Kir Kolyshkin |
Subject: |
[PATCH] cp -p doesn't work with HAVE_FUTIMENS and without /proc |
Date: |
Sat, 15 Apr 2006 02:34:15 +0400 |
User-agent: |
Mozilla Thunderbird 1.0.7 (X11/20060217) |
I have come across a bug in cp utility from coreutils-5.93 on a Fedora
Core 5 system (glibc-2.4), while working on OpenVZ user-level tools.
Original, unpatched versions of coreutils-5.93 and 5.94 are also affected.
PREREQUISITES
-------------
Bug occurs when coreutils is compiled on a system which provides
futimens() function, and only if /proc fs is not mounted.
SYMPTOMS
--------
Copying a file with -p (or --preserve=timestamps) option gives the
following error message; cp when exits with 1:
cp: preserving times for `dst-file-name': Function not implemented
ANALYSYS
--------
Strace shows that cp tries to call utimes on /proc/self/fd/4, it fails
and cp bails out:
open("dst-file-name", O_WRONLY|O_CREAT|O_LARGEFILE, 0100644) = 4
fstat64(4, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
fstat64(3, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
read(3, "", 4096) = 0
utimes("/proc/self/fd/4", {1145050934, 0}) = -1 ENOENT (No such file
or directory)
fcntl(4, F_GETFD) = 0
write(2, "cp: ", 4cp: ) = 4
write(2, "preserving times for `dst-file-n"..., 36preserving times for
`dst-file-name') = 36
write(2, ": Function not implemented", 26: Function not implemented) = 26
write(2, "\n", 1
) = 1
Ltrace shows that cp calls futimens, which fails, and cp bails out:
open64("dst-file-name", 513,
00) = 4
__fxstat64(3, 4,
0xffffc184) = 0
__fxstat64(3, 3,
0xffffc184) = 0
getpagesize()
= 4096
read(3, "",
4096) = 0
futimesat(4, 0, -24452, 0x8058a20,
0xf7dbfb94) = -1
__errno_location()
= 0xf7d6b690
__errno_location()
= 0xf7d6b690
__ctype_get_mb_cur_max(0xf7db25b0, 0xc0b8fae, 0, 0x8048ab0,
494452) = 1
dcgettext(0, 0x8055c2a, 5, 0x80588dc,
0xf7d6b690) = 0x8055c2a
dcgettext(0, 0x8055f38, 5, 0x80588dc,
0x8055c2a) = 0x8055f38
strlen("'")
= 1
dcgettext(0, 0x80558c1, 5, 0,
0) = 0x80558c1
__errno_location()
= 0xf7d6b690
error(0, 38, 0x80558c1, 0x8058b00, 0cp: preserving times for
`dst-file-name': Function not implemented
) = 0
CODE
----
The following piece of code from coreutils/lib/utimens.c sheds some light:
# if HAVE_FUTIMESAT
return fd < 0 ? futimesat (AT_FDCWD, file, t) : futimesat (fd, NULL, t);
# elif HAVE_FUTIMES
if (0 <= fd)
{
if (futimes (fd, t) == 0)
return 0;
/* Don't worry about trying to speed things up by returning right
away here. glibc futimes can incorrectly fail with errno ==
ENOENT if /proc isn't mounted. Also, Mandrake 10.0 in high
security mode doesn't allow ordinary users to read /proc/self, so
glibc futimes incorrectly fails with errno == EACCES. If futimes
fails with errno == EIO, EPERM, or EROFS, it's probably safe to
fail right away, but these cases are rare enough that they're not
worth optimizing, and who knows what other messed-up systems are
out there? So play it safe and fall back on the code below. */
}
# endif
#endif
Apparently, there is a fallback path for futimes, but there is no such
path for futimesat.
FIX
---
Attached is the patch that enables fallback path for futimesat().
--- coreutils-5.93/lib/utimens.c 2005-11-02 15:16:12.000000000 +0300
+++ coreutils-5.93-cp-p-fix/lib/utimens.c 2006-04-14 23:33:49.000000000
+0400
@@ -92,7 +92,14 @@
t = NULL;
# if HAVE_FUTIMESAT
- return fd < 0 ? futimesat (AT_FDCWD, file, t) : futimesat (fd, NULL, t);
+ if (fd < 0)
+ return futimesat (AT_FDCWD, file, t);
+ else if (futimesat (fd, NULL, t) == 0)
+ return 0;
+ /* If futimesat failed, the reason might be that /proc is not mounted
+ or it is otherwise inaccessible. In that case we use the fallback code
+ below.
+ */
# elif HAVE_FUTIMES
if (0 <= fd)
{
@@ -112,8 +119,6 @@
# endif
#endif
-#if ! HAVE_FUTIMESAT
-
if (!file)
{
# if ! (HAVE_WORKING_UTIMES && HAVE_FUTIMES)
@@ -151,8 +156,6 @@
return utime (file, ut);
}
# endif
-
-#endif
}
/* Set the access and modification time stamps of FILE to be
- [PATCH] cp -p doesn't work with HAVE_FUTIMENS and without /proc,
Kir Kolyshkin <=