Hello, Attached 2 patches:
mountlist tests: add mountlist-tests module mountlist: add support for windows DOS-style drives The second patch enables the completion of coreutils' "./configure" under windows with mingw compiler (not the entire build, just "configure") instead of failing with: configure: error: could not determine how to read list of mounted file systems This is a first step towards getting stock coreutils to compile on mingw (and perhaps also findutils which uses mountlist). Comments welcomed, - assaf
>From d1c3e9a61e7c1e9a6bab2b5198d24391e309adc0 Mon Sep 17 00:00:00 2001 From: Assaf Gordon <assafgor...@gmail.com> Date: Wed, 10 Oct 2018 14:08:42 -0600 Subject: [PATCH 1/2] mountlist tests: add mountlist-tests module Call read_file_system_list, print the list, and free the entries. Typical output example: $ ./gnulib-tool -create-testdir -dir mnt-list mountlist-tests $ cd mnt-list $ ./configure && make $ ./gltests/test-mountlist devname: proc mountdir: /proc mntdoor: / type: proc dev: 4 dummy: 1 remote: 0 type_alc: 1 devname: /dev/sda1 mountdir: / mntdoor: / type: ext4 dev: 2049 dummy: 0 remote: 0 type_alc: 1 [...] * modules/mountlist-tests: New module file. * tests/test-mountlist.c: New test file. --- ChangeLog | 29 +++++++++++++++++++++++++++++ modules/mountlist-tests | 11 +++++++++++ tests/test-mountlist.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 modules/mountlist-tests create mode 100644 tests/test-mountlist.c diff --git a/ChangeLog b/ChangeLog index 6161c05b6..aa490686f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2018-10-10 Assaf Gordon <assafgor...@gmail.com> + + mountlist tests: add mountlist-tests module + Call read_file_system_list, print the list, and free the entries. + Typical output example: + $ ./gnulib-tool -create-testdir -dir mnt-list mountlist-tests + $ cd mnt-list + $ ./configure && make + $ ./gltests/test-mountlist + devname: proc + mountdir: /proc + mntdoor: / + type: proc + dev: 4 + dummy: 1 + remote: 0 + type_alc: 1 + devname: /dev/sda1 + mountdir: / + mntdoor: / + type: ext4 + dev: 2049 + dummy: 0 + remote: 0 + type_alc: 1 + [...] + * modules/mountlist-tests: New module file. + * tests/test-mountlist.c: New test file. + 2018-10-08 Paul Eggert <egg...@cs.ucla.edu> fts: cleanup after FTS_NOATIME removal diff --git a/modules/mountlist-tests b/modules/mountlist-tests new file mode 100644 index 000000000..5fb380f90 --- /dev/null +++ b/modules/mountlist-tests @@ -0,0 +1,11 @@ +Files: +tests/test-mountlist.c + +Depends-on: +mountlist + +configure.ac: + +Makefile.am: +TESTS += test-mountlist +check_PROGRAMS += test-mountlist diff --git a/tests/test-mountlist.c b/tests/test-mountlist.c new file mode 100644 index 000000000..474afd3f3 --- /dev/null +++ b/tests/test-mountlist.c @@ -0,0 +1,48 @@ +/* Test of <mountlist.h> functions. + Copyright (C) 2018 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. */ + +/* Written by Assaf Gordon <assafgor...@gmail.com>, 2018 */ + +#include <config.h> +#include <stdio.h> +#include <mountlist.h> + +int +main () +{ + struct mount_entry *mnt_ent = read_file_system_list (true); + + while (mnt_ent) + { + struct mount_entry *mnt_free; + + printf ("devname: %s\n", mnt_ent->me_devname); + printf ("mountdir: %s\n", mnt_ent->me_mountdir); + printf ("mntdoor: %s\n", mnt_ent->me_mntroot); + printf ("type: %s\n", mnt_ent->me_type); + printf ("dev: %ld\n", (long int)mnt_ent->me_dev); + printf ("dummy: %d\n", mnt_ent->me_dummy); + printf ("remote: %d\n", mnt_ent->me_remote); + printf ("type_alc: %d\n", mnt_ent->me_type_malloced); + putchar ('\n'); + + mnt_free = mnt_ent; + mnt_ent = mnt_ent->me_next; + free_mount_entry (mnt_free); + } + + return 0; +} -- 2.11.0
>From 4de125a449fd90b865bdf69a0632939531a71fd6 Mon Sep 17 00:00:00 2001 From: Assaf Gordon <assafgor...@gmail.com> Date: Wed, 10 Oct 2018 14:13:10 -0600 Subject: [PATCH 2/2] mountlist: add support for windows DOS-style drives Support basic DOS-style drives on Windows (e.g. C:\, D:\, Q:\). Using Win32 API that should be backwards compatible back to Windows XP. Example of 'struct mount_entry' (as printed by 'test-mountlist'): devname: \Device\HarddiskVolume2 mountdir: C:\ mntdoor: C:\ type: NTFS dev: -1 dummy: 0 remote: 0 type_alc: 1 devname: \Device\HarddiskVolume4 mountdir: D:\ mntdoor: D:\ type: NTFS dev: -1 dummy: 0 remote: 0 type_alc: 1 * m4/ls-mntd-fs.m4: Check for <windows.h> and GetLogicalDrives() function. If found, assume Win32 mount list method. Adds MOUNTED_GETLOGICALDRIVES to config.h, and fu_cv_getlogicaldrives={yes,no} to the ./configure script. * lib/mountlist.c (re_remote): Include this function for both CYGWIN and Win32. (read_file_system_list): If using Win32, call GetLogicalDrives(), GetVolumeInformation() and QueryDosDevice() to populate the mount entries list. --- ChangeLog | 33 ++++++++++++++++++++++++ lib/mountlist.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- m4/ls-mntd-fs.m4 | 20 +++++++++++++++ 3 files changed, 129 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index aa490686f..3f6e7f207 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,38 @@ 2018-10-10 Assaf Gordon <assafgor...@gmail.com> + mountlist: add support for windows DOS-style drives + Support basic DOS-style drives on Windows (e.g. C:\, D:\, Q:\). + Using Win32 API that should be backwards compatible back to Windows XP. + Example of 'struct mount_entry' (as printed by 'test-mountlist'): + devname: \Device\HarddiskVolume2 + mountdir: C:\ + mntdoor: C:\ + type: NTFS + dev: -1 + dummy: 0 + remote: 0 + type_alc: 1 + devname: \Device\HarddiskVolume4 + mountdir: D:\ + mntdoor: D:\ + type: NTFS + dev: -1 + dummy: 0 + remote: 0 + type_alc: 1 + * m4/ls-mntd-fs.m4: Check for <windows.h> and GetLogicalDrives() + function. If found, assume Win32 mount list method. + Adds MOUNTED_GETLOGICALDRIVES to config.h, + and fu_cv_getlogicaldrives={yes,no} to the ./configure script. + * lib/mountlist.c (re_remote): Include this function for both CYGWIN and + Win32. + (read_file_system_list): If using Win32, call GetLogicalDrives(), + GetVolumeInformation() and QueryDosDevice() to populate the mount + entries list. + + +2018-10-10 Assaf Gordon <assafgor...@gmail.com> + mountlist tests: add mountlist-tests module Call read_file_system_list, print the list, and free the entries. Typical output example: diff --git a/lib/mountlist.c b/lib/mountlist.c index b691f3808..12964d1ef 100644 --- a/lib/mountlist.c +++ b/lib/mountlist.c @@ -135,6 +135,10 @@ # include <sys/mntent.h> #endif +#ifdef MOUNTED_GETLOGICALDRIVES /* Win32 API */ +# include <windows.h> +#endif + #ifndef HAVE_HASMNTOPT # define hasmntopt(mnt, opt) ((char *) 0) #endif @@ -196,7 +200,7 @@ (ME_DUMMY_0 (Fs_name, Fs_type) || strcmp (Fs_type, "none") == 0) #endif -#ifdef __CYGWIN__ +#if defined __CYGWIN__ || defined MOUNTED_GETLOGICALDRIVES # include <windows.h> # define ME_REMOTE me_remote /* All cygwin mount points include ':' or start with '//'; so it @@ -1105,6 +1109,77 @@ read_file_system_list (bool need_fs_type) } #endif /* MOUNTED_INTERIX_STATVFS */ +#ifdef MOUNTED_GETLOGICALDRIVES + { + int i; + char RootPathName[4]; + char VolumeName[MAX_PATH+1]; + DWORD VolumeSerialNum; + DWORD MaxComponentLen; + DWORD FileSystemFlags; + char FileSystemName[MAX_PATH+1]; + char DosDevicePath[MAX_PATH+1]; + DWORD dw; + DWORD ld = GetLogicalDrives(); + + if (ld == 0) + return NULL; + + for (i=0 ; i<32; ++i) + { + + if (!(ld & (1<<i))) + continue; + + snprintf (RootPathName, 4, "%c:\\", (char)('A'+i)); + memset (VolumeName, 0, sizeof (VolumeName)); + memset (FileSystemName, 0, sizeof (FileSystemName)); + VolumeSerialNum = 0; + MaxComponentLen = 0; + FileSystemFlags = 0; + + /* There are various valid reasons why this could fail. + GetLastError() can provide more information, e.g.: + ERROR_ACCESS_DENIED (0x5): permission denied + ERROR_NOT_READY (0x15): e.g. a CDROM drive without a CD inside. */ + if (!GetVolumeInformation (RootPathName, + VolumeName, sizeof (VolumeName), + &VolumeSerialNum, + &MaxComponentLen, + &FileSystemFlags, + FileSystemName, sizeof (FileSystemName))) + continue; + + /* Chop the trailing backslash - QueryDosDevice does not accept it. */ + RootPathName[2] = '\x0'; + dw = QueryDosDevice (RootPathName, + DosDevicePath, sizeof (DosDevicePath)); + + /* FIXME: for now, the buffer is fixed size. If the call fails + or if the buffer is too small - skip the drive. */ + if (dw == 0 || dw == ERROR_INSUFFICIENT_BUFFER) + continue; + + /* restore the backslash. */ + RootPathName[2] = '\\'; + + me = xmalloc (sizeof *me); + me->me_devname = xstrdup (DosDevicePath); + me->me_mountdir = xstrdup (RootPathName); + me->me_mntroot = xstrdup (RootPathName); + me->me_type = xstrdup (FileSystemName); + me->me_type_malloced = 1; + me->me_dummy = 0; + me->me_remote = me_remote (RootPathName, NULL); + me->me_dev = -1; + + /* Add to the linked list. */ + *mtail = me; + mtail = &me->me_next; + } + } +#endif /* MOUNTED_GETLOGICALDRIVES */ + *mtail = NULL; return mount_list; diff --git a/m4/ls-mntd-fs.m4 b/m4/ls-mntd-fs.m4 index 4a84f0aca..e3a4ae5ce 100644 --- a/m4/ls-mntd-fs.m4 +++ b/m4/ls-mntd-fs.m4 @@ -349,6 +349,26 @@ if test -z "$ac_list_mounted_fs"; then fi if test -z "$ac_list_mounted_fs"; then + # Win32 API (based on GetLogicalDrives() function) + AC_MSG_CHECKING([for Win32API Volume Information]) + AC_CACHE_VAL([fu_cv_getlogicaldrives], + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include <windows.h> +]], + [[ DWORD dw = GetLogicalDrives(); return 0; ]])], + [fu_cv_getlogicaldrives=yes], + [fu_cv_getlogicaldrives=no])]) + AC_MSG_RESULT([$fu_cv_getlogicaldrives]) + if test $fu_cv_getlogicaldrives = yes; then + ac_list_mounted_fs=found + AC_DEFINE([MOUNTED_GETLOGICALDRIVES], [1], + [Define if there is a function named GetLogicalDrives for reading the + list of logical drives. + (Win32 API)]) + fi +fi + +if test -z "$ac_list_mounted_fs"; then AC_MSG_ERROR([could not determine how to read list of mounted file systems]) # FIXME -- no need to abort building the whole package # Can't build mountlist.c or anything that needs its functions -- 2.11.0