📄 unix.c
字号:
/* * Unix support routines for PhysicsFS. * * Please see the file LICENSE in the source's root directory. * * This file written by Ryan C. Gordon. */#if HAVE_CONFIG_H# include <config.h>#endif/* BeOS uses beos.cpp and posix.c ... Cygwin and such use win32.c ... */#if ((!defined __BEOS__) && (!defined WIN32))#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <unistd.h>#include <sys/types.h>#include <pwd.h>#include <sys/stat.h>#include <sys/param.h>#include <dirent.h>#include <time.h>#include <errno.h>#include <sys/mount.h>#ifndef PHYSFS_DARWIN# if defined(__MACH__) && defined(__APPLE__)# define PHYSFS_DARWIN 1# 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#endif#if (!defined PHYSFS_NO_PTHREADS_SUPPORT)#include <pthread.h>#endif#ifdef PHYSFS_HAVE_SYS_UCRED_H# ifdef PHYSFS_HAVE_MNTENT_H# undef PHYSFS_HAVE_MNTENT_H /* don't do both... */# endif# include <sys/ucred.h>#endif#ifdef PHYSFS_HAVE_MNTENT_H#include <mntent.h>#endif#define __PHYSICSFS_INTERNAL__#include "physfs_internal.h"const char *__PHYSFS_platformDirSeparator = "/";int __PHYSFS_platformInit(void){ return(1); /* always succeed. */} /* __PHYSFS_platformInit */int __PHYSFS_platformDeinit(void){ return(1); /* always succeed. */} /* __PHYSFS_platformDeinit */#ifdef PHYSFS_NO_CDROM_SUPPORT/* Stub version for platforms without CD-ROM support. */char **__PHYSFS_platformDetectAvailableCDs(void){ char **retval = (char **) malloc(sizeof (char *)); BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL); *retval = NULL; return(retval);} /* __PHYSFS_platformDetectAvailableCDs */#elif (defined PHYSFS_DARWIN) /* "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 */char **__PHYSFS_platformDetectAvailableCDs(void){ const char *devPrefix = "/dev/"; int prefixLen = strlen(devPrefix); mach_port_t masterPort = 0; char **retval = (char **) malloc(sizeof (char *)); int cd_count = 1; /* We count the NULL entry. */ struct statfs *mntbufp; int i, mounts; retval[0] = NULL; if (IOMasterPort(MACH_PORT_NULL, &masterPort) != KERN_SUCCESS) return(retval); 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)) { char **tmp = realloc(retval, sizeof (char *) * (cd_count + 1)); if (tmp) { retval = tmp; retval[cd_count - 1] = (char *) malloc(strlen(mnt) + 1); if (retval[cd_count - 1]) { strcpy(retval[cd_count - 1], mnt); cd_count++; } /* if */ } /* if */ } /* if */ } /* for */ retval[cd_count - 1] = NULL; return(retval);} /* __PHYSFS_platformDetectAvailableCDs */#elif (defined PHYSFS_HAVE_SYS_UCRED_H)char **__PHYSFS_platformDetectAvailableCDs(void){ char **retval = (char **) malloc(sizeof (char *)); int cd_count = 1; /* We count the NULL entry. */ struct statfs *mntbufp = NULL; int mounts; int i; BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL); mounts = getmntinfo(&mntbufp, MNT_WAIT); for (i = 0; i < mounts; i++) { int add_it = 0; if (strcmp(mntbufp[i].f_fstypename, "iso9660") == 0) add_it = 1; else if (strcmp( mntbufp[i].f_fstypename, "cd9660") == 0) add_it = 1; /* add other mount types here */ if (add_it) { char **tmp = realloc(retval, sizeof (char *) * (cd_count + 1)); if (tmp) { retval = tmp; retval[cd_count - 1] = (char *) malloc(strlen(mntbufp[i].f_mntonname) + 1); if (retval[cd_count - 1]) { strcpy(retval[cd_count - 1], mntbufp[i].f_mntonname); cd_count++; } /* if */ } /* if */ } /* if */ } /* for */ retval[cd_count - 1] = NULL; return(retval);} /* __PHYSFS_platformDetectAvailableCDs */#elif (defined PHYSFS_HAVE_MNTENT_H)char **__PHYSFS_platformDetectAvailableCDs(void){ char **retval = (char **) malloc(sizeof (char *)); int cd_count = 1; /* We count the NULL entry. */ FILE *mounts = NULL; struct mntent *ent = NULL; BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL); *retval = NULL; mounts = setmntent("/etc/mtab", "r"); BAIL_IF_MACRO(mounts == NULL, ERR_IO_ERROR, retval); while ( (ent = getmntent(mounts)) != NULL ) { int add_it = 0; if (strcmp(ent->mnt_type, "iso9660") == 0) add_it = 1; /* add other mount types here */ if (add_it) { char **tmp = realloc(retval, sizeof (char *) * (cd_count + 1)); if (tmp) { retval = tmp; retval[cd_count-1] = (char *) malloc(strlen(ent->mnt_dir) + 1); if (retval[cd_count - 1]) { strcpy(retval[cd_count - 1], ent->mnt_dir); cd_count++; } /* if */ } /* if */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -