bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug-gnulib] Re: [patch #3741] Added support for Interix within mountlis


From: Jim Meyering
Subject: [bug-gnulib] Re: [patch #3741] Added support for Interix within mountlist.c
Date: Tue, 15 Feb 2005 16:45:02 +0100

James Youngman <address@hidden> wrote:
> I've received a patch for findutils from Darren R. Starr.  The patch
> adds support for Interix to the mountlist.c file.  This file is
> distributed with findutils, but is not present in the findutils CVS
> code (insteead, findutils uses gnulib's CVS code directly).  Hence I
> have forwarded the patch to the "upstream" gnulib code base.  However,
> this is the only patch on the gnulib patch tracker.  In case you guys
> tend not to use the Savannah patch tracker, I thought I'd send an
> email to point the patch out to you.  It's available at
>
> http://savannah.gnu.org/patch/?func=detailitem&item_id=3742

Thanks for the heads-up and for pointing out the problem
of the undetected opendir failure.

There's another minor problem:
If the opendir and all readdir_r calls succeed, yet statvfs always fails,
then the function would return NULL, with a readdir_r-clobbered errno.
Similarly, closedir might clobber errno.

Here's an untested patch that addresses those problems and uses variable
names more in line with the style of the rest of the code in that file.
Also, I rearranged the loop so that there is only one readdir_r call
and moved variable declarations to inner scopes, nearer to where they're
actually used.

Darren, would you please make sure it works?
Also, is there already a patch to make ls-mntd-fs.m4
detect and define MOUNTED_INTERIX?

Index: lib/mountlist.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/mountlist.c,v
retrieving revision 1.48
diff -u -p -r1.48 mountlist.c
--- lib/mountlist.c     1 Feb 2005 23:56:47 -0000       1.48
+++ lib/mountlist.c     15 Feb 2005 15:41:03 -0000
@@ -95,6 +95,11 @@ char *strstr ();
 # include <dirent.h>
 #endif
 
+#ifdef MOUNTED_INTERIX         /* Windows with Interix / Microsoft Services 
For UNIX */
+# include <dirent.h>
+# include <sys/statvfs.h>
+#endif
+
 #ifdef MOUNTED_FREAD           /* SVR2.  */
 # include <mnttab.h>
 #endif
@@ -421,6 +426,95 @@ read_file_system_list (bool need_fs_type
   }
 #endif /* MOUNTED_GETMNT. */
 
+#if defined MOUNTED_INTERIX
+  /* Windows with Interix / Microsoft Services For UNIX */
+  {
+    /* Unlike Cygwin which attempts to implement as many of the UNIX
+       API's as possible Interix implements a great deal and then depends
+       on developers to port the rest. On Interix, the POSIX implementation
+       prefers to deny that UNIX style file systems exist and therefore
+       does not implement the mount tables for the system.
+
+       This implementation simply scans the mounted file system directory
+       and then reads the statvfs data for each entry to construct the
+       mount list.
+
+       The implementation also chooses to use the reentrant implementation
+       of readdir_r in order to favor a threading friendly system. */
+
+    int statvfs_errno = 0;
+    int fail;
+
+    DIR *dirp = opendir ("/dev/fs");
+    if (dirp == NULL)
+      {
+       fail = 1;
+      }
+    else
+      {
+       char file_name[9 + NAME_MAX]; /* 8 for /dev/fs/ + 1 for NUL */
+       int saved_errno;
+
+       while (1)
+         {
+           struct statvfs stat_buf;
+           struct dirent entry;
+           struct dirent *result;
+
+           fail = readdir_r (dirp, &entry, &result);
+
+           if (fail || result == NULL)
+             break;
+
+           strcpy (file_name, "/dev/fs/");
+           strcat (file_name, entry.d_name);
+
+           fail = statvfs (file_name, &stat_buf);
+           if (fail == 0)
+             {
+               char const *Magic_mount_from_name
+                 = "/Device/LanmanRedirector/;",
+               me = xmalloc (sizeof *me);
+               me->me_devname = xstrdup (stat_buf.f_mntfromname);
+               me->me_mountdir = xstrdup (stat_buf.f_mntonname);
+               me->me_type = xstrdup (stat_buf.f_fstypename);
+               me->me_type_malloced = 1;
+               me->me_dummy = 0;
+               me->me_dev = stat_buf.f_fsid;
+               me->me_remote
+                 = strncmp (stat_buf.f_mntfromname, Magic_mount_from_name,
+                            strlen (Magic_mount_from_name)) == 0;
+
+               /* Add to the linked list. */
+               *mtail = me;
+               mtail = &me->me_next;
+             }
+           else
+             {
+               statvfs_errno = errno;
+             }
+         }
+
+       saved_errno = errno;
+       closedir (dirp);
+       errno = saved_errno;
+      }
+
+    if (!fail && statvfs_errno)
+      {
+       /* In the unlikely event that opendir and each readdir
+          succeed, but all statvfs calls fail, ensure that we
+          fail with a valid errno value.  */
+       fail = 1;
+       errno = statvfs_errno;
+      }
+
+    if (fail)
+      goto free_then_fail;
+
+  }
+#endif
+
 #if defined MOUNTED_FS_STAT_DEV /* BeOS */
   {
     /* The next_dev() and fs_stat_dev() system calls give the list of




reply via email to

[Prev in Thread] Current Thread [Next in Thread]