From 0fdf99bee07b6c38795eb5415b5e337ab82cfba8 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Sun, 27 Jun 2021 13:40:07 +0100 Subject: win32: changes to mntent implementation Make the structure returned by getmntent(3) static so it persists after endmntent(3) closes the stream. No current caller in the WIN32 port needs this functionality but it's good to match the documented behaviour. Populate more fields of the mntent structure in find_mount_point(). This is required to support the df -t and -T flags recently added upstream. The static structures used here are allocated on demand. Separate static structures are used in each case because df iterates through mounts calling statfs(2) on each and the WIN32 implementation of statfs(2) calls find_mount_point(). --- libbb/find_mount_point.c | 23 ++++------ win32/mntent.c | 106 +++++++++++++++++++++++++---------------------- win32/mntent.h | 12 ++++++ 3 files changed, 77 insertions(+), 64 deletions(-) diff --git a/libbb/find_mount_point.c b/libbb/find_mount_point.c index edf734614..2464357c1 100644 --- a/libbb/find_mount_point.c +++ b/libbb/find_mount_point.c @@ -6,6 +6,9 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +#if ENABLE_PLATFORM_MINGW32 +# define MNTENT_PRIVATE +#endif #include "libbb.h" #include @@ -25,13 +28,7 @@ struct mntent* FAST_FUNC find_mount_point(const char *name, int subdir_too) dev_t devno_of_name; bool block_dev; #else - static char mnt_fsname[4]; - static char mnt_dir[4]; - static char mnt_type[1]; - static char mnt_opts[1]; - static struct mntent my_mount_entry = { - mnt_fsname, mnt_dir, mnt_type, mnt_opts, 0, 0 - }; + static struct mntdata *data = NULL; char *current; const char *path; DWORD len; @@ -105,15 +102,11 @@ struct mntent* FAST_FUNC find_mount_point(const char *name, int subdir_too) } if ( path && isalpha(path[0]) && path[1] == ':' ) { - mnt_fsname[0] = path[0]; - mnt_fsname[1] = path[1]; - mnt_fsname[2] = '\0'; - mnt_dir[0] = path[0]; - mnt_dir[1] = path[1]; - mnt_dir[2] = '\\'; - mnt_dir[3] = '\0'; + if (data == NULL) + data = xmalloc(sizeof(*data)); - mountEntry = &my_mount_entry; + fill_mntdata(data, toupper(path[0]) - 'A'); + mountEntry = &data->me; } free(current); #endif diff --git a/win32/mntent.c b/win32/mntent.c index 7ab51239d..7f142b485 100644 --- a/win32/mntent.c +++ b/win32/mntent.c @@ -2,39 +2,20 @@ * A simple WIN32 implementation of mntent routines. It only handles * logical drives. */ +#define MNTENT_PRIVATE #include "libbb.h" -struct mntdata { - DWORD flags; +struct mntstate { + DWORD drives; int index; - struct mntent me; - char mnt_fsname[PATH_MAX]; - char mnt_dir[4]; - char mnt_type[100]; - char mnt_opts[4]; }; -FILE *mingw_setmntent(void) -{ - struct mntdata *data; - - if ( (data=malloc(sizeof(struct mntdata))) == NULL ) { - return NULL; - } - - data->flags = GetLogicalDrives(); - data->index = -1; - - return (FILE *)data; -} - -struct mntent *getmntent(FILE *stream) +int fill_mntdata(struct mntdata *data, int index) { - struct mntdata *data = (struct mntdata *)stream; - struct mntent *entry; UINT drive_type; char buf[PATH_MAX]; + // initialise pointers and scalar data data->me.mnt_fsname = data->mnt_fsname; data->me.mnt_dir = data->mnt_dir; data->me.mnt_type = data->mnt_type; @@ -42,34 +23,61 @@ struct mntent *getmntent(FILE *stream) data->me.mnt_freq = 0; data->me.mnt_passno = 0; - entry = NULL; - while ( ++data->index < 26 ) { - if ( (data->flags & 1<index) != 0 ) { - data->mnt_fsname[0] = 'A' + data->index; - data->mnt_fsname[1] = ':'; - data->mnt_fsname[2] = '\0'; - data->mnt_dir[0] = 'A' + data->index; - data->mnt_dir[1] = ':'; - data->mnt_dir[2] = '/'; - data->mnt_dir[3] = '\0'; - data->mnt_type[0] = '\0'; - data->mnt_opts[0] = '\0'; + // initialise strings + data->mnt_fsname[0] = 'A' + index; + data->mnt_fsname[1] = ':'; + data->mnt_fsname[2] = '\0'; + data->mnt_dir[0] = 'A' + index; + data->mnt_dir[1] = ':'; + data->mnt_dir[2] = '/'; + data->mnt_dir[3] = '\0'; + data->mnt_type[0] = '\0'; + data->mnt_opts[0] = '\0'; - drive_type = GetDriveType(data->mnt_dir); - if ( drive_type == DRIVE_FIXED || drive_type == DRIVE_CDROM || - drive_type == DRIVE_REMOVABLE || - drive_type == DRIVE_REMOTE ) { - if ( !GetVolumeInformation(data->mnt_dir, NULL, 0, NULL, NULL, - NULL, data->mnt_type, 100) ) { - continue; - } + drive_type = GetDriveType(data->mnt_dir); + if (drive_type == DRIVE_FIXED || drive_type == DRIVE_CDROM || + drive_type == DRIVE_REMOVABLE || drive_type == DRIVE_REMOTE) { + if (!GetVolumeInformation(data->mnt_dir, NULL, 0, NULL, NULL, + NULL, data->mnt_type, 100)) { + return FALSE; + } + + if (realpath(data->mnt_dir, buf) != NULL) { + if (isalpha(buf[0]) && strcmp(buf+1, ":/") == 0) + buf[2] = '\0'; + strcpy(data->mnt_fsname, buf); + } + return TRUE; + } + return FALSE; +} + +FILE *mingw_setmntent(void) +{ + struct mntstate *state; + + if ( (state=malloc(sizeof(struct mntstate))) == NULL ) { + return NULL; + } + + state->drives = GetLogicalDrives(); + state->index = -1; + + return (FILE *)state; +} + +struct mntent *getmntent(FILE *stream) +{ + struct mntstate *state = (struct mntstate *)stream; + static struct mntdata *data = NULL; + struct mntent *entry = NULL; - if (realpath(data->mnt_dir, buf) != NULL) { - if (isalpha(buf[0]) && strcmp(buf+1, ":/") == 0) - buf[2] = '\0'; - strcpy(data->mnt_fsname, buf); - } + while (++state->index < 26) { + if ((state->drives & 1 << state->index) != 0) { + if (data == NULL) + data = xmalloc(sizeof(*data)); + if (fill_mntdata(data, state->index)) { entry = &data->me; break; } diff --git a/win32/mntent.h b/win32/mntent.h index 8bdf3d45e..029f18b96 100644 --- a/win32/mntent.h +++ b/win32/mntent.h @@ -16,6 +16,18 @@ extern FILE *mingw_setmntent(void); extern struct mntent *getmntent(FILE *stream); extern int endmntent(FILE *stream); +# if defined(MNTENT_PRIVATE) +struct mntdata { + struct mntent me; + char mnt_fsname[PATH_MAX]; + char mnt_dir[4]; + char mnt_type[100]; + char mnt_opts[4]; +}; + +extern int fill_mntdata(struct mntdata *data, int index); +# endif + #define setmntent(f, m) mingw_setmntent() #endif -- cgit v1.2.3-55-g6feb