From owner-freebsd-audit@FreeBSD.ORG Sat May 8 05:55:50 2004 Return-Path: Delivered-To: freebsd-audit@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 1726416A4CE; Sat, 8 May 2004 05:55:50 -0700 (PDT) Received: from mail.musha.org (daemon.musha.org [210.189.104.8]) by mx1.FreeBSD.org (Postfix) with ESMTP id 5D50E43D48; Sat, 8 May 2004 05:55:49 -0700 (PDT) (envelope-from knu@iDaemons.org) Received: from archon.local.idaemons.org (archon.local.idaemons.org [192.168.1.32]) by mail.musha.org (Postfix) with ESMTP id 00FD6ACD7; Sat, 8 May 2004 21:55:48 +0900 (JST) Date: Sat, 08 May 2004 21:55:48 +0900 Message-ID: <86smebgjsb.knu@iDaemons.org> From: "Akinori MUSHA" To: current@FreeBSD.org, audit@FreeBSD.org Organization: Associated I. Daemons X-PGP-Public-Key: finger knu@FreeBSD.org X-PGP-Fingerprint: 081D 099C 1705 861D 4B70 B04A 920B EFC7 9FD9 E1EE MIME-Version: 1.0 (generated by EMIKO 1.14.1 - "Choanoflagellata") Content-Type: text/plain; charset=US-ASCII Subject: making test(1)'s -nt/-ot ignore nanosecond fractions X-BeenThere: freebsd-audit@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: FreeBSD Security Audit List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 08 May 2004 12:55:50 -0000 Hello, I faced an odd situation regarding file timestamps: knu@archon[2]% sh $ ls a b a b $ touch -r a b $ [ a -nt b ] && echo "D'oh!" D'oh! $ touch -r a a $ [ a -nt b ] || echo "Nah, how did it fix?" Nah, how did it fix? (Note that this is only rarely reproducible) I tracked it down and found out some facts: - File timestamps are recorded in nanoseconds on a UFS, and sometimes a file's timestamp actually has >1000 nanosecond (= >1 microsecond) value. - Stat(2) offers a file's mtime in nanoseconds through st_mtimespec.tv_nsec. - sh(1)'s builtin test command, which entity is test(1), compares times strictly in nanoseconds when seconds match. - On the other hand, there is no API to set a file's mtime in nanoseconds; utimes(2) takes time values in microseconds, and utime(3), which just calls utimes, takes time values in seconds. - Which means touch(1) or any other userland tool can only set a file's mtime in microseconds at most. - So, copying timestamps from a file "a" to a file "b" leaves a under-microsecond fraction only in "a", and after the copy "a" is "newer" than "b" by test(1). In order to fix this, we could consider adding a syscall or extend utimes(2) to take nanoseconds, but I'm afraid it would take a long time before it becomes available on -STABLE and the API spread over third-party applications. So, I'd suggest the following simple fix to make test(1) ignore such nanosecond fractions as a temporary measure: Index: test.c =================================================================== RCS file: /mirror/freebsd/ncvs/root/src/src/bin/test/test.c,v retrieving revision 1.52 diff -u -r1.52 test.c --- test.c 19 Aug 2002 09:19:31 -0000 1.52 +++ test.c 7 May 2004 17:06:54 -0000 @@ -527,7 +527,7 @@ if (b1.st_mtimespec.tv_sec < b2.st_mtimespec.tv_sec) return 0; - return (b1.st_mtimespec.tv_nsec > b2.st_mtimespec.tv_nsec); + return (b1.st_mtimespec.tv_nsec / 1000 > b2.st_mtimespec.tv_nsec / 1000); } static int Fortunately, bash and zsh behave the same way, as nanosecond times support is so heavily system dependent they give up to care about, which means the above change only makes test(1) compatible with other shells and would cause any harm. IMHO, no userland tool should care about nanosecond fractions when there is no API to set times in nanoseconds. Opinions? -- / /__ __ Akinori.org / MUSHA.org / ) ) ) ) / FreeBSD.org / Ruby-lang.org Akinori MUSHA aka / (_ / ( (__( @ iDaemons.org / and.or.jp "It seems to me as we make our own few circles 'round the sun We get it backwards and our seven years go by like one"