From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LwIXt-00023T-3m for qemu-devel@nongnu.org; Tue, 21 Apr 2009 12:10:05 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LwIXs-00022E-5G for qemu-devel@nongnu.org; Tue, 21 Apr 2009 12:10:04 -0400 Received: from [199.232.76.173] (port=52811 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LwIXr-000226-Mi for qemu-devel@nongnu.org; Tue, 21 Apr 2009 12:10:03 -0400 Received: from dd21438.kasserver.com ([85.13.141.110]:42846) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1LwIXr-0003k0-47 for qemu-devel@nongnu.org; Tue, 21 Apr 2009 12:10:03 -0400 Message-ID: <49EDEFD4.9000707@opensuse.org> Date: Tue, 21 Apr 2009 18:09:56 +0200 From: Martin Mohring MIME-Version: 1.0 Subject: Re: [Qemu-devel] [PATCH] Fix utimensat (aka unbreak cp -a) References: <878wlufm8s.fsf@lechat.rtp-net.org> <20090421123455.GA15170@kos.to> In-Reply-To: <20090421123455.GA15170@kos.to> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Riku Voipio Cc: laurent.desnogues@gmail.com, qemu-devel@nongnu.org, Arnaud Patard i found another related case it seems: when i call in a chroot under arm with qemu user mode: $ touch /var/log/wtmp the resulting file has a date/time of 1.1.1970, although the clock is correct in the system. calling $ touch /var/log/wtmp /var/run/utmp /var/log/btmp /bin/touch: setting times of `/var/run/utmp': Invalid argument /bin/touch: setting times of `/var/log/btmp': Invalid argument results in the invalid argutment error. I ll currently check which syscalls are involved here. the time of 1.1.1970 looks to me like a wrongly passed argument (of ==0). Riku Voipio wrote: > On Tue, Apr 21, 2009 at 10:24:03AM +0200, Arnaud Patard wrote: > >> Don't use the glibc function for utimensat because glibc returns -EINVAL >> if the path is null which is a different behaviour with the syscall. >> path can be null because internally the glibc is using utimensat with >> path null (for instance, see __futimes in >> sysdeps/unix/sysv/linux/futimes.c in glibc tree). >> > > Soo.. glibc uses utimensat to implement futimens, but doesn't allow > applications to use utimensat in the same way. What a mess. > > But if we are to go towards using libc calls, your patch is a step > backwards. In case pathname is null, we can use futimens. > > > commit 0f34ff059fb9ad6e8c8fa5161d9d17265286bb62 > Author: Riku Voipio > Date: Tue Apr 21 15:01:51 2009 +0300 > > linux-user: fix utimensat when used as futimens > > The glibc function for utimensat glibc returns -EINVAL when the path is null > which is a different behaviour with the syscall. > > path can be null because internally the glibc is using utimensat with > path null when implmenting futimens. If path is null, call futimes > instead. > > diff --git a/configure b/configure > index 08df436..fc980a4 100755 > --- a/configure > +++ b/configure > @@ -1208,6 +1208,25 @@ EOF > fi > fi > > +# check if utimensat and futimens are supported > +utimens=no > +cat > $TMPC << EOF > +#define _ATFILE_SOURCE > +#define _GNU_SOURCE > +#include > +#include > + > +int main(void) > +{ > + utimensat(AT_FDCWD, "foo", NULL, 0); > + futimens(0, NULL); > + return 0; > +} > +EOF > +if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then > + utimens=yes > +fi > + > # Check if tools are available to build documentation. > if [ -x "`which texi2html 2>/dev/null`" ] && \ > [ -x "`which pod2man 2>/dev/null`" ]; then > @@ -1604,6 +1623,9 @@ fi > if test "$atfile" = "yes" ; then > echo "#define CONFIG_ATFILE 1" >> $config_h > fi > +if test "$utimens" = "yes" ; then > + echo "#define CONFIG_UTIMENSAT 1" >> $config_h > +fi > if test "$inotify" = "yes" ; then > echo "#define CONFIG_INOTIFY 1" >> $config_h > fi > diff --git a/linux-user/syscall.c b/linux-user/syscall.c > index 408ccc6..4dad5c1 100644 > --- a/linux-user/syscall.c > +++ b/linux-user/syscall.c > @@ -406,13 +406,6 @@ static int sys_unlinkat(int dirfd, const char *pathname, int flags) > return (unlinkat(dirfd, pathname, flags)); > } > #endif > -#ifdef TARGET_NR_utimensat > -static int sys_utimensat(int dirfd, const char *pathname, > - const struct timespec times[2], int flags) > -{ > - return (utimensat(dirfd, pathname, times, flags)); > -} > -#endif > #else /* !CONFIG_ATFILE */ > > /* > @@ -476,12 +469,24 @@ _syscall3(int,sys_symlinkat,const char *,oldpath, > #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat) > _syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags) > #endif > + > +#endif /* CONFIG_ATFILE */ > + > +#ifdef CONFIG_UTIMENSAT > +static int sys_utimensat(int dirfd, const char *pathname, > + const struct timespec times[2], int flags) > +{ > + if (pathname == NULL) > + return futimens(dirfd, times); > + else > + return utimensat(dirfd, pathname, times, flags); > +} > +#else > #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat) > _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname, > const struct timespec *,tsp,int,flags) > #endif > - > -#endif /* CONFIG_ATFILE */ > +#endif /* CONFIG_UTIMENSAT */ > > #ifdef CONFIG_INOTIFY > #include > > >