Good morning,
The following piece of shell code does not work on sunos.
mkfifo /tmp/pipe
cat < /tmp/pipe &
exec 6>/tmp/pipe
test -p /dev/fd/6 && echo pipe
The reason is on sunos /dev/fd/6 is a special character file, not a pipe
(unlike bsd), not a symlink (unlike linux, cygwin).
sh_stat ends up calling stat("/dev/fd/6", finfo) and obtains stat of /dev/fd/6
file rather than stat of the file pointed to by fd 6.
The patch in the attachment makes sh_stat always use fstat regardless of
HAVE_DEV_FD.
I've tested this patch on linux, sunos and aix.
regards, Dmitry
diff --git a/lib/sh/eaccess.c b/lib/sh/eaccess.c
index 8132a9a..1575dd2 100644
--- a/lib/sh/eaccess.c
+++ b/lib/sh/eaccess.c
@@ -82,8 +82,6 @@ sh_stat (path, finfo)
const char *path;
struct stat *finfo;
{
- static char *pbuf = 0;
-
if (*path == '\0')
{
errno = ENOENT;
@@ -91,7 +89,6 @@ sh_stat (path, finfo)
}
if (path[0] == '/' && path[1] == 'd' && strncmp (path, "/dev/fd/", 8) == 0)
{
-#if !defined (HAVE_DEV_FD)
intmax_t fd;
int r;
@@ -103,16 +100,6 @@ sh_stat (path, finfo)
}
errno = ENOENT;
return (-1);
-#else
- /* If HAVE_DEV_FD is defined, DEV_FD_PREFIX is defined also, and has a
- trailing slash. Make sure /dev/fd/xx really uses DEV_FD_PREFIX/xx.
- On most systems, with the notable exception of linux, this is
- effectively a no-op. */
- pbuf = xrealloc (pbuf, sizeof (DEV_FD_PREFIX) + strlen (path + 8));
- strcpy (pbuf, DEV_FD_PREFIX);
- strcat (pbuf, path + 8);
- return (stat (pbuf, finfo));
-#endif /* !HAVE_DEV_FD */
}
#if !defined (HAVE_DEV_STDIN)
else if (STREQN (path, "/dev/std", 8))
diff --git a/tests/test.tests b/tests/test.tests
index 47eef35..5a790d8 100644
--- a/tests/test.tests
+++ b/tests/test.tests
@@ -436,3 +436,17 @@ t -t /dev/tty4444444...
# fixed in bash-4.0-beta
t -t ' '
+
+exec 6>&-
+echo "t -p /dev/fd/6"
+t -p /dev/fd/6
+
+rm /tmp/pipe 2>/dev/null
+mkfifo /tmp/pipe
+cat < /tmp/pipe &
+exec 6>&-
+exec 6>/tmp/pipe
+echo "t -p /dev/fd/6"
+t -p /dev/fd/6
+kill $! 2>/dev/null
+rm /tmp/pipe 2>/dev/null