📄 unix.c
字号:
} /* if */ } /* while */ endmntent(mounts); retval[cd_count - 1] = NULL; return(retval);} /* __PHYSFS_platformDetectAvailableCDs */#endif/* this is in posix.c ... */extern char *__PHYSFS_platformCopyEnvironmentVariable(const char *varname);/* * See where program (bin) resides in the $PATH specified by (envr). * returns a copy of the first element in envr that contains it, or NULL * if it doesn't exist or there were other problems. PHYSFS_SetError() is * called if we have a problem. * * (envr) will be scribbled over, and you are expected to free() the * return value when you're done with it. */static char *findBinaryInPath(const char *bin, char *envr){ size_t alloc_size = 0; char *exe = NULL; char *start = envr; char *ptr; BAIL_IF_MACRO(bin == NULL, ERR_INVALID_ARGUMENT, NULL); BAIL_IF_MACRO(envr == NULL, ERR_INVALID_ARGUMENT, NULL); do { size_t size; ptr = strchr(start, ':'); /* find next $PATH separator. */ if (ptr) *ptr = '\0'; size = strlen(start) + strlen(bin) + 2; if (size > alloc_size) { char *x = (char *) realloc(exe, size); if (x == NULL) { if (exe != NULL) free(exe); BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL); } /* if */ alloc_size = size; exe = x; } /* if */ /* build full binary path... */ strcpy(exe, start); if ((exe[0] == '\0') || (exe[strlen(exe) - 1] != '/')) strcat(exe, "/"); strcat(exe, bin); if (access(exe, X_OK) == 0) /* Exists as executable? We're done. */ { strcpy(exe, start); /* i'm lazy. piss off. */ return(exe); } /* if */ start = ptr + 1; /* start points to beginning of next element. */ } while (ptr != NULL); if (exe != NULL) free(exe); return(NULL); /* doesn't exist in path. */} /* findBinaryInPath */char *__PHYSFS_platformCalcBaseDir(const char *argv0){ /* If there isn't a path on argv0, then look through the $PATH for it. */ char *retval; char *envr; if (strchr(argv0, '/') != NULL) /* default behaviour can handle this. */ return(NULL); envr = __PHYSFS_platformCopyEnvironmentVariable("PATH"); BAIL_IF_MACRO(!envr, NULL, NULL); retval = findBinaryInPath(argv0, envr); free(envr); return(retval);} /* __PHYSFS_platformCalcBaseDir *//* Much like my college days, try to sleep for 10 milliseconds at a time... */void __PHYSFS_platformTimeslice(void){ usleep( 10 * 1000 ); /* don't care if it fails. */} /* __PHYSFS_platformTimeslice */#if PHYSFS_DARWIN/* * 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; int i; /* Calloc will place the \0 character in the proper place for us */ /* !!! FIXME: Can we stack-allocate this? --ryan. */ tempbuf = (char*)calloc( (strlen(path)+1), sizeof(char) ); /* 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 */ 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'; } free(tempbuf); return;}#endif /* defined __MACH__ && defined __APPLE__ */char *__PHYSFS_platformRealPath(const char *path){ char resolved_path[MAXPATHLEN]; char *retval = NULL; errno = 0; BAIL_IF_MACRO(!realpath(path, resolved_path), strerror(errno), NULL); retval = (char *) malloc(strlen(resolved_path) + 1); BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL); strcpy(retval, resolved_path);#if defined(__MACH__) && defined(__APPLE__) stripAppleBundle(retval);#endif /* defined __MACH__ && defined __APPLE__ */ return(retval);} /* __PHYSFS_platformRealPath */#if (defined PHYSFS_NO_PTHREADS_SUPPORT)PHYSFS_uint64 __PHYSFS_platformGetThreadID(void) { return(0x0001); }void *__PHYSFS_platformCreateMutex(void) { return((void *) 0x0001); }void __PHYSFS_platformDestroyMutex(void *mutex) {}int __PHYSFS_platformGrabMutex(void *mutex) { return(1); }void __PHYSFS_platformReleaseMutex(void *mutex) {}#else/* Just in case; this is a panic value. */#if ((!defined SIZEOF_INT) || (SIZEOF_INT <= 0))# define SIZEOF_INT 4#endif#if (SIZEOF_INT == 4)# define PHTREAD_TO_UI64(thr) ( (PHYSFS_uint64) ((PHYSFS_uint32) (thr)) )#elif (SIZEOF_INT == 2)# define PHTREAD_TO_UI64(thr) ( (PHYSFS_uint64) ((PHYSFS_uint16) (thr)) )#elif (SIZEOF_INT == 1)# define PHTREAD_TO_UI64(thr) ( (PHYSFS_uint64) ((PHYSFS_uint8) (thr)) )#else# define PHTREAD_TO_UI64(thr) ((PHYSFS_uint64) (thr))#endifPHYSFS_uint64 __PHYSFS_platformGetThreadID(void){ return(PHTREAD_TO_UI64(pthread_self()));} /* __PHYSFS_platformGetThreadID */void *__PHYSFS_platformCreateMutex(void){ int rc; pthread_mutex_t *m = (pthread_mutex_t *) malloc(sizeof (pthread_mutex_t)); BAIL_IF_MACRO(m == NULL, ERR_OUT_OF_MEMORY, NULL); rc = pthread_mutex_init(m, NULL); if (rc != 0) { free(m); BAIL_MACRO(strerror(rc), NULL); } /* if */ return((void *) m);} /* __PHYSFS_platformCreateMutex */void __PHYSFS_platformDestroyMutex(void *mutex){ pthread_mutex_destroy((pthread_mutex_t *) mutex); free(mutex);} /* __PHYSFS_platformDestroyMutex */int __PHYSFS_platformGrabMutex(void *mutex){ return(pthread_mutex_lock((pthread_mutex_t *) mutex) == 0); } /* __PHYSFS_platformGrabMutex */void __PHYSFS_platformReleaseMutex(void *mutex){ pthread_mutex_unlock((pthread_mutex_t *) mutex);} /* __PHYSFS_platformReleaseMutex */#endif /* !PHYSFS_NO_PTHREADS_SUPPORT */#endif /* !defined __BEOS__ && !defined WIN32 *//* end of unix.c ... */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -