comparison dwcompat.c @ 2645:cb984fab3a17

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.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Mon, 16 Aug 2021 15:53:49 +0000
parents 45a6b33a003a
children
comparison
equal deleted inserted replaced
2644:45a6b33a003a 2645:cb984fab3a17
77 va_end(args); 77 va_end(args);
78 78
79 return buf; 79 return buf;
80 } 80 }
81 81
82 /* Get around getmntinfo() not being thread safe */
83 #if defined(__FreeBSD__) || defined(__MAC__) || defined(__IOS__)
84 int _getmntinfo_r(struct statfs **mntbufp, int flags)
85 {
86 static HMTX mutex = 0;
87 int result;
88
89 if(!mutex)
90 mutex = dw_mutex_new();
91
92 dw_mutex_lock(mutex);
93 result = getmntinfo(mntbufp, flags);
94 dw_mutex_unlock(mutex);
95 return result;
96 }
97 #endif
98
99 #ifdef __MINGW32__ 82 #ifdef __MINGW32__
100 double API drivefree(int drive) 83 double API drivefree(int drive)
101 #else 84 #else
102 long double API drivefree(int drive) 85 long double API drivefree(int drive)
103 #endif 86 #endif
126 if(GetDiskFreeSpace(buffer, &spc, &bps, &fc, &tc) == 0) 109 if(GetDiskFreeSpace(buffer, &spc, &bps, &fc, &tc) == 0)
127 return 0; 110 return 0;
128 111
129 return (long double)((double)spc*(double)bps*(double)fc); 112 return (long double)((double)spc*(double)bps*(double)fc);
130 #elif defined(__FreeBSD__) || defined(__MAC__) || defined(__IOS__) 113 #elif defined(__FreeBSD__) || defined(__MAC__) || defined(__IOS__)
131 struct statfs *fsp = NULL; 114 int entries = getfsstat(NULL, 0, MNT_NOWAIT), index = 1;
132 int entries, index = 1; 115
133 116 if(entries > 0)
134 entries = _getmntinfo_r(&fsp, MNT_NOWAIT); 117 {
135 118 struct statfs *fsp = alloca(sizeof(struct statfs) * entries);
136 for (; entries-- > 0; fsp++) 119
137 { 120 entries = getfsstat(fsp, sizeof(struct statfs) * entries, MNT_NOWAIT);
138 if(index == drive) 121
139 return (long double)((double)fsp->f_bsize * (double)fsp->f_bavail); 122 for(; entries-- > 0; fsp++)
140 index++; 123 {
124 if(index == drive)
125 return (long double)((double)fsp->f_bsize * (double)fsp->f_bavail);
126 index++;
127 }
141 } 128 }
142 return 0; 129 return 0;
143 #elif defined(__sun__) 130 #elif defined(__sun__)
144 FILE *fp = fopen("/etc/mnttab", "r"); 131 FILE *fp = fopen("/etc/mnttab", "r");
145 struct mnttab mnt; 132 struct mnttab mnt;
162 } 149 }
163 } 150 }
164 fclose(fp); 151 fclose(fp);
165 return size; 152 return size;
166 } 153 }
167 index++; 154 index++;
168 } 155 }
169 fclose(fp); 156 fclose(fp);
170 } 157 }
171 return 0; 158 return 0;
172 #elif defined(__linux__) 159 #elif defined(__linux__)
192 } 179 }
193 } 180 }
194 endmntent(fp); 181 endmntent(fp);
195 return size; 182 return size;
196 } 183 }
197 index++; 184 index++;
198 } 185 }
199 endmntent(fp); 186 endmntent(fp);
200 } 187 }
201 return 0; 188 return 0;
202 #else 189 #else
234 if(GetDiskFreeSpace(buffer, &spc, &bps, &fc, &tc) == 0) 221 if(GetDiskFreeSpace(buffer, &spc, &bps, &fc, &tc) == 0)
235 return 0; 222 return 0;
236 223
237 return (long double)((double)spc*(double)bps*(double)tc); 224 return (long double)((double)spc*(double)bps*(double)tc);
238 #elif defined(__FreeBSD__) || defined(__MAC__) || defined(__IOS__) 225 #elif defined(__FreeBSD__) || defined(__MAC__) || defined(__IOS__)
239 struct statfs *fsp = NULL; 226 int entries = getfsstat(NULL, 0, MNT_NOWAIT), index = 1;
240 int entries, index = 1; 227
241 228 if(entries > 0)
242 entries = _getmntinfo_r(&fsp, MNT_NOWAIT); 229 {
243 230 struct statfs *fsp = alloca(sizeof(struct statfs) * entries);
244 for (; entries-- > 0; fsp++) 231
245 { 232 entries = getfsstat(fsp, sizeof(struct statfs) * entries, MNT_NOWAIT);
246 if(index == drive) 233
247 return (long double)((double)fsp->f_bsize * (double)fsp->f_blocks); 234 for(; entries-- > 0; fsp++)
248 index++; 235 {
236 if(index == drive)
237 return (long double)((double)fsp->f_bsize * (double)fsp->f_blocks);
238 index++;
239 }
249 } 240 }
250 return 0; 241 return 0;
251 #elif defined(__sun__) 242 #elif defined(__sun__)
252 FILE *fp = fopen("/etc/mnttab", "r"); 243 FILE *fp = fopen("/etc/mnttab", "r");
253 struct mnttab mnt; 244 struct mnttab mnt;
334 buffer[0] = drive + 'A' - 1; 325 buffer[0] = drive + 'A' - 1;
335 326
336 if(GetVolumeInformation(buffer, volname, 100, &spc, &bps, &fc, NULL, 0) != 0) 327 if(GetVolumeInformation(buffer, volname, 100, &spc, &bps, &fc, NULL, 0) != 0)
337 return 1; 328 return 1;
338 #elif defined(__FreeBSD__) || defined(__MAC__) || defined(__IOS__) 329 #elif defined(__FreeBSD__) || defined(__MAC__) || defined(__IOS__)
339 struct statfs *fsp = NULL; 330 int entries = getfsstat(NULL, 0, MNT_NOWAIT), index = 1;
340 int entries, index = 1; 331
341 332 if(entries > 0)
342 entries = _getmntinfo_r(&fsp, MNT_NOWAIT); 333 {
343 334 struct statfs *fsp = alloca(sizeof(struct statfs) * entries);
344 for (; entries-- > 0; fsp++) 335
345 { 336 entries = getfsstat(fsp, sizeof(struct statfs) * entries, MNT_NOWAIT);
346 if(index == drive && fsp->f_blocks) 337
347 return 1; 338 for (; entries-- > 0; fsp++)
348 index++; 339 {
340 if(index == drive && fsp->f_blocks)
341 return 1;
342 index++;
343 }
349 } 344 }
350 #elif defined(__sun__) 345 #elif defined(__sun__)
351 FILE *fp = fopen("/etc/mnttab", "r"); 346 FILE *fp = fopen("/etc/mnttab", "r");
352 struct mnttab mnt; 347 struct mnttab mnt;
353 struct statvfs sfs; 348 struct statvfs sfs;
365 if(!statvfs(mnt.mnt_mountp, &sfs) && sfs.f_blocks) 360 if(!statvfs(mnt.mnt_mountp, &sfs) && sfs.f_blocks)
366 return 1; 361 return 1;
367 } 362 }
368 return 0; 363 return 0;
369 } 364 }
370 index++; 365 index++;
371 } 366 }
372 fclose(fp); 367 fclose(fp);
373 } 368 }
374 #elif defined(__linux__) 369 #elif defined(__linux__)
375 FILE *fp = setmntent(MOUNTED, "r"); 370 FILE *fp = setmntent(MOUNTED, "r");
392 return 1; 387 return 1;
393 } 388 }
394 } 389 }
395 return 0; 390 return 0;
396 } 391 }
397 index++; 392 index++;
398 } 393 }
399 endmntent(fp); 394 endmntent(fp);
400 } 395 }
401 #endif 396 #endif
402 return 0; 397 return 0;
404 399
405 void API getfsname(int drive, char *buf, int len) 400 void API getfsname(int drive, char *buf, int len)
406 { 401 {
407 #if defined(__UNIX__) || defined(__MAC__) || defined(__IOS__) || defined(__ANDROID__) 402 #if defined(__UNIX__) || defined(__MAC__) || defined(__IOS__) || defined(__ANDROID__)
408 #if defined(__FreeBSD__) || defined(__MAC__) || defined(__IOS__) 403 #if defined(__FreeBSD__) || defined(__MAC__) || defined(__IOS__)
409 struct statfs *fsp = NULL; 404 int entries = getfsstat(NULL, 0, MNT_NOWAIT), index = 1;
410 int entries, index = 1; 405
411 406 if(entries > 0)
412 strncpy(buf, "Unknown", len); 407 {
413 408 struct statfs *fsp = alloca(sizeof(struct statfs) * entries);
414 entries = _getmntinfo_r(&fsp, MNT_NOWAIT); 409
415 410 entries = getfsstat(fsp, sizeof(struct statfs) * entries, MNT_NOWAIT);
416 for (; entries-- > 0; fsp++) 411
417 { 412 strncpy(buf, "Unknown", len);
418 if(index == drive) 413
419 strncpy(buf, fsp->f_mntonname, len); 414 for(; entries-- > 0; fsp++)
420 index++; 415 {
416 if(index == drive)
417 strncpy(buf, fsp->f_mntonname, len);
418 index++;
419 }
421 } 420 }
422 #elif defined(__sun__) 421 #elif defined(__sun__)
423 FILE *fp = fopen("/etc/mnttab", "r"); 422 FILE *fp = fopen("/etc/mnttab", "r");
424 struct mnttab mnt; 423 struct mnttab mnt;
425 int index = 1; 424 int index = 1;