platform/unix.c
changeset 570 b331437b9ec0
parent 520 a72bbf255074
child 657 dad3b5c307a9
equal deleted inserted replaced
569:c83c96f2e1d9 570:b331437b9ec0
    25 #include <dirent.h>
    25 #include <dirent.h>
    26 #include <time.h>
    26 #include <time.h>
    27 #include <errno.h>
    27 #include <errno.h>
    28 #include <sys/mount.h>
    28 #include <sys/mount.h>
    29 
    29 
       
    30 #ifndef PHYSFS_DARWIN
       
    31 #  if defined(__MACH__) && defined(__APPLE__)
       
    32 #    define PHYSFS_DARWIN 1
       
    33 #    include <CoreFoundation/CoreFoundation.h>
       
    34 #    include <CoreServices/CoreServices.h>
       
    35 #    include <IOKit/IOKitLib.h>
       
    36 #    include <IOKit/storage/IOMedia.h>
       
    37 #    include <IOKit/storage/IOCDMedia.h>
       
    38 #    include <IOKit/storage/IODVDMedia.h>
       
    39 #  endif
       
    40 #endif
       
    41 
    30 #if (!defined PHYSFS_NO_PTHREADS_SUPPORT)
    42 #if (!defined PHYSFS_NO_PTHREADS_SUPPORT)
    31 #include <pthread.h>
    43 #include <pthread.h>
    32 #endif
    44 #endif
    33 
    45 
    34 #ifdef PHYSFS_HAVE_SYS_UCRED_H
    46 #ifdef PHYSFS_HAVE_SYS_UCRED_H
    70     BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
    82     BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
    71     *retval = NULL;
    83     *retval = NULL;
    72     return(retval);
    84     return(retval);
    73 } /* __PHYSFS_platformDetectAvailableCDs */
    85 } /* __PHYSFS_platformDetectAvailableCDs */
    74 
    86 
    75 #else
    87 
    76 
    88 #elif (defined PHYSFS_DARWIN)  /* "Big Nasty." */
    77 
    89 /*
    78 #ifdef PHYSFS_HAVE_SYS_UCRED_H
    90  * Code based on sample from Apple Developer Connection:
       
    91  *  http://developer.apple.com/samplecode/Sample_Code/Devices_and_Hardware/Disks/VolumeToBSDNode/VolumeToBSDNode.c.htm
       
    92  */
       
    93 
       
    94 static int darwinIsWholeMedia(io_service_t service)
       
    95 {
       
    96     int retval = 0;
       
    97     CFTypeRef wholeMedia;
       
    98 
       
    99     if (!IOObjectConformsTo(service, kIOMediaClass))
       
   100         return(0);
       
   101         
       
   102     wholeMedia = IORegistryEntryCreateCFProperty(service,
       
   103                                                  CFSTR(kIOMediaWholeKey),
       
   104                                                  kCFAllocatorDefault, 0);
       
   105     if (wholeMedia == NULL)
       
   106         return(0);
       
   107 
       
   108     retval = CFBooleanGetValue(wholeMedia);
       
   109     CFRelease(wholeMedia);
       
   110 
       
   111     return retval;
       
   112 } /* darwinIsWholeMedia */
       
   113 
       
   114 
       
   115 static int darwinIsMountedDisc(char *bsdName, mach_port_t masterPort)
       
   116 {
       
   117     int retval = 0;
       
   118     CFMutableDictionaryRef matchingDict;
       
   119     kern_return_t rc;
       
   120     io_iterator_t iter;
       
   121     io_service_t service;
       
   122 
       
   123     if ((matchingDict = IOBSDNameMatching(masterPort, 0, bsdName)) == NULL)
       
   124         return(0);
       
   125 
       
   126     rc = IOServiceGetMatchingServices(masterPort, matchingDict, &iter);
       
   127     if ((rc != KERN_SUCCESS) || (!iter))
       
   128         return(0);
       
   129 
       
   130     service = IOIteratorNext(iter);
       
   131     IOObjectRelease(iter);
       
   132     if (!service)
       
   133         return(0);
       
   134 
       
   135     rc = IORegistryEntryCreateIterator(service, kIOServicePlane,
       
   136              kIORegistryIterateRecursively | kIORegistryIterateParents, &iter);
       
   137     
       
   138     if (!iter)
       
   139         return(0);
       
   140 
       
   141     if (rc != KERN_SUCCESS)
       
   142     {
       
   143         IOObjectRelease(iter);
       
   144         return(0);
       
   145     } /* if */
       
   146 
       
   147     IOObjectRetain(service);  /* add an extra object reference... */
       
   148 
       
   149     do
       
   150     {
       
   151         if (darwinIsWholeMedia(service))
       
   152         {
       
   153             if ( (IOObjectConformsTo(service, kIOCDMediaClass)) ||
       
   154                  (IOObjectConformsTo(service, kIODVDMediaClass)) )
       
   155             {
       
   156                 retval = 1;
       
   157             } /* if */
       
   158         } /* if */
       
   159         IOObjectRelease(service);
       
   160     } while ((service = IOIteratorNext(iter)) && (!retval));
       
   161                 
       
   162     IOObjectRelease(iter);
       
   163     IOObjectRelease(service);
       
   164 
       
   165     return(retval);
       
   166 } /* darwinIsMountedDisc */
       
   167 
       
   168 
       
   169 char **__PHYSFS_platformDetectAvailableCDs(void)
       
   170 {
       
   171     const char *devPrefix = "/dev/";
       
   172     int prefixLen = strlen(devPrefix);
       
   173     mach_port_t masterPort = 0;
       
   174     char **retval = (char **) malloc(sizeof (char *));
       
   175     int cd_count = 1;  /* We count the NULL entry. */
       
   176     struct statfs *mntbufp;
       
   177     int i, mounts;
       
   178 
       
   179     retval[0] = NULL;
       
   180 
       
   181     if (IOMasterPort(MACH_PORT_NULL, &masterPort) != KERN_SUCCESS)
       
   182         return(retval);
       
   183 
       
   184     mounts = getmntinfo(&mntbufp, MNT_WAIT);  /* NOT THREAD SAFE! */
       
   185     for (i = 0; i < mounts; i++)
       
   186     {
       
   187         char *dev = mntbufp[i].f_mntfromname;
       
   188         char *mnt = mntbufp[i].f_mntonname;
       
   189         if (strncmp(dev, devPrefix, prefixLen) != 0)  /* a virtual device? */
       
   190             continue;
       
   191 
       
   192         dev += prefixLen;
       
   193         if (darwinIsMountedDisc(dev, masterPort))
       
   194         {
       
   195             char **tmp = realloc(retval, sizeof (char *) * (cd_count + 1));
       
   196             if (tmp)
       
   197             {
       
   198                 retval = tmp;
       
   199                 retval[cd_count - 1] = (char *) malloc(strlen(mnt) + 1);
       
   200                 if (retval[cd_count - 1])
       
   201                 {
       
   202                     strcpy(retval[cd_count - 1], mnt);
       
   203                     cd_count++;
       
   204                 } /* if */
       
   205             } /* if */
       
   206         } /* if */
       
   207     } /* for */
       
   208 
       
   209     retval[cd_count - 1] = NULL;
       
   210     return(retval);
       
   211 } /* __PHYSFS_platformDetectAvailableCDs */
       
   212 
       
   213 #elif (defined PHYSFS_HAVE_SYS_UCRED_H)
    79 
   214 
    80 char **__PHYSFS_platformDetectAvailableCDs(void)
   215 char **__PHYSFS_platformDetectAvailableCDs(void)
    81 {
   216 {
    82     char **retval = (char **) malloc(sizeof (char *));
   217     char **retval = (char **) malloc(sizeof (char *));
    83     int cd_count = 1;  /* We count the NULL entry. */
   218     int cd_count = 1;  /* We count the NULL entry. */
   119 
   254 
   120     retval[cd_count - 1] = NULL;
   255     retval[cd_count - 1] = NULL;
   121     return(retval);
   256     return(retval);
   122 } /* __PHYSFS_platformDetectAvailableCDs */
   257 } /* __PHYSFS_platformDetectAvailableCDs */
   123 
   258 
   124 #endif
   259 #elif (defined PHYSFS_HAVE_MNTENT_H)
   125 
       
   126 
       
   127 #ifdef PHYSFS_HAVE_MNTENT_H
       
   128 
   260 
   129 char **__PHYSFS_platformDetectAvailableCDs(void)
   261 char **__PHYSFS_platformDetectAvailableCDs(void)
   130 {
   262 {
   131     char **retval = (char **) malloc(sizeof (char *));
   263     char **retval = (char **) malloc(sizeof (char *));
   132     int cd_count = 1;  /* We count the NULL entry. */
   264     int cd_count = 1;  /* We count the NULL entry. */
   169     return(retval);
   301     return(retval);
   170 } /* __PHYSFS_platformDetectAvailableCDs */
   302 } /* __PHYSFS_platformDetectAvailableCDs */
   171 
   303 
   172 #endif
   304 #endif
   173 
   305 
   174 #endif  /* !PHYSFS_NO_CDROM_SUPPORT */
       
   175 
       
   176 
   306 
   177 /* this is in posix.c ... */
   307 /* this is in posix.c ... */
   178 extern char *__PHYSFS_platformCopyEnvironmentVariable(const char *varname);
   308 extern char *__PHYSFS_platformCopyEnvironmentVariable(const char *varname);
   179 
   309 
   180 
   310 
   264 {
   394 {
   265     usleep( 10 * 1000 );           /* don't care if it fails. */
   395     usleep( 10 * 1000 );           /* don't care if it fails. */
   266 } /* __PHYSFS_platformTimeslice */
   396 } /* __PHYSFS_platformTimeslice */
   267 
   397 
   268 
   398 
   269 #if defined(__MACH__) && defined(__APPLE__)
   399 #if PHYSFS_DARWIN
   270 /* 
   400 /* 
   271  * This function is only for OSX. The problem is that Apple's applications
   401  * This function is only for OSX. The problem is that Apple's applications
   272  * can actually be directory structures with the actual executable nested
   402  * can actually be directory structures with the actual executable nested
   273  * several levels down. PhysFS computes the base directory from the Unix
   403  * several levels down. PhysFS computes the base directory from the Unix
   274  * executable, but this may not be the correct directory. Apple tries to
   404  * executable, but this may not be the correct directory. Apple tries to
   312     char *found_ptr = NULL;
   442     char *found_ptr = NULL;
   313     char *tempbuf = NULL;
   443     char *tempbuf = NULL;
   314     int i;
   444     int i;
   315     
   445     
   316     /* Calloc will place the \0 character in the proper place for us */
   446     /* Calloc will place the \0 character in the proper place for us */
       
   447     /* !!! FIXME: Can we stack-allocate this? --ryan. */
   317     tempbuf = (char*)calloc( (strlen(path)+1), sizeof(char) );
   448     tempbuf = (char*)calloc( (strlen(path)+1), sizeof(char) );
   318     /* Unlike other Unix filesystems, HFS is case insensitive
   449     /* Unlike other Unix filesystems, HFS is case insensitive
   319      * It wouldn be nice to use strcasestr, but it doesn't seem
   450      * It wouldn be nice to use strcasestr, but it doesn't seem
   320      * to be available in the OSX gcc library right now.
   451      * to be available in the OSX gcc library right now.
   321      * So we should make a lower case copy of the path to 
   452      * So we should make a lower case copy of the path to