]> git.saurik.com Git - apple/cf.git/blame - CFFileUtilities.c
CF-476.18.tar.gz
[apple/cf.git] / CFFileUtilities.c
CommitLineData
9ce05555 1/*
bd5b749c 2 * Copyright (c) 2008 Apple Inc. All rights reserved.
9ce05555
A
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
9ce05555
A
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23/* CFFileUtilities.c
24 Copyright 1999-2002, Apple, Inc. All rights reserved.
25 Responsibility: Christopher Kane
26*/
27
28#include "CFInternal.h"
29#include "CFPriv.h"
bd5b749c
A
30#include <string.h>
31#include <unistd.h>
32#include <dirent.h>
33#include <sys/stat.h>
34#include <sys/types.h>
35#include <pwd.h>
36#include <fcntl.h>
37#include <errno.h>
38#include <stdio.h>
9ce05555 39
bd5b749c 40#define CF_OPENFLGS (0)
9ce05555
A
41
42
43__private_extern__ CFStringRef _CFCopyExtensionForAbstractType(CFStringRef abstractType) {
bd5b749c 44 return (abstractType ? (CFStringRef)CFRetain(abstractType) : NULL);
9ce05555
A
45}
46
47
48__private_extern__ Boolean _CFCreateDirectory(const char *path) {
bd5b749c 49#if 0 || 0
9ce05555
A
50 return CreateDirectoryA(path, (LPSECURITY_ATTRIBUTES)NULL);
51#else
bd5b749c
A
52 int no_hang_fd = open("/dev/autofs_nowait", 0);
53 int ret = ((mkdir(path, 0777) == 0) ? true : false);
54 close(no_hang_fd);
55 return ret;
9ce05555
A
56#endif
57}
58
59__private_extern__ Boolean _CFRemoveDirectory(const char *path) {
bd5b749c 60#if 0 || 0
9ce05555
A
61 return RemoveDirectoryA(path);
62#else
bd5b749c
A
63 int no_hang_fd = open("/dev/autofs_nowait", 0);
64 int ret = ((rmdir(path) == 0) ? true : false);
65 close(no_hang_fd);
66 return ret;
9ce05555
A
67#endif
68}
69
70__private_extern__ Boolean _CFDeleteFile(const char *path) {
bd5b749c 71#if 0 || 0
9ce05555
A
72 return DeleteFileA(path);
73#else
bd5b749c
A
74 int no_hang_fd = open("/dev/autofs_nowait", 0);
75 int ret = unlink(path) == 0;
76 close(no_hang_fd);
77 return ret;
9ce05555
A
78#endif
79}
80
81__private_extern__ Boolean _CFReadBytesFromFile(CFAllocatorRef alloc, CFURLRef url, void **bytes, CFIndex *length, CFIndex maxLength) {
82 // maxLength is the number of bytes desired, or 0 if the whole file is desired regardless of length.
83 struct stat statBuf;
84 int fd = -1;
85 char path[CFMaxPathSize];
bd5b749c 86 if (!CFURLGetFileSystemRepresentation(url, true, (uint8_t *)path, CFMaxPathSize)) {
9ce05555
A
87 return false;
88 }
89
90 *bytes = NULL;
91
0ae65c4b 92
bd5b749c 93#if 0 || 0
9ce05555
A
94 fd = open(path, O_RDONLY|CF_OPENFLGS, 0666|_S_IREAD);
95#else
bd5b749c 96 int no_hang_fd = open("/dev/autofs_nowait", 0);
9ce05555
A
97 fd = open(path, O_RDONLY|CF_OPENFLGS, 0666);
98#endif
99 if (fd < 0) {
bd5b749c 100 close(no_hang_fd);
9ce05555
A
101 return false;
102 }
103 if (fstat(fd, &statBuf) < 0) {
104 int saveerr = thread_errno();
105 close(fd);
bd5b749c 106 close(no_hang_fd);
9ce05555
A
107 thread_set_errno(saveerr);
108 return false;
109 }
110 if ((statBuf.st_mode & S_IFMT) != S_IFREG) {
111 close(fd);
bd5b749c 112 close(no_hang_fd);
9ce05555
A
113 thread_set_errno(EACCES);
114 return false;
115 }
116 if (statBuf.st_size == 0) {
117 *bytes = CFAllocatorAllocate(alloc, 4, 0); // don't return constant string -- it's freed!
118 if (__CFOASafe) __CFSetLastAllocationEventName(*bytes, "CFUtilities (file-bytes)");
119 *length = 0;
120 } else {
121 CFIndex desiredLength;
122 if ((maxLength >= statBuf.st_size) || (maxLength == 0)) {
123 desiredLength = statBuf.st_size;
124 } else {
125 desiredLength = maxLength;
126 }
127 *bytes = CFAllocatorAllocate(alloc, desiredLength, 0);
128 if (__CFOASafe) __CFSetLastAllocationEventName(*bytes, "CFUtilities (file-bytes)");
d8925383 129// fcntl(fd, F_NOCACHE, 1);
9ce05555
A
130 if (read(fd, *bytes, desiredLength) < 0) {
131 CFAllocatorDeallocate(alloc, *bytes);
132 close(fd);
bd5b749c 133 close(no_hang_fd);
9ce05555
A
134 return false;
135 }
136 *length = desiredLength;
137 }
138 close(fd);
bd5b749c 139 close(no_hang_fd);
9ce05555
A
140 return true;
141}
142
143__private_extern__ Boolean _CFWriteBytesToFile(CFURLRef url, const void *bytes, CFIndex length) {
144 struct stat statBuf;
145 int fd = -1;
bd5b749c 146 int mode;
9ce05555 147 char path[CFMaxPathSize];
bd5b749c 148 if (!CFURLGetFileSystemRepresentation(url, true, (uint8_t *)path, CFMaxPathSize)) {
9ce05555
A
149 return false;
150 }
151
bd5b749c
A
152#if 0 || 0
153 mode = 0666;
9ce05555
A
154 if (0 == stat(path, &statBuf)) {
155 mode = statBuf.st_mode;
156 } else if (thread_errno() != ENOENT) {
157 return false;
158 }
9ce05555 159 fd = open(path, O_WRONLY|O_CREAT|O_TRUNC|CF_OPENFLGS, 0666|_S_IWRITE);
9ce05555
A
160 if (fd < 0) {
161 return false;
162 }
163 if (length && write(fd, bytes, length) != length) {
164 int saveerr = thread_errno();
165 close(fd);
166 thread_set_errno(saveerr);
167 return false;
168 }
9ce05555 169 FlushFileBuffers((HANDLE)_get_osfhandle(fd));
bd5b749c 170 close(fd);
9ce05555 171#else
bd5b749c
A
172 int no_hang_fd = open("/dev/autofs_nowait", 0);
173 mode = 0666;
174 if (0 == stat(path, &statBuf)) {
175 mode = statBuf.st_mode;
176 } else if (thread_errno() != ENOENT) {
177 close(no_hang_fd);
178 return false;
179 }
180 fd = open(path, O_WRONLY|O_CREAT|O_TRUNC|CF_OPENFLGS, 0666);
181 if (fd < 0) {
182 close(no_hang_fd);
183 return false;
184 }
185 if (length && write(fd, bytes, length) != length) {
186 int saveerr = thread_errno();
187 close(fd);
188 close(no_hang_fd);
189 thread_set_errno(saveerr);
190 return false;
191 }
9ce05555 192 fsync(fd);
9ce05555 193 close(fd);
bd5b749c
A
194 close(no_hang_fd);
195#endif
9ce05555
A
196 return true;
197}
198
199
200/* On Mac OS 8/9, one of dirSpec and dirURL must be non-NULL. On all other platforms, one of path and dirURL must be non-NULL
201If both are present, they are assumed to be in-synch; that is, they both refer to the same directory. */
bd5b749c 202/* Lately, dirSpec appears to be (rightfully) unused. */
9ce05555
A
203__private_extern__ CFMutableArrayRef _CFContentsOfDirectory(CFAllocatorRef alloc, char *dirPath, void *dirSpec, CFURLRef dirURL, CFStringRef matchingAbstractType) {
204 CFMutableArrayRef files = NULL;
205 Boolean releaseBase = false;
206 CFIndex pathLength = dirPath ? strlen(dirPath) : 0;
207 // MF:!!! Need to use four-letter type codes where appropriate.
208 CFStringRef extension = (matchingAbstractType ? _CFCopyExtensionForAbstractType(matchingAbstractType) : NULL);
209 CFIndex extLen = (extension ? CFStringGetLength(extension) : 0);
210 uint8_t extBuff[CFMaxPathSize];
9ce05555
A
211
212 if (extLen > 0) {
bd5b749c 213 CFStringGetBytes(extension, CFRangeMake(0, extLen), CFStringFileSystemEncoding(), 0, false, extBuff, CFMaxPathLength, &extLen);
9ce05555
A
214 extBuff[extLen] = '\0';
215 }
d8925383
A
216
217 uint8_t pathBuf[CFMaxPathSize];
218
219 if (!dirPath) {
220 if (!CFURLGetFileSystemRepresentation(dirURL, true, pathBuf, CFMaxPathLength)) {
221 if (extension) CFRelease(extension);
222 return NULL;
223 } else {
bd5b749c 224 dirPath = (char *)pathBuf;
d8925383
A
225 pathLength = strlen(dirPath);
226 }
227 }
9ce05555 228
bd5b749c
A
229#if (DEPLOYMENT_TARGET_MACOSX) || defined(__svr4__) || defined(__hpux__) || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
230 struct dirent buffer;
d8925383
A
231 struct dirent *dp;
232 int err;
bd5b749c
A
233
234 int no_hang_fd = open("/dev/autofs_nowait", 0);
235
236 DIR *dirp = opendir(dirPath);
9ce05555
A
237 if (!dirp) {
238 if (extension) {
239 CFRelease(extension);
240 }
bd5b749c 241 close(no_hang_fd);
9ce05555
A
242 return NULL;
243 // raiseErrno("opendir", path);
244 }
245 files = CFArrayCreateMutable(alloc, 0, & kCFTypeArrayCallBacks);
246
bd5b749c 247 while((0 == readdir_r(dirp, &buffer, &dp)) && dp) {
9ce05555
A
248 CFURLRef fileURL;
249 unsigned namelen = strlen(dp->d_name);
250
251 // skip . & ..; they cause descenders to go berserk
252 if (dp->d_name[0] == '.' && (namelen == 1 || (namelen == 2 && dp->d_name[1] == '.'))) {
253 continue;
254 }
bd5b749c
A
255
256 if (extLen > namelen) continue; // if the extension is the same length or longer than the name, it can't possibly match.
257
9ce05555
A
258 if (extLen > 0) {
259 // Check to see if it matches the extension we're looking for.
bd5b749c 260 if (strncmp(&(dp->d_name[namelen - extLen]), (char *)extBuff, extLen) != 0) {
9ce05555
A
261 continue;
262 }
263 }
264 if (dirURL == NULL) {
bd5b749c 265 dirURL = CFURLCreateFromFileSystemRepresentation(alloc, (uint8_t *)dirPath, pathLength, true);
9ce05555
A
266 releaseBase = true;
267 }
bd5b749c
A
268 if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN) {
269 Boolean isDir = (dp->d_type == DT_DIR);
270 if (!isDir) {
271 // Ugh; must stat.
272 char subdirPath[CFMaxPathLength];
273 struct stat statBuf;
274 strlcpy(subdirPath, dirPath, sizeof(subdirPath));
275 strlcat(subdirPath, "/", sizeof(subdirPath));
276 strlcat(subdirPath, dp->d_name, sizeof(subdirPath));
277 if (stat(subdirPath, &statBuf) == 0) {
278 isDir = ((statBuf.st_mode & S_IFMT) == S_IFDIR);
279 }
280 }
281 fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(alloc, (uint8_t *)dp->d_name, dp->d_namlen, isDir, dirURL);
282 } else {
283 fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase (alloc, (uint8_t *)dp->d_name, dp->d_namlen, false, dirURL);
284 }
9ce05555
A
285 CFArrayAppendValue(files, fileURL);
286 CFRelease(fileURL);
287 }
288 err = closedir(dirp);
bd5b749c 289 close(no_hang_fd);
9ce05555
A
290 if (err != 0) {
291 CFRelease(files);
292 if (releaseBase) {
293 CFRelease(dirURL);
294 }
295 if (extension) {
296 CFRelease(extension);
297 }
298 return NULL;
9ce05555
A
299 }
300
9ce05555
A
301#else
302
303#error _CFContentsOfDirectory() unknown architechture, not implemented
304
305#endif
306
307 if (extension) {
308 CFRelease(extension);
309 }
310 if (releaseBase) {
311 CFRelease(dirURL);
312 }
313 return files;
314}
315
316__private_extern__ SInt32 _CFGetFileProperties(CFAllocatorRef alloc, CFURLRef pathURL, Boolean *exists, SInt32 *posixMode, int64_t *size, CFDateRef *modTime, SInt32 *ownerID, CFArrayRef *dirContents) {
317 Boolean fileExists;
318 Boolean isDirectory = false;
319
bd5b749c
A
320 struct stat64 statBuf;
321 char path[CFMaxPathSize];
9ce05555
A
322
323 if ((exists == NULL) && (posixMode == NULL) && (size == NULL) && (modTime == NULL) && (ownerID == NULL) && (dirContents == NULL)) {
324 // Nothing to do.
325 return 0;
326 }
327
bd5b749c 328 if (!CFURLGetFileSystemRepresentation(pathURL, true, (uint8_t *)path, CFMaxPathLength)) {
9ce05555
A
329 return -1;
330 }
331
bd5b749c 332 if (stat64(path, &statBuf) != 0) {
9ce05555
A
333 // stat failed, but why?
334 if (thread_errno() == ENOENT) {
335 fileExists = false;
336 } else {
337 return thread_errno();
338 }
339 } else {
340 fileExists = true;
341 isDirectory = ((statBuf.st_mode & S_IFMT) == S_IFDIR);
342 }
343
344
345 if (exists != NULL) {
346 *exists = fileExists;
347 }
348
349 if (posixMode != NULL) {
350 if (fileExists) {
351
352 *posixMode = statBuf.st_mode;
353
354 } else {
355 *posixMode = 0;
356 }
357 }
358
359 if (size != NULL) {
360 if (fileExists) {
361
362 *size = statBuf.st_size;
363
364 } else {
365 *size = 0;
366 }
367 }
368
369 if (modTime != NULL) {
370 if (fileExists) {
bd5b749c
A
371 CFAbsoluteTime theTime = (CFAbsoluteTime)statBuf.st_mtimespec.tv_sec - kCFAbsoluteTimeIntervalSince1970;
372 theTime += (CFAbsoluteTime)statBuf.st_mtimespec.tv_nsec / 1000000000.0;
9ce05555
A
373 *modTime = CFDateCreate(alloc, theTime);
374 } else {
375 *modTime = NULL;
376 }
377 }
378
379 if (ownerID != NULL) {
380 if (fileExists) {
381
382 *ownerID = statBuf.st_uid;
383
384 } else {
385 *ownerID = -1;
386 }
387 }
388
389 if (dirContents != NULL) {
390 if (fileExists && isDirectory) {
391
392 CFMutableArrayRef contents = _CFContentsOfDirectory(alloc, path, NULL, pathURL, NULL);
393
394 if (contents) {
395 *dirContents = contents;
396 } else {
397 *dirContents = NULL;
398 }
399 } else {
400 *dirContents = NULL;
401 }
402 }
403 return 0;
404}
405
406
407// MF:!!! Should pull in the rest of the UniChar based path utils from Foundation.
bd5b749c 408#if (DEPLOYMENT_TARGET_MACOSX) || defined(__svr4__) || defined(__hpux__) || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
9ce05555
A
409 #define UNIX_PATH_SEMANTICS
410#elif defined(__WIN32__)
411 #define WINDOWS_PATH_SEMANTICS
412#else
413#error Unknown platform
414#endif
415
416#if defined(WINDOWS_PATH_SEMANTICS)
417 #define CFPreferredSlash ((UniChar)'\\')
418#elif defined(UNIX_PATH_SEMANTICS)
419 #define CFPreferredSlash ((UniChar)'/')
420#elif defined(HFS_PATH_SEMANTICS)
421 #define CFPreferredSlash ((UniChar)':')
422#else
423 #error Cannot define NSPreferredSlash on this platform
424#endif
425
426#if defined(HFS_PATH_SEMANTICS)
427#define HAS_DRIVE(S) (false)
428#define HAS_NET(S) (false)
429#else
430#define HAS_DRIVE(S) ((S)[1] == ':' && (('A' <= (S)[0] && (S)[0] <= 'Z') || ('a' <= (S)[0] && (S)[0] <= 'z')))
431#define HAS_NET(S) ((S)[0] == '\\' && (S)[1] == '\\')
432#endif
433
434#if defined(WINDOWS_PATH_SEMANTICS)
435 #define IS_SLASH(C) ((C) == '\\' || (C) == '/')
436#elif defined(UNIX_PATH_SEMANTICS)
437 #define IS_SLASH(C) ((C) == '/')
438#elif defined(HFS_PATH_SEMANTICS)
439 #define IS_SLASH(C) ((C) == ':')
440#endif
441
442__private_extern__ Boolean _CFIsAbsolutePath(UniChar *unichars, CFIndex length) {
443 if (length < 1) {
444 return false;
445 }
446#if defined(WINDOWS_PATH_SEMANTICS)
447 if (unichars[0] == '~') {
448 return true;
449 }
450 if (length < 2) {
451 return false;
452 }
453 if (HAS_NET(unichars)) {
454 return true;
455 }
456 if (length < 3) {
457 return false;
458 }
459 if (IS_SLASH(unichars[2]) && HAS_DRIVE(unichars)) {
460 return true;
461 }
462#elif defined(HFS_PATH_SEMANTICS)
463 return !IS_SLASH(unichars[0]);
464#else
465 if (unichars[0] == '~') {
466 return true;
467 }
468 if (IS_SLASH(unichars[0])) {
469 return true;
470 }
471#endif
472 return false;
473}
474
475__private_extern__ Boolean _CFStripTrailingPathSlashes(UniChar *unichars, CFIndex *length) {
476 Boolean destHasDrive = (1 < *length) && HAS_DRIVE(unichars);
477 CFIndex oldLength = *length;
478 while (((destHasDrive && 3 < *length) || (!destHasDrive && 1 < *length)) && IS_SLASH(unichars[*length - 1])) {
479 (*length)--;
480 }
481 return (oldLength != *length);
482}
483
484__private_extern__ Boolean _CFAppendPathComponent(UniChar *unichars, CFIndex *length, CFIndex maxLength, UniChar *component, CFIndex componentLength) {
485 if (0 == componentLength) {
486 return true;
487 }
488 if (maxLength < *length + 1 + componentLength) {
489 return false;
490 }
491 switch (*length) {
492 case 0:
493 break;
494 case 1:
495 if (!IS_SLASH(unichars[0])) {
496 unichars[(*length)++] = CFPreferredSlash;
497 }
498 break;
499 case 2:
500 if (!HAS_DRIVE(unichars) && !HAS_NET(unichars)) {
501 unichars[(*length)++] = CFPreferredSlash;
502 }
503 break;
504 default:
505 unichars[(*length)++] = CFPreferredSlash;
506 break;
507 }
508 memmove(unichars + *length, component, componentLength * sizeof(UniChar));
509 *length += componentLength;
510 return true;
511}
512
513__private_extern__ Boolean _CFAppendPathExtension(UniChar *unichars, CFIndex *length, CFIndex maxLength, UniChar *extension, CFIndex extensionLength) {
514 if (maxLength < *length + 1 + extensionLength) {
515 return false;
516 }
517 if ((0 < extensionLength && IS_SLASH(extension[0])) || (1 < extensionLength && HAS_DRIVE(extension))) {
518 return false;
519 }
520 _CFStripTrailingPathSlashes(unichars, length);
521 switch (*length) {
522 case 0:
523 return false;
524 case 1:
525 if (IS_SLASH(unichars[0]) || unichars[0] == '~') {
526 return false;
527 }
528 break;
529 case 2:
530 if (HAS_DRIVE(unichars) || HAS_NET(unichars)) {
531 return false;
532 }
533 break;
534 case 3:
535 if (IS_SLASH(unichars[2]) && HAS_DRIVE(unichars)) {
536 return false;
537 }
538 break;
539 }
540 if (0 < *length && unichars[0] == '~') {
541 CFIndex idx;
542 Boolean hasSlash = false;
543 for (idx = 1; idx < *length; idx++) {
544 if (IS_SLASH(unichars[idx])) {
545 hasSlash = true;
546 break;
547 }
548 }
549 if (!hasSlash) {
550 return false;
551 }
552 }
553 unichars[(*length)++] = '.';
554 memmove(unichars + *length, extension, extensionLength * sizeof(UniChar));
555 *length += extensionLength;
556 return true;
557}
558
559__private_extern__ Boolean _CFTransmutePathSlashes(UniChar *unichars, CFIndex *length, UniChar replSlash) {
560 CFIndex didx, sidx, scnt = *length;
561 sidx = (1 < *length && HAS_NET(unichars)) ? 2 : 0;
562 didx = sidx;
563 while (sidx < scnt) {
564 if (IS_SLASH(unichars[sidx])) {
565 unichars[didx++] = replSlash;
566 for (sidx++; sidx < scnt && IS_SLASH(unichars[sidx]); sidx++);
567 } else {
568 unichars[didx++] = unichars[sidx++];
569 }
570 }
571 *length = didx;
572 return (scnt != didx);
573}
574
575__private_extern__ CFIndex _CFStartOfLastPathComponent(UniChar *unichars, CFIndex length) {
576 CFIndex idx;
577 if (length < 2) {
578 return 0;
579 }
580 for (idx = length - 1; idx; idx--) {
581 if (IS_SLASH(unichars[idx - 1])) {
582 return idx;
583 }
584 }
585 if ((2 < length) && HAS_DRIVE(unichars)) {
586 return 2;
587 }
588 return 0;
589}
590
591__private_extern__ CFIndex _CFLengthAfterDeletingLastPathComponent(UniChar *unichars, CFIndex length) {
592 CFIndex idx;
593 if (length < 2) {
594 return 0;
595 }
596 for (idx = length - 1; idx; idx--) {
597 if (IS_SLASH(unichars[idx - 1])) {
598 if ((idx != 1) && (!HAS_DRIVE(unichars) || idx != 3)) {
599 return idx - 1;
600 }
601 return idx;
602 }
603 }
604 if ((2 < length) && HAS_DRIVE(unichars)) {
605 return 2;
606 }
607 return 0;
608}
609
610__private_extern__ CFIndex _CFStartOfPathExtension(UniChar *unichars, CFIndex length) {
611 CFIndex idx;
612 if (length < 2) {
613 return 0;
614 }
615 for (idx = length - 1; idx; idx--) {
616 if (IS_SLASH(unichars[idx - 1])) {
617 return 0;
618 }
619 if (unichars[idx] != '.') {
620 continue;
621 }
622 if (idx == 2 && HAS_DRIVE(unichars)) {
623 return 0;
624 }
625 return idx;
626 }
627 return 0;
628}
629
630__private_extern__ CFIndex _CFLengthAfterDeletingPathExtension(UniChar *unichars, CFIndex length) {
631 CFIndex start = _CFStartOfPathExtension(unichars, length);
632 return ((0 < start) ? start : length);
633}
634
635#undef CF_OPENFLGS
636#undef UNIX_PATH_SEMANTICS
637#undef WINDOWS_PATH_SEMANTICS
638#undef HFS_PATH_SEMANTICS
639#undef CFPreferredSlash
640#undef HAS_DRIVE
641#undef HAS_NET
642#undef IS_SLASH
643