# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1629129229 0 # Node ID cb984fab3a170db1e21a8189be6e60f3d0e35775 # Parent 45a6b33a003a2caaf964dd07953c710ed1edf71a Mac/iOS/FreeBSD: Rewrite the filesystem code using getfsstat(). I had previously been using a mutex to protect access to getmntinfo(). However recently realized I can use getfsstat() and remove the mutex. diff -r 45a6b33a003a -r cb984fab3a17 dwcompat.c --- a/dwcompat.c Mon Aug 16 06:51:28 2021 +0000 +++ b/dwcompat.c Mon Aug 16 15:53:49 2021 +0000 @@ -79,23 +79,6 @@ return buf; } -/* Get around getmntinfo() not being thread safe */ -#if defined(__FreeBSD__) || defined(__MAC__) || defined(__IOS__) -int _getmntinfo_r(struct statfs **mntbufp, int flags) -{ - static HMTX mutex = 0; - int result; - - if(!mutex) - mutex = dw_mutex_new(); - - dw_mutex_lock(mutex); - result = getmntinfo(mntbufp, flags); - dw_mutex_unlock(mutex); - return result; -} -#endif - #ifdef __MINGW32__ double API drivefree(int drive) #else @@ -128,16 +111,20 @@ return (long double)((double)spc*(double)bps*(double)fc); #elif defined(__FreeBSD__) || defined(__MAC__) || defined(__IOS__) - struct statfs *fsp = NULL; - int entries, index = 1; + int entries = getfsstat(NULL, 0, MNT_NOWAIT), index = 1; - entries = _getmntinfo_r(&fsp, MNT_NOWAIT); + if(entries > 0) + { + struct statfs *fsp = alloca(sizeof(struct statfs) * entries); - for (; entries-- > 0; fsp++) - { - if(index == drive) - return (long double)((double)fsp->f_bsize * (double)fsp->f_bavail); - index++; + entries = getfsstat(fsp, sizeof(struct statfs) * entries, MNT_NOWAIT); + + for(; entries-- > 0; fsp++) + { + if(index == drive) + return (long double)((double)fsp->f_bsize * (double)fsp->f_bavail); + index++; + } } return 0; #elif defined(__sun__) @@ -164,7 +151,7 @@ fclose(fp); return size; } - index++; + index++; } fclose(fp); } @@ -194,7 +181,7 @@ endmntent(fp); return size; } - index++; + index++; } endmntent(fp); } @@ -236,16 +223,20 @@ return (long double)((double)spc*(double)bps*(double)tc); #elif defined(__FreeBSD__) || defined(__MAC__) || defined(__IOS__) - struct statfs *fsp = NULL; - int entries, index = 1; + int entries = getfsstat(NULL, 0, MNT_NOWAIT), index = 1; - entries = _getmntinfo_r(&fsp, MNT_NOWAIT); + if(entries > 0) + { + struct statfs *fsp = alloca(sizeof(struct statfs) * entries); - for (; entries-- > 0; fsp++) - { - if(index == drive) - return (long double)((double)fsp->f_bsize * (double)fsp->f_blocks); - index++; + entries = getfsstat(fsp, sizeof(struct statfs) * entries, MNT_NOWAIT); + + for(; entries-- > 0; fsp++) + { + if(index == drive) + return (long double)((double)fsp->f_bsize * (double)fsp->f_blocks); + index++; + } } return 0; #elif defined(__sun__) @@ -336,16 +327,20 @@ if(GetVolumeInformation(buffer, volname, 100, &spc, &bps, &fc, NULL, 0) != 0) return 1; #elif defined(__FreeBSD__) || defined(__MAC__) || defined(__IOS__) - struct statfs *fsp = NULL; - int entries, index = 1; + int entries = getfsstat(NULL, 0, MNT_NOWAIT), index = 1; - entries = _getmntinfo_r(&fsp, MNT_NOWAIT); + if(entries > 0) + { + struct statfs *fsp = alloca(sizeof(struct statfs) * entries); - for (; entries-- > 0; fsp++) - { - if(index == drive && fsp->f_blocks) - return 1; - index++; + entries = getfsstat(fsp, sizeof(struct statfs) * entries, MNT_NOWAIT); + + for (; entries-- > 0; fsp++) + { + if(index == drive && fsp->f_blocks) + return 1; + index++; + } } #elif defined(__sun__) FILE *fp = fopen("/etc/mnttab", "r"); @@ -367,7 +362,7 @@ } return 0; } - index++; + index++; } fclose(fp); } @@ -394,7 +389,7 @@ } return 0; } - index++; + index++; } endmntent(fp); } @@ -406,18 +401,22 @@ { #if defined(__UNIX__) || defined(__MAC__) || defined(__IOS__) || defined(__ANDROID__) #if defined(__FreeBSD__) || defined(__MAC__) || defined(__IOS__) - struct statfs *fsp = NULL; - int entries, index = 1; + int entries = getfsstat(NULL, 0, MNT_NOWAIT), index = 1; - strncpy(buf, "Unknown", len); + if(entries > 0) + { + struct statfs *fsp = alloca(sizeof(struct statfs) * entries); - entries = _getmntinfo_r(&fsp, MNT_NOWAIT); + entries = getfsstat(fsp, sizeof(struct statfs) * entries, MNT_NOWAIT); + + strncpy(buf, "Unknown", len); - for (; entries-- > 0; fsp++) - { - if(index == drive) - strncpy(buf, fsp->f_mntonname, len); - index++; + for(; entries-- > 0; fsp++) + { + if(index == drive) + strncpy(buf, fsp->f_mntonname, len); + index++; + } } #elif defined(__sun__) FILE *fp = fopen("/etc/mnttab", "r");