[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
"touch -" test cases, and fixes for "touch -c - >&-"
From: |
Paul Eggert |
Subject: |
"touch -" test cases, and fixes for "touch -c - >&-" |
Date: |
Mon, 26 Sep 2005 16:11:00 -0700 |
User-agent: |
Gnus/5.1007 (Gnus v5.10.7) Emacs/21.4 (gnu/linux) |
I some test cases for "touch". They caused me to discover one minor
bug in the old "touch" code; "close(fd)" could clobber errno (this was
more by code inspection than anything else). Also, they uncovered
some portability mishaps (causing suboptimal code or incorrect errno
values in diagnostics). Also, they uncovered the fact that "touch -c
- >&-" should not report an error number, by analogy with "touch -c
no-such-file".
Here's the patch I installed:
2005-09-25 Paul Eggert <address@hidden>
* lib/utimens.c: Include unistd.h, for dup2.
(futimens): Fix typo: HAVE_FUTIMESAT was misspelled in an #if.
(futimens) [! HAVE_FUTIMESAT]: If !file, set errno before returning -1.
* src/touch.c (touch): Handle "touch -c - >&-" by checking for EBADF
and ENOSYS.
Do not pass "-" to futimens; pass NULL instead.
If close (STDIN_FILENO) fails, report the error separately instead
of letting the 'close' pollute errno.
* tests/touch/empty-file: Test "touch -" too.
* tests/touch/no-create-missing: Likewise.
* tests/touch/read-only: Likewise.
Index: lib/utimens.c
===================================================================
RCS file: /fetish/cu/lib/utimens.c,v
retrieving revision 1.9
diff -p -u -r1.9 utimens.c
--- lib/utimens.c 25 Sep 2005 06:08:45 -0000 1.9
+++ lib/utimens.c 26 Sep 2005 22:57:54 -0000
@@ -26,6 +26,7 @@
#include <errno.h>
#include <fcntl.h>
+#include <unistd.h>
#if HAVE_UTIME_H
# include <utime.h>
@@ -113,11 +114,24 @@ futimens (int fd ATTRIBUTE_UNUSED,
# endif
#endif
-#if ! HAVE_FUTIMES_AT
+#if ! HAVE_FUTIMESAT
if (!file)
{
+# if ! (HAVE_WORKING_UTIMES && HAVE_FUTIMES)
errno = ENOSYS;
+# endif
+
+ /* Prefer EBADF to ENOSYS if both error numbers apply. */
+ if (errno == ENOSYS)
+ {
+ int fd2 = dup (fd);
+ int dup_errno = errno;
+ if (0 <= fd2)
+ close (fd2);
+ errno = (fd2 < 0 && dup_errno == EBADF ? EBADF : ENOSYS);
+ }
+
return -1;
}
Index: src/touch.c
===================================================================
RCS file: /fetish/cu/src/touch.c,v
retrieving revision 1.135
diff -p -u -r1.135 touch.c
--- src/touch.c 25 Sep 2005 06:12:21 -0000 1.135
+++ src/touch.c 26 Sep 2005 22:57:54 -0000
@@ -154,7 +154,7 @@ touch (const char *file)
error (0, open_errno, _("creating %s"), quote (file));
else
{
- if (no_create && errno == ENOENT)
+ if (no_create && (errno == ENOENT || errno == EBADF))
return true;
error (0, errno, _("failed to get attributes of %s"),
quote (file));
@@ -182,9 +182,23 @@ touch (const char *file)
t = timespec;
}
- ok = (futimens (fd, file, t) == 0);
+ ok = (futimens (fd, (fd == STDOUT_FILENO ? NULL : file), t) == 0);
+
if (fd == STDIN_FILENO)
- ok &= (close (fd) == 0);
+ {
+ if (close (STDIN_FILENO) != 0)
+ {
+ error (0, errno, _("closing %s"), quote (file));
+ return false;
+ }
+ }
+ else if (fd == STDOUT_FILENO)
+ {
+ /* Do not diagnose "touch -c - >&-". */
+ if (!ok && errno == EBADF && no_create
+ && change_times == (CH_ATIME | CH_MTIME))
+ return true;
+ }
if (!ok)
{
Index: tests/touch/empty-file
===================================================================
RCS file: /fetish/cu/tests/touch/empty-file,v
retrieving revision 1.7
diff -p -u -r1.7 empty-file
--- tests/touch/empty-file 2 Feb 2000 14:04:47 -0000 1.7
+++ tests/touch/empty-file 26 Sep 2005 22:57:54 -0000
@@ -22,11 +22,13 @@ fail=0
framework_failure=0
for d in $TOUCH_DIR_LIST; do
- rm -rf $d/a $d/b
+ rm -rf $d/a $d/b $d/c
> $d/a || framework_failure=1
test -f $d/a || framework_failure=1
> $d/b || framework_failure=1
test -f $d/b || framework_failure=1
+ > $d/c || framework_failure=1
+ test -f $d/c || framework_failure=1
done
if test $framework_failure = 1; then
@@ -49,7 +51,12 @@ for d in $TOUCH_DIR_LIST; do
set x `ls -t $d/a $d/b`
test "$*" = "x $d/b $d/a" || fail=1
- rm -rf $d/a $d/b
+ if touch - 1< $d/c 2> /dev/null; then
+ set x `ls -t $d/a $d/c`
+ test "$*" = "x $d/c $d/a" || fail=1
+ fi
+
+ rm -rf $d/a $d/b $d/c
done
if test $fail != 0; then
Index: tests/touch/no-create-missing
===================================================================
RCS file: /fetish/cu/tests/touch/no-create-missing,v
retrieving revision 1.4
diff -p -u -r1.4 no-create-missing
--- tests/touch/no-create-missing 23 Jun 2004 15:07:05 -0000 1.4
+++ tests/touch/no-create-missing 26 Sep 2005 22:57:54 -0000
@@ -25,5 +25,8 @@ fail=0
touch -c no-file > /dev/null 2>&1 || fail=1
touch -cm no-file > /dev/null 2>&1 || fail=1
touch -ca no-file > /dev/null 2>&1 || fail=1
+touch -c - >&- 2> /dev/null || fail=1
+touch -cm - >&- 2> /dev/null || fail=1
+touch -ca - >&- 2> /dev/null || fail=1
(exit $fail); exit $fail
Index: tests/touch/read-only
===================================================================
RCS file: /fetish/cu/tests/touch/read-only,v
retrieving revision 1.1
diff -p -u -r1.1 read-only
--- tests/touch/read-only 26 Sep 2005 07:31:57 -0000 1.1
+++ tests/touch/read-only 26 Sep 2005 22:57:54 -0000
@@ -29,4 +29,6 @@ fail=0
touch read-only || fail=1
+touch - 1< read-only 2> /dev/null && { test ! -f - || fail=1; }
+
(exit $fail); exit $fail
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- "touch -" test cases, and fixes for "touch -c - >&-",
Paul Eggert <=