cfcd27d35d
Reviewed-by: Steve Marquess <marquess@openssl.org>
93 lines
2.2 KiB
Objective-C
93 lines
2.2 KiB
Objective-C
#include <stdio.h>
|
|
#include <dlfcn.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
#include <Foundation/Foundation.h>
|
|
|
|
static FILE *(*libc_fopen)(const char *, const char *) = NULL;
|
|
|
|
__attribute__((constructor))
|
|
static void pre_main(void)
|
|
{
|
|
/*
|
|
* Pull reference to fopen(3) from libc.
|
|
*/
|
|
void *handle = dlopen("libSystem.B.dylib",RTLD_LAZY);
|
|
|
|
if (handle) {
|
|
libc_fopen = dlsym(handle,"fopen");
|
|
dlclose(handle);
|
|
}
|
|
|
|
/*
|
|
* Change to Documents directory.
|
|
*/
|
|
NSString *docs = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
|
|
|
|
NSFileManager *filemgr = [NSFileManager defaultManager];
|
|
[filemgr changeCurrentDirectoryPath: docs];
|
|
[filemgr release];
|
|
}
|
|
|
|
char *mkdirhier(char *path)
|
|
{
|
|
char *slash;
|
|
struct stat buf;
|
|
|
|
if (path[0]=='.' && path[1]=='/') path+=2;
|
|
|
|
if ((slash = strrchr(path,'/'))) {
|
|
*slash = '\0';
|
|
if (stat(path,&buf)==0) {
|
|
*slash = '/';
|
|
return NULL;
|
|
}
|
|
(void)mkdirhier(path);
|
|
mkdir (path,0777);
|
|
*slash = '/';
|
|
}
|
|
|
|
return slash;
|
|
}
|
|
/*
|
|
* Replacement fopen(3)
|
|
*/
|
|
FILE *fopen(const char *filename, const char *mode)
|
|
{
|
|
FILE *ret;
|
|
|
|
if ((ret = (*libc_fopen)(filename,mode)) == NULL) {
|
|
/*
|
|
* If file is not present in Documents directory, try from Bundle.
|
|
*/
|
|
NSString *nsspath = [NSString stringWithFormat:@"%@/%s",
|
|
[[NSBundle mainBundle] bundlePath],
|
|
filename];
|
|
|
|
if ((ret = (*libc_fopen)([nsspath cStringUsingEncoding:NSUTF8StringEncoding],mode)) == NULL &&
|
|
mode[0]=='w' &&
|
|
((filename[0]!='.' && filename[0]!='/') ||
|
|
(filename[0]=='.' && filename[1]=='/')) ) {
|
|
/*
|
|
* If not present in Bundle, create directory in Documents
|
|
*/
|
|
char *path = strdup(filename), *slash;
|
|
static int once = 1;
|
|
|
|
if ((slash = mkdirhier(path)) && once) {
|
|
/*
|
|
* For some reason iOS truncates first created file
|
|
* upon program exit, so we create one preemptively...
|
|
*/
|
|
once = 0;
|
|
strcpy(slash,"/.0");
|
|
creat(path,0444);
|
|
}
|
|
free(path);
|
|
ret = (*libc_fopen)(filename,mode);
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|