Subject: Re: bug#10305: coreutils-8.14, "rm -r" fails with EBADF

From: Eric Blake <[email-masked]>
Date: Wed, 21 Dec 2011 10:32:17 -0700

On 12/21/2011 10:12 AM, Joachim Schmitz wrote:
>>> Write a small test program that opens say four directories, to get one
>>> DIR* pointer for each.  Then print a table of the DIR member values.
>>> Maybe you'll see a pattern, i.e., how to derive an FD number from
>>> those dd1,2,3 fields.
> 
> Yes, indeed, thanks for that idea (should have been mine):
> It got to be dd1, only it is not an fd but something called fnum and these a) start counting with 1 rather than 0 and b) have 1 and 2 being root and CPD, followed by 3,4 and 5 being stdin, stdout, stderr... it seems fnum -3 == fd 

Yay - we can implement dirfd() in terms of dd1-3.

Please try this on coreutils:

./configure gl_cv_sys_dir_fd_member_name='dd1-3'

and if that works, then the solution is this patch to gnulib (along with
enhancing our testsuite to further test our dirfd emulation):

diff --git i/ChangeLog w/ChangeLog
index 749b538..7a6bf4b 100644
--- i/ChangeLog
+++ w/ChangeLog
@@ -1,3 +1,9 @@
+2011-12-21  Eric Blake  <[email-masked]>
+
+	dirfd: port to HP NonStop
+	* m4/dirfd.m4 (gl_PREREQ_DIRFD): Also probe for NonStop variant.
+	Reported by Joachim Schmitz.
+
 2011-12-14  Alex Nelson  <[email-masked]>  (tiny change)

 	strftime-tests: also test nanoseconds
diff --git i/m4/dirfd.m4 w/m4/dirfd.m4
index ea75e4e..031c337 100644
--- i/m4/dirfd.m4
+++ w/m4/dirfd.m4
@@ -1,4 +1,4 @@
-# serial 22   -*- Autoconf -*-
+# serial 23   -*- Autoconf -*-

 dnl Find out how to get the file descriptor associated with an open DIR*.

@@ -50,8 +50,10 @@ AC_DEFUN([gl_PREREQ_DIRFD],
   AC_CACHE_CHECK([how to get the file descriptor associated with an
open DIR*],
                  [gl_cv_sys_dir_fd_member_name],
     [
+      # Most systems expose the fd directly, via d_fd or dd_fd
+      # HP NonStop instead has a member dd1, with a value 3 larger than
the fd
       dirfd_save_CFLAGS=$CFLAGS
-      for ac_expr in d_fd dd_fd; do
+      for ac_expr in d_fd dd_fd dd1-3; do

         CFLAGS="$CFLAGS -DDIR_FD_MEMBER_NAME=$ac_expr"
         AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[

-- 
Eric Blake   [email-masked]    +1-919-301-3266
Libvirt virtualization library http://libvirt.org