Revision d11e6a4410d5aae70ad545d085d344644c33d9cc authored by Steve Marquess on 25 April 2017, 12:15:14 UTC, committed by Dr. Stephen Henson on 30 August 2017, 20:45:26 UTC
Reviewed-by: Rich Salz <rsalz@openssl.org> Reviewed-by: Andy Polyakov <appro@openssl.org> (Merged from https://github.com/openssl/openssl/pull/3300) (cherry picked from commit d674242a884368083bf1044cc4e6e30d8f452a50)
1 parent e576b67
fopen.m
#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;
}

Computing file changes ...