r859 - in trunk: . platform
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Wed Mar 21 01:03:17 EDT 2007
Author: icculus
Date: 2007-03-21 01:03:17 -0400 (Wed, 21 Mar 2007)
New Revision: 859
Added:
trunk/platform/macosx.c
Modified:
trunk/CMakeLists.txt
trunk/physfs_platforms.h
trunk/platform/beos.cpp
trunk/platform/posix.c
trunk/platform/unix.c
Log:
Split out Mac OS X code from unix.c and added some Carbon-specific code...
moved some stuff around and implemented a few things in BeOS and POSIX bits
to accomodate this.
Modified: trunk/CMakeLists.txt
===================================================================
--- trunk/CMakeLists.txt 2007-03-21 04:31:13 UTC (rev 858)
+++ trunk/CMakeLists.txt 2007-03-21 05:03:17 UTC (rev 859)
@@ -117,6 +117,7 @@
platform/pocketpc.c
platform/posix.c
platform/unix.c
+ platform/macosx.c
platform/windows.c
archivers/dir.c
archivers/grp.c
Modified: trunk/physfs_platforms.h
===================================================================
--- trunk/physfs_platforms.h 2007-03-21 04:31:13 UTC (rev 858)
+++ trunk/physfs_platforms.h 2007-03-21 05:03:17 UTC (rev 859)
@@ -23,7 +23,6 @@
# define PHYSFS_PLATFORM_OS2
#elif ((defined __MACH__) && (defined __APPLE__))
# define PHYSFS_PLATFORM_MACOSX
-# define PHYSFS_PLATFORM_UNIX
# define PHYSFS_PLATFORM_POSIX
#elif defined(macintosh)
# error Classic Mac OS support was dropped from PhysicsFS 2.0. Move to OS X.
Modified: trunk/platform/beos.cpp
===================================================================
--- trunk/platform/beos.cpp 2007-03-21 04:31:13 UTC (rev 858)
+++ trunk/platform/beos.cpp 2007-03-21 05:03:17 UTC (rev 859)
@@ -30,9 +30,6 @@
#include "physfs_internal.h"
-const char *__PHYSFS_platformDirSeparator = "/";
-
-
int __PHYSFS_platformInit(void)
{
return(1); /* always succeed. */
@@ -158,7 +155,7 @@
thread_id tid = find_thread(NULL);
get_thread_info(tid, &info);
return(info.team);
-} /* getMyTeamID */
+} /* getTeamID */
char *__PHYSFS_platformCalcBaseDir(const char *argv0)
@@ -201,6 +198,12 @@
} /* __PHYSFS_platformRealPath */
+char *__PHYSFS_platformCurrentDir(void)
+{
+ return(__PHYSFS_platformRealPath(".")); /* let BPath sort it out. */
+} /* __PHYSFS_platformCurrentDir */
+
+
/* !!! FIXME: semaphores are not mutexes... */
void *__PHYSFS_platformCreateMutex(void)
{
Added: trunk/platform/macosx.c
===================================================================
--- trunk/platform/macosx.c (rev 0)
+++ trunk/platform/macosx.c 2007-03-21 05:03:17 UTC (rev 859)
@@ -0,0 +1,396 @@
+/*
+ * Mac OS X support routines for PhysicsFS.
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ *
+ * This file written by Ryan C. Gordon.
+ */
+
+#define __PHYSICSFS_INTERNAL__
+#include "physfs_platforms.h"
+
+#ifdef PHYSFS_PLATFORM_MACOSX
+
+#include <Carbon/Carbon.h>
+#include <IOKit/storage/IOMedia.h>
+#include <IOKit/storage/IOCDMedia.h>
+#include <IOKit/storage/IODVDMedia.h>
+#include <sys/mount.h>
+
+/* Seems to get defined in some system header... */
+#ifdef Free
+#undef Free
+#endif
+
+#include "physfs_internal.h"
+
+
+/* Wrap PHYSFS_Allocator in a CFAllocator... */
+static CFAllocatorRef cfallocator = NULL;
+
+CFStringRef cfallocDesc(const void *info)
+{
+ return(CFStringCreateWithCString(cfallocator, "PhysicsFS",
+ kCFStringEncodingASCII));
+} /* cfallocDesc */
+
+
+static void *cfallocMalloc(CFIndex allocSize, CFOptionFlags hint, void *info)
+{
+ return allocator.Malloc(allocSize);
+} /* cfallocMalloc */
+
+
+static void cfallocFree(void *ptr, void *info)
+{
+ allocator.Free(ptr);
+} /* cfallocFree */
+
+
+static void *cfallocRealloc(void *ptr, CFIndex newsize,
+ CFOptionFlags hint, void *info)
+{
+ if ((ptr == NULL) || (newsize <= 0))
+ return NULL; /* ADC docs say you should always return NULL here. */
+ return allocator.Realloc(ptr, newsize);
+} /* cfallocRealloc */
+
+
+int __PHYSFS_platformInit(void)
+{
+ /* set up a CFAllocator, so Carbon can use the physfs allocator, too. */
+ CFAllocatorContext ctx;
+ memset(&ctx, '\0', sizeof (ctx));
+ ctx.copyDescription = cfallocDesc;
+ ctx.allocate = cfallocMalloc;
+ ctx.reallocate = cfallocRealloc;
+ ctx.deallocate = cfallocFree;
+ cfallocator = CFAllocatorCreate(kCFAllocatorUseContext, &ctx);
+ BAIL_IF_MACRO(cfallocator == NULL, ERR_OUT_OF_MEMORY, 0);
+ return(1); /* success. */
+} /* __PHYSFS_platformInit */
+
+
+int __PHYSFS_platformDeinit(void)
+{
+ CFRelease(cfallocator);
+ cfallocator = NULL;
+ return(1); /* always succeed. */
+} /* __PHYSFS_platformDeinit */
+
+
+/* CD-ROM detection code... */
+
+/*
+ * Code based on sample from Apple Developer Connection:
+ * http://developer.apple.com/samplecode/Sample_Code/Devices_and_Hardware/Disks/VolumeToBSDNode/VolumeToBSDNode.c.htm
+ */
+
+static int darwinIsWholeMedia(io_service_t service)
+{
+ int retval = 0;
+ CFTypeRef wholeMedia;
+
+ if (!IOObjectConformsTo(service, kIOMediaClass))
+ return(0);
+
+ wholeMedia = IORegistryEntryCreateCFProperty(service,
+ CFSTR(kIOMediaWholeKey),
+ cfallocator, 0);
+ if (wholeMedia == NULL)
+ return(0);
+
+ retval = CFBooleanGetValue(wholeMedia);
+ CFRelease(wholeMedia);
+
+ return retval;
+} /* darwinIsWholeMedia */
+
+
+static int darwinIsMountedDisc(char *bsdName, mach_port_t masterPort)
+{
+ int retval = 0;
+ CFMutableDictionaryRef matchingDict;
+ kern_return_t rc;
+ io_iterator_t iter;
+ io_service_t service;
+
+ if ((matchingDict = IOBSDNameMatching(masterPort, 0, bsdName)) == NULL)
+ return(0);
+
+ rc = IOServiceGetMatchingServices(masterPort, matchingDict, &iter);
+ if ((rc != KERN_SUCCESS) || (!iter))
+ return(0);
+
+ service = IOIteratorNext(iter);
+ IOObjectRelease(iter);
+ if (!service)
+ return(0);
+
+ rc = IORegistryEntryCreateIterator(service, kIOServicePlane,
+ kIORegistryIterateRecursively | kIORegistryIterateParents, &iter);
+
+ if (!iter)
+ return(0);
+
+ if (rc != KERN_SUCCESS)
+ {
+ IOObjectRelease(iter);
+ return(0);
+ } /* if */
+
+ IOObjectRetain(service); /* add an extra object reference... */
+
+ do
+ {
+ if (darwinIsWholeMedia(service))
+ {
+ if ( (IOObjectConformsTo(service, kIOCDMediaClass)) ||
+ (IOObjectConformsTo(service, kIODVDMediaClass)) )
+ {
+ retval = 1;
+ } /* if */
+ } /* if */
+ IOObjectRelease(service);
+ } while ((service = IOIteratorNext(iter)) && (!retval));
+
+ IOObjectRelease(iter);
+ IOObjectRelease(service);
+
+ return(retval);
+} /* darwinIsMountedDisc */
+
+
+void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
+{
+ const char *devPrefix = "/dev/";
+ const int prefixLen = strlen(devPrefix);
+ mach_port_t masterPort = 0;
+ struct statfs *mntbufp;
+ int i, mounts;
+
+ if (IOMasterPort(MACH_PORT_NULL, &masterPort) != KERN_SUCCESS)
+ BAIL_MACRO(ERR_OS_ERROR, /*return void*/);
+
+ mounts = getmntinfo(&mntbufp, MNT_WAIT); /* NOT THREAD SAFE! */
+ for (i = 0; i < mounts; i++)
+ {
+ char *dev = mntbufp[i].f_mntfromname;
+ char *mnt = mntbufp[i].f_mntonname;
+ if (strncmp(dev, devPrefix, prefixLen) != 0) /* a virtual device? */
+ continue;
+
+ dev += prefixLen;
+ if (darwinIsMountedDisc(dev, masterPort))
+ cb(data, mnt);
+ } /* for */
+} /* __PHYSFS_platformDetectAvailableCDs */
+
+
+static char *convertCFString(CFStringRef cfstr)
+{
+ CFIndex len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstr),
+ kCFStringEncodingUTF8) + 1;
+ char *retval = (char *) allocator.Malloc(len);
+ BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
+
+ if (CFStringGetCString(cfstr, retval, len, kCFStringEncodingUTF8))
+ {
+ /* shrink overallocated buffer if possible... */
+ CFIndex newlen = strlen(retval) + 1;
+ if (newlen < len)
+ {
+ void *ptr = allocator.Realloc(retval, newlen);
+ if (ptr != NULL)
+ retval = (char *) ptr;
+ } /* if */
+ } /* if */
+
+ else /* probably shouldn't fail, but just in case... */
+ {
+ allocator.Free(retval);
+ BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
+ } /* else */
+
+ return(retval);
+} /* convertCFString */
+
+
+char *__PHYSFS_platformCalcBaseDir(const char *argv0)
+{
+ ProcessSerialNumber psn = { 0, kCurrentProcess };
+ FSRef fsref;
+ CFRange cfrange;
+ CFURLRef cfurl = NULL;
+ CFStringRef cfstr = NULL;
+ CFMutableStringRef cfmutstr = NULL;
+ char *retval = NULL;
+
+ BAIL_IF_MACRO(GetProcessBundleLocation(&psn, &fsref) != noErr, NULL, NULL);
+ cfurl = CFURLCreateFromFSRef(cfallocator, &fsref);
+ BAIL_IF_MACRO(cfurl == NULL, NULL, NULL);
+ cfstr = CFURLCopyFileSystemPath(cfurl, kCFURLPOSIXPathStyle);
+ CFRelease(cfurl);
+ BAIL_IF_MACRO(cfstr == NULL, NULL, NULL);
+ cfmutstr = CFStringCreateMutableCopy(cfallocator, 0, cfstr);
+ CFRelease(cfstr);
+ BAIL_IF_MACRO(cfmutstr == NULL, NULL, NULL);
+
+ /* Find last dirsep so we can chop the binary's filename from the path. */
+ cfrange = CFStringFind(cfmutstr, CFSTR("/"), kCFCompareBackwards);
+ if (cfrange.location == kCFNotFound)
+ {
+ assert(0); /* shouldn't ever hit this... */
+ CFRelease(cfmutstr);
+ return(NULL);
+ } /* if */
+
+ /* chop the "/exename" from the end of the path string... */
+ cfrange.length = CFStringGetLength(cfmutstr) - cfrange.location;
+ CFStringDelete(cfmutstr, cfrange);
+
+ /* If we're an Application Bundle, chop everything but the base. */
+ cfrange = CFStringFind(cfmutstr, CFSTR("/Contents/MacOS"),
+ kCFCompareCaseInsensitive |
+ kCFCompareBackwards |
+ kCFCompareAnchored);
+
+ if (cfrange.location != kCFNotFound)
+ CFStringDelete(cfmutstr, cfrange); /* chop that, too. */
+
+ retval = convertCFString(cfmutstr);
+ CFRelease(cfmutstr);
+
+ return(retval); /* whew. */
+} /* __PHYSFS_platformCalcBaseDir */
+
+
+/* !!! FIXME */
+#define osxerr(x) x
+
+char *__PHYSFS_platformRealPath(const char *path)
+{
+ /* The symlink and relative path resolving happens in FSPathMakeRef() */
+ FSRef fsref;
+ CFURLRef cfurl = NULL;
+ CFStringRef cfstr = NULL;
+ char *retval = NULL;
+ OSStatus rc = osxerr(FSPathMakeRef((UInt8 *) path, &fsref, NULL));
+ BAIL_IF_MACRO(rc != noErr, NULL, NULL);
+
+ /* Now get it to spit out a full path. */
+ cfurl = CFURLCreateFromFSRef(cfallocator, &fsref);
+ BAIL_IF_MACRO(cfurl == NULL, ERR_OUT_OF_MEMORY, NULL);
+ cfstr = CFURLCopyFileSystemPath(cfurl, kCFURLPOSIXPathStyle);
+ CFRelease(cfurl);
+ BAIL_IF_MACRO(cfstr == NULL, ERR_OUT_OF_MEMORY, NULL);
+ retval = convertCFString(cfstr);
+ CFRelease(cfstr);
+
+ return(retval);
+} /* __PHYSFS_platformRealPath */
+
+
+char *__PHYSFS_platformCurrentDir(void)
+{
+ return(__PHYSFS_platformRealPath(".")); /* let CFURL sort it out. */
+} /* __PHYSFS_platformCurrentDir */
+
+
+/* Platform allocator uses default CFAllocator at PHYSFS_init() time. */
+
+static CFAllocatorRef cfallocdef = NULL;
+
+static int macosxAllocatorInit(void)
+{
+ int retval = 0;
+ cfallocdef = CFAllocatorGetDefault();
+ retval = (cfallocdef != NULL);
+ if (retval)
+ CFRetain(cfallocdef);
+ return(retval);
+} /* macosxAllocatorInit */
+
+
+static void macosxAllocatorDeinit(void)
+{
+ if (cfallocdef != NULL)
+ {
+ CFRelease(cfallocdef);
+ cfallocdef = NULL;
+ } /* if */
+} /* macosxAllocatorDeinit */
+
+
+static void *macosxAllocatorMalloc(PHYSFS_uint64 s)
+{
+ BAIL_IF_MACRO(__PHYSFS_ui64FitsAddressSpace(s), ERR_OUT_OF_MEMORY, NULL);
+ return(CFAllocatorAllocate(cfallocdef, (CFIndex) s, 0));
+} /* macosxAllocatorMalloc */
+
+
+static void *macosxAllocatorRealloc(void *ptr, PHYSFS_uint64 s)
+{
+ BAIL_IF_MACRO(__PHYSFS_ui64FitsAddressSpace(s), ERR_OUT_OF_MEMORY, NULL);
+ return(CFAllocatorReallocate(cfallocdef, ptr, (CFIndex) s, 0));
+} /* macosxAllocatorRealloc */
+
+
+static void macosxAllocatorFree(void *ptr)
+{
+ CFAllocatorDeallocate(cfallocdef, ptr);
+} /* macosxAllocatorFree */
+
+
+int __PHYSFS_platformSetDefaultAllocator(PHYSFS_Allocator *a)
+{
+ allocator.Init = macosxAllocatorInit;
+ allocator.Deinit = macosxAllocatorDeinit;
+ allocator.Malloc = macosxAllocatorMalloc;
+ allocator.Realloc = macosxAllocatorRealloc;
+ allocator.Free = macosxAllocatorFree;
+ return(1); /* return non-zero: we're supplying custom allocator. */
+} /* __PHYSFS_platformSetDefaultAllocator */
+
+
+PHYSFS_uint64 __PHYSFS_platformGetThreadID(void)
+{
+ return( (PHYSFS_uint64) ((size_t) MPCurrentTaskID()) );
+} /* __PHYSFS_platformGetThreadID */
+
+
+void *__PHYSFS_platformCreateMutex(void)
+{
+ MPCriticalRegionID m = NULL;
+ if (osxerr(MPCreateCriticalRegion(&m)) != noErr)
+ return NULL;
+ return m;
+} /* __PHYSFS_platformCreateMutex */
+
+
+void __PHYSFS_platformDestroyMutex(void *mutex)
+{
+ MPCriticalRegionID m = (MPCriticalRegionID) mutex;
+ MPDeleteCriticalRegion(m);
+} /* __PHYSFS_platformDestroyMutex */
+
+
+int __PHYSFS_platformGrabMutex(void *mutex)
+{
+ MPCriticalRegionID m = (MPCriticalRegionID) mutex;
+ if (MPEnterCriticalRegion(m, kDurationForever) != noErr)
+ return(0);
+ return(1);
+} /* __PHYSFS_platformGrabMutex */
+
+
+void __PHYSFS_platformReleaseMutex(void *mutex)
+{
+ MPCriticalRegionID m = (MPCriticalRegionID) mutex;
+ MPExitCriticalRegion(m);
+} /* __PHYSFS_platformReleaseMutex */
+
+#endif /* PHYSFS_PLATFORM_MACOSX */
+
+/* end of macosx.c ... */
+
Modified: trunk/platform/posix.c
===================================================================
--- trunk/platform/posix.c 2007-03-21 04:31:13 UTC (rev 858)
+++ trunk/platform/posix.c 2007-03-21 05:03:17 UTC (rev 859)
@@ -30,6 +30,9 @@
#include "physfs_internal.h"
+const char *__PHYSFS_platformDirSeparator = "/";
+
+
char *__PHYSFS_platformCopyEnvironmentVariable(const char *varname)
{
const char *envr = getenv(varname);
@@ -224,43 +227,6 @@
} /* __PHYSFS_platformEnumerateFiles */
-char *__PHYSFS_platformCurrentDir(void)
-{
- int allocSize = 0;
- char *retval = NULL;
- char *ptr;
-
- do
- {
- allocSize += 100;
- ptr = (char *) allocator.Realloc(retval, allocSize);
- if (ptr == NULL)
- {
- if (retval != NULL)
- allocator.Free(retval);
- BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
- } /* if */
-
- retval = ptr;
- ptr = getcwd(retval, allocSize);
- } while (ptr == NULL && errno == ERANGE);
-
- if (ptr == NULL && errno)
- {
- /*
- * getcwd() failed for some reason, for example current
- * directory not existing.
- */
- if (retval != NULL)
- allocator.Free(retval);
- BAIL_MACRO(ERR_NO_SUCH_FILE, NULL);
- } /* if */
-
- return(retval);
-} /* __PHYSFS_platformCurrentDir */
-
-
-
int __PHYSFS_platformMkDir(const char *path)
{
int rc;
Modified: trunk/platform/unix.c
===================================================================
--- trunk/platform/unix.c 2007-03-21 04:31:13 UTC (rev 858)
+++ trunk/platform/unix.c 2007-03-21 05:03:17 UTC (rev 859)
@@ -25,15 +25,6 @@
#include <errno.h>
#include <sys/mount.h>
-#ifdef PHYSFS_PLATFORM_MACOSX
-# include <CoreFoundation/CoreFoundation.h>
-# include <CoreServices/CoreServices.h>
-# include <IOKit/IOKitLib.h>
-# include <IOKit/storage/IOMedia.h>
-# include <IOKit/storage/IOCDMedia.h>
-# include <IOKit/storage/IODVDMedia.h>
-#endif
-
#if (!defined PHYSFS_NO_PTHREADS_SUPPORT)
#include <pthread.h>
#endif
@@ -51,14 +42,7 @@
#include "physfs_internal.h"
-/* Seems to get defined in some system header... */
-#ifdef Free
-#undef Free
-#endif
-const char *__PHYSFS_platformDirSeparator = "/";
-
-
int __PHYSFS_platformInit(void)
{
return(1); /* always succeed. */
@@ -78,113 +62,6 @@
{
} /* __PHYSFS_platformDetectAvailableCDs */
-
-#elif (defined PHYSFS_PLATFORM_MACOSX) /* "Big Nasty." */
-/*
- * Code based on sample from Apple Developer Connection:
- * http://developer.apple.com/samplecode/Sample_Code/Devices_and_Hardware/Disks/VolumeToBSDNode/VolumeToBSDNode.c.htm
- */
-
-static int darwinIsWholeMedia(io_service_t service)
-{
- int retval = 0;
- CFTypeRef wholeMedia;
-
- if (!IOObjectConformsTo(service, kIOMediaClass))
- return(0);
-
- wholeMedia = IORegistryEntryCreateCFProperty(service,
- CFSTR(kIOMediaWholeKey),
- kCFAllocatorDefault, 0);
- if (wholeMedia == NULL)
- return(0);
-
- retval = CFBooleanGetValue(wholeMedia);
- CFRelease(wholeMedia);
-
- return retval;
-} /* darwinIsWholeMedia */
-
-
-static int darwinIsMountedDisc(char *bsdName, mach_port_t masterPort)
-{
- int retval = 0;
- CFMutableDictionaryRef matchingDict;
- kern_return_t rc;
- io_iterator_t iter;
- io_service_t service;
-
- if ((matchingDict = IOBSDNameMatching(masterPort, 0, bsdName)) == NULL)
- return(0);
-
- rc = IOServiceGetMatchingServices(masterPort, matchingDict, &iter);
- if ((rc != KERN_SUCCESS) || (!iter))
- return(0);
-
- service = IOIteratorNext(iter);
- IOObjectRelease(iter);
- if (!service)
- return(0);
-
- rc = IORegistryEntryCreateIterator(service, kIOServicePlane,
- kIORegistryIterateRecursively | kIORegistryIterateParents, &iter);
-
- if (!iter)
- return(0);
-
- if (rc != KERN_SUCCESS)
- {
- IOObjectRelease(iter);
- return(0);
- } /* if */
-
- IOObjectRetain(service); /* add an extra object reference... */
-
- do
- {
- if (darwinIsWholeMedia(service))
- {
- if ( (IOObjectConformsTo(service, kIOCDMediaClass)) ||
- (IOObjectConformsTo(service, kIODVDMediaClass)) )
- {
- retval = 1;
- } /* if */
- } /* if */
- IOObjectRelease(service);
- } while ((service = IOIteratorNext(iter)) && (!retval));
-
- IOObjectRelease(iter);
- IOObjectRelease(service);
-
- return(retval);
-} /* darwinIsMountedDisc */
-
-
-void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
-{
- const char *devPrefix = "/dev/";
- int prefixLen = strlen(devPrefix);
- mach_port_t masterPort = 0;
- struct statfs *mntbufp;
- int i, mounts;
-
- if (IOMasterPort(MACH_PORT_NULL, &masterPort) != KERN_SUCCESS)
- BAIL_MACRO(ERR_OS_ERROR, /*return void*/);
-
- mounts = getmntinfo(&mntbufp, MNT_WAIT); /* NOT THREAD SAFE! */
- for (i = 0; i < mounts; i++)
- {
- char *dev = mntbufp[i].f_mntfromname;
- char *mnt = mntbufp[i].f_mntonname;
- if (strncmp(dev, devPrefix, prefixLen) != 0) /* a virtual device? */
- continue;
-
- dev += prefixLen;
- if (darwinIsMountedDisc(dev, masterPort))
- cb(data, mnt);
- } /* for */
-} /* __PHYSFS_platformDetectAvailableCDs */
-
#elif (defined PHYSFS_HAVE_SYS_UCRED_H)
void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
@@ -350,107 +227,6 @@
} /* __PHYSFS_platformCalcBaseDir */
-#ifdef PHYSFS_PLATFORM_MACOSX
-/*
- * This function is only for OSX. The problem is that Apple's applications
- * can actually be directory structures with the actual executable nested
- * several levels down. PhysFS computes the base directory from the Unix
- * executable, but this may not be the correct directory. Apple tries to
- * hide everything from the user, so from Finder, the user never sees the
- * Unix executable, and the directory package (bundle) is considered the
- * "executable". This means that the correct base directory is at the
- * level where the directory structure starts.
- * A typical bundle seems to look like this:
- * MyApp.app/ <-- top level...this is what the user sees in Finder
- * Contents/
- * MacOS/
- * MyApp <-- the actual executable
- *
- * Since anything below the app folder is considered hidden, most
- * application files need to be at the top level if you intend to
- * write portable software. Thus if the application resides in:
- * /Applications/MyProgram
- * and the executable is the bundle MyApp.app,
- * PhysFS computes the following as the base directory:
- * /Applications/MyProgram/MyApp.app/Contents/MacOS/
- * We need to strip off the MyApp.app/Contents/MacOS/
- *
- * However, there are corner cases. OSX applications can be traditional
- * Unix executables without the bundle. Also, it is not entirely clear
- * to me what kinds of permutations bundle structures can have.
- *
- * For now, this is a temporary hack until a better solution
- * can be made. This function will try to find a "/Contents/MacOS"
- * inside the path. If it succeeds, then the path will be truncated
- * to correct the directory. If it is not found, the path will be
- * left alone and will presume it is a traditional Unix execuatable.
- * Most programs also include the .app extention in the top level
- * folder, but it doesn't seem to be a requirement (Acrobat doesn't
- * have it). MacOS looks like it can also be MacOSClassic.
- * This function will test for MacOS and hope it captures any
- * other permutations.
- */
-static void stripAppleBundle(char *path)
-{
- char *sub_str = "/contents/macos";
- char *found_ptr = NULL;
- char *tempbuf = NULL;
- size_t len = strlen(path) + 1;
- int i;
-
- /* !!! FIXME: Can we stack-allocate this? --ryan. */
- tempbuf = (char *) allocator.Malloc(len);
- if (!tempbuf) return;
- memset(tempbuf, '\0', len);
-
- /* Unlike other Unix filesystems, HFS is case insensitive
- * It wouldn be nice to use strcasestr, but it doesn't seem
- * to be available in the OSX gcc library right now.
- * So we should make a lower case copy of the path to
- * compare against
- */
- for(i=0; i<strlen(path); i++)
- {
- /* convert to lower case */
- tempbuf[i] = tolower(path[i]);
- }
- /* See if we can find "/contents/macos" in the path */
- found_ptr = strstr(tempbuf, sub_str);
- if(NULL == found_ptr)
- {
- /* It doesn't look like a bundle so we can keep the
- * original path. Just return */
- allocator.Free(tempbuf);
- return;
- }
- /* We have a bundle, so let's backstep character by character
- * to erase the extra parts of the path. Quit when we hit
- * the preceding '/' character.
- */
- for(i=strlen(path)-strlen(found_ptr)-1; i>=0; i--)
- {
- if('/' == path[i])
- {
- break;
- }
- }
- /* Safety check */
- if(i<1)
- {
- /* This probably shouldn't happen. */
- path[0] = '\0';
- }
- else
- {
- /* Back up one more to remove trailing '/' and set the '\0' */
- path[i] = '\0';
- }
- allocator.Free(tempbuf);
- return;
-}
-#endif
-
-
char *__PHYSFS_platformRealPath(const char *path)
{
char resolved_path[MAXPATHLEN];
@@ -462,15 +238,51 @@
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
strcpy(retval, resolved_path);
-/* !!! FIXME: this shouldn't be here. */
-#ifdef PHYSFS_PLATFORM_MACOSX
- stripAppleBundle(retval);
-#endif
-
return(retval);
} /* __PHYSFS_platformRealPath */
+char *__PHYSFS_platformCurrentDir(void)
+{
+ /*
+ * This can't just do platformRealPath("."), since that would eventually
+ * just end up calling back into here.
+ */
+
+ int allocSize = 0;
+ char *retval = NULL;
+ char *ptr;
+
+ do
+ {
+ allocSize += 100;
+ ptr = (char *) allocator.Realloc(retval, allocSize);
+ if (ptr == NULL)
+ {
+ if (retval != NULL)
+ allocator.Free(retval);
+ BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
+ } /* if */
+
+ retval = ptr;
+ ptr = getcwd(retval, allocSize);
+ } while (ptr == NULL && errno == ERANGE);
+
+ if (ptr == NULL && errno)
+ {
+ /*
+ * getcwd() failed for some reason, for example current
+ * directory not existing.
+ */
+ if (retval != NULL)
+ allocator.Free(retval);
+ BAIL_MACRO(ERR_NO_SUCH_FILE, NULL);
+ } /* if */
+
+ return(retval);
+} /* __PHYSFS_platformCurrentDir */
+
+
int __PHYSFS_platformSetDefaultAllocator(PHYSFS_Allocator *a)
{
return(0); /* just use malloc() and friends. */
More information about the physfs-commits
mailing list