Add support for mounting folders from iOS

This commit is contained in:
NoahPeeters
2019-12-14 13:54:59 +02:00
committed by Theodore Dubois
parent c1ab200b20
commit 68340acd03
9 changed files with 548 additions and 20 deletions
+7 -2
View File
@@ -10,11 +10,13 @@
#include <netdb.h>
#import <SystemConfiguration/SystemConfiguration.h>
#import "AppDelegate.h"
#import "AppGroup.h"
#import "iOSFS.h"
#import "SceneDelegate.h"
#import "PasteboardDevice.h"
#import "LocationDevice.h"
#import "TerminalViewController.h"
#import "UserPreferences.h"
#import "AppGroup.h"
#include "kernel/init.h"
#include "kernel/calls.h"
#include "fs/dyndev.h"
@@ -137,7 +139,9 @@ static void ios_handle_die(const char *msg) {
die_handler = ios_handle_die;
NSString *sockTmp = [NSTemporaryDirectory() stringByAppendingString:@"ishsock"];
sock_tmp_prefix = strdup(sockTmp.UTF8String);
filesystems[IOS_FILESYSTEM_ID] = &iosfs;
filesystems[IOS_UNSAFE_FILESYSTEM_ID] = &iosfs_unsafe;
tty_drivers[TTY_CONSOLE_MAJOR] = &ios_console_driver;
set_console_device(TTY_CONSOLE_MAJOR, 1);
err = create_stdio("/dev/console", TTY_CONSOLE_MAJOR, 1);
@@ -237,6 +241,7 @@ void NetworkReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReach
if (self.window != nil) {
// For iOS <13, where the app delegate owns the window instead of the scene
TerminalViewController *vc = (TerminalViewController *) self.window.rootViewController;
currentTerminalViewController = vc;
[vc startNewSession];
}
return YES;
+3
View File
@@ -6,9 +6,12 @@
//
#import <UIKit/UIKit.h>
#import "TerminalViewController.h"
NS_ASSUME_NONNULL_BEGIN
extern TerminalViewController *currentTerminalViewController;
API_AVAILABLE(ios(13))
@interface SceneDelegate : UIResponder <UIWindowSceneDelegate>
+15 -1
View File
@@ -6,7 +6,8 @@
//
#import "SceneDelegate.h"
#import "TerminalViewController.h"
TerminalViewController *currentTerminalViewController = NULL;
@interface SceneDelegate ()
@@ -40,4 +41,17 @@ static NSString *const TerminalUUID = @"TerminalUUID";
return activity;
}
- (void)sceneDidBecomeActive:(UIScene *)scene {
TerminalViewController *terminalViewController = (TerminalViewController *) self.window.rootViewController;;
currentTerminalViewController = terminalViewController;
}
- (void)sceneWillResignActive:(UIScene *)scene {
TerminalViewController *terminalViewController = (TerminalViewController *) self.window.rootViewController;
if (currentTerminalViewController == terminalViewController) {
currentTerminalViewController = NULL;
}
}
@end
+9
View File
@@ -0,0 +1,9 @@
//
// iOSFS.h
// iSH
//
// Created by Noah Peeters on 26.10.19.
//
extern const struct fs_ops iosfs;
extern const struct fs_ops iosfs_unsafe;
+449
View File
@@ -0,0 +1,449 @@
//
// iOSFS.m
// iSH
//
// Created by Noah Peeters on 26.10.19.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#include <sys/stat.h>
#include "SceneDelegate.h"
#include "iOSFS.h"
#include "kernel/fs.h"
#include "kernel/errno.h"
#include "fs/path.h"
const NSFileCoordinatorWritingOptions NSFileCoordinatorWritingForCreating = NSFileCoordinatorWritingForMerging;
@interface DirectoryPickerDelegate : NSObject <UIDocumentPickerDelegate>
@property NSURL *url;
@property pthread_mutex_t *mutex;
@end
@implementation DirectoryPickerDelegate
- (instancetype)initWithMutex:(pthread_mutex_t *)mutex {
if (self = [super init]) {
self.mutex = mutex;
self.url = nil;
pthread_mutex_lock(mutex);
}
return self;
}
- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller {
pthread_mutex_unlock(self.mutex);
}
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls {
if (urls.count > 0)
self.url = urls[0];
pthread_mutex_unlock(self.mutex);
}
@end
NSURL *url_for_mount(struct mount *mount) {
return (__bridge NSURL *) mount->data;
}
NSURL *url_for_path_in_mount(struct mount *mount, const char *path) {
return [[url_for_mount(mount) URLByAppendingPathComponent:[NSString stringWithUTF8String:path]] URLByStandardizingPath];
}
const char *path_for_url_in_mount(struct mount *mount, NSURL *url, const char *fallback) {
NSString *mount_path = [[url_for_mount(mount) URLByStandardizingPath] path];
NSString *url_path = [[url URLByStandardizingPath] path];
// The `/private` prefix is a special case as described in the documentation of `URLByStandardizingPath`.
if ([mount_path hasPrefix:@"/private/"]) mount_path = [mount_path substringFromIndex:8];
if ([url_path hasPrefix:@"/private/"]) url_path = [url_path substringFromIndex:8];
if (![url_path hasPrefix:mount_path])
return fallback;
NSURL *new_url = [NSURL fileURLWithPath:[url_path substringFromIndex:[mount_path length]]];
return [new_url ? [new_url path] : @"" cStringUsingEncoding:NSUTF8StringEncoding];
}
static int iosfs_stat(struct mount *mount, const char *path, struct statbuf *fake_stat);
const struct fd_ops iosfs_fdops;
static int posixErrorFromNSError(NSError *error) {
if (error != nil) {
NSError *underlyingError = [error.userInfo objectForKey:NSUnderlyingErrorKey];
if (underlyingError) {
return -(int)underlyingError.code
;
} else {
return _EPERM;
}
}
return 0;
}
static int combine_error(NSError *coordinatorError, int err) {
int posix_error = posixErrorFromNSError(coordinatorError);
return posix_error ? posix_error : err;
}
static struct fd *iosfs_open(struct mount *mount, const char *path, int flags, int mode) {
NSURL *url = url_for_path_in_mount(mount, path);
struct statbuf stats;
int err = iosfs_stat(mount, path, &stats);
if (!err && S_ISREG(stats.mode)) {
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
__block pthread_mutex_t open_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&open_mutex);
__block NSError *error;
__block struct fd *openedFile;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
void (^operation)(NSURL *url) = ^(NSURL *url) {
openedFile = realfs_open_with_fdops(mount, path_for_url_in_mount(mount, url, path), flags, mode, &iosfs_fdops);
if (IS_ERR(openedFile)) {
pthread_mutex_unlock(&open_mutex);
} else {
pthread_mutex_t close_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&close_mutex);
openedFile->data = &close_mutex;
pthread_mutex_unlock(&open_mutex);
pthread_mutex_lock(&close_mutex);
pthread_mutex_unlock(&close_mutex);
}
};
if (!(flags & O_WRONLY_) && !(flags & O_RDWR_)) {
[coordinator coordinateReadingItemAtURL:url options:NSFileCoordinatorReadingWithoutChanges error:&error byAccessor:operation];
} else if (flags & O_CREAT_) {
[coordinator coordinateWritingItemAtURL:url options:NSFileCoordinatorWritingForCreating error:&error byAccessor:operation];
} else {
[coordinator coordinateWritingItemAtURL:url options:NSFileCoordinatorWritingForMerging error:&error byAccessor:operation];
}
});
pthread_mutex_lock(&open_mutex);
pthread_mutex_unlock(&open_mutex);
int posix_error = posixErrorFromNSError(error);
return posix_error ? ERR_PTR(posix_error) : openedFile;
} else {
return realfs_open_with_fdops(mount, path, flags, mode, &iosfs_fdops);
}
}
int iosfs_close(struct fd *fd) {
int err = realfs.close(fd);
if (fd->data) {
pthread_mutex_t *mutex = (pthread_mutex_t *)fd->data;
pthread_mutex_unlock(mutex);
}
return err;
}
static int iosfs_ask_for_url(NSURL **url) {
TerminalViewController *terminalViewController = currentTerminalViewController;
if (!terminalViewController)
return _ENODEV;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
DirectoryPickerDelegate *pickerDelegate = [[DirectoryPickerDelegate alloc] initWithMutex:&mutex];
dispatch_async(dispatch_get_main_queue(), ^(void) {
UIDocumentPickerViewController *picker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[ @"public.folder" ] inMode:UIDocumentPickerModeOpen];
picker.delegate = pickerDelegate;
[terminalViewController presentViewController:picker animated:true completion:nil];
});
pthread_mutex_lock(&mutex);
pthread_mutex_unlock(&mutex);
if (pickerDelegate.url == nil)
return _ENODEV;
*url = pickerDelegate.url;
return 0;
}
static int iosfs_mount(struct mount *mount) {
NSURL *url;
int err = iosfs_ask_for_url(&url);
if (err)
return err;
// Overwrite url & base path
mount->data = (void *)CFBridgingRetain(url);
mount->source = strdup([[url path] UTF8String]);
if ([url startAccessingSecurityScopedResource] == NO) {
CFBridgingRelease(mount->data);
return _EPERM;
}
return realfs.mount(mount);
}
static int iosfs_umount(struct mount *mount) {
NSURL *url = url_for_mount(mount);
[url stopAccessingSecurityScopedResource];
CFBridgingRelease(mount->data);
return 0;
}
static int iosfs_rename(struct mount *mount, const char *src, const char *dst) {
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
NSURL *src_url = url_for_path_in_mount(mount, src);
NSURL *dst_url = url_for_path_in_mount(mount, dst);
NSError *error;
__block int err;
[coordinator coordinateWritingItemAtURL:src_url options:NSFileCoordinatorWritingForMoving error:&error byAccessor:^(NSURL *url) {
[coordinator itemAtURL:url willMoveToURL:dst_url];
err = realfs.rename(mount, path_for_url_in_mount(mount, url, src), dst);
[coordinator itemAtURL:url didMoveToURL:dst_url];
}];
return combine_error(error, err);
}
static int iosfs_symlink(struct mount *mount, const char *target, const char *link) {
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
NSURL *dst_url = url_for_path_in_mount(mount, link);
NSError *error;
__block int err;
[coordinator coordinateWritingItemAtURL:dst_url options:NSFileCoordinatorWritingForCreating error:&error byAccessor:^(NSURL *url) {
err = realfs.symlink(mount, path_for_url_in_mount(mount, url, target), link);
}];
return combine_error(error, err);
}
static int iosfs_mknod(struct mount *mount, const char *path, mode_t_ mode, dev_t_ dev) {
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
NSURL *in_url = url_for_path_in_mount(mount, path);
NSError *error;
__block int err;
[coordinator coordinateWritingItemAtURL:in_url options:NSFileCoordinatorWritingForCreating error:&error byAccessor:^(NSURL *url) {
err = realfs.mknod(mount, path_for_url_in_mount(mount, url, path), mode, dev);
}];
return combine_error(error, err);
}
static int iosfs_setattr(struct mount *mount, const char *path, struct attr attr) {
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
NSURL *in_url = url_for_path_in_mount(mount, path);
NSError *error;
__block int err;
[coordinator coordinateWritingItemAtURL:in_url options:NSFileCoordinatorWritingContentIndependentMetadataOnly error:&error byAccessor:^(NSURL *url) {
err = realfs.setattr(mount, path_for_url_in_mount(mount, url, path), attr);
}];
return combine_error(error, err);
}
static int iosfs_fsetattr(struct fd *fd, struct attr attr) {
return realfs.fsetattr(fd, attr);
}
static ssize_t iosfs_readlink(struct mount *mount, const char *path, char *buf, size_t bufsize) {
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
NSURL *in_url = url_for_path_in_mount(mount, path);
NSError *error;
__block ssize_t size;
[coordinator coordinateReadingItemAtURL:in_url options:NSFileCoordinatorReadingWithoutChanges error:&error byAccessor:^(NSURL *url) {
size = realfs.readlink(mount, path_for_url_in_mount(mount, url, path), buf, bufsize);
}];
int posix_error = posixErrorFromNSError(error);
return posix_error ? posix_error : size;
}
static int iosfs_getpath(struct fd *fd, char *buf) {
return realfs.getpath(fd, buf);
}
static int iosfs_link(struct mount *mount, const char *src, const char *dst) {
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
NSURL *dst_url = url_for_path_in_mount(mount, dst);
NSError *error;
__block int err;
[coordinator coordinateWritingItemAtURL:dst_url options:NSFileCoordinatorWritingForCreating error:&error byAccessor:^(NSURL *url) {
err = realfs.link(mount, src, path_for_url_in_mount(mount, url, dst));
}];
return combine_error(error, err);
}
static int iosfs_unlink(struct mount *mount, const char *path) {
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
NSURL *in_url = url_for_path_in_mount(mount, path);
NSError *error;
__block int err;
[coordinator coordinateWritingItemAtURL:in_url options:NSFileCoordinatorWritingForDeleting error:&error byAccessor:^(NSURL *url) {
err = realfs.unlink(mount, path_for_url_in_mount(mount, url, path));
}];
return combine_error(error, err);
}
static int iosfs_rmdir(struct mount *mount, const char *path) {
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
NSURL *in_url = url_for_path_in_mount(mount, path);
NSError *error;
__block int err;
[coordinator coordinateWritingItemAtURL:in_url options:NSFileCoordinatorWritingForDeleting error:&error byAccessor:^(NSURL *url) {
err = realfs.rmdir(mount, path_for_url_in_mount(mount, url, path));
}];
return combine_error(error, err);
}
static int iosfs_stat(struct mount *mount, const char *path, struct statbuf *fake_stat) {
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
NSURL *in_url = url_for_path_in_mount(mount, path);
NSError *error;
__block int err;
[coordinator coordinateReadingItemAtURL:in_url options:NSFileCoordinatorReadingWithoutChanges error:&error byAccessor:^(NSURL *url) {
err = realfs.stat(mount, path_for_url_in_mount(mount, url, path), fake_stat);
}];
return combine_error(error, err);
}
static int iosfs_fstat(struct fd *fd, struct statbuf *fake_stat) {
int err = realfs.fstat(fd, fake_stat);
return err;
}
static int iosfs_utime(struct mount *mount, const char *path, struct timespec atime, struct timespec mtime) {
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
NSURL *in_url = url_for_path_in_mount(mount, path);
NSError *error;
__block int err;
[coordinator coordinateWritingItemAtURL:in_url options:NSFileCoordinatorWritingContentIndependentMetadataOnly error:&error byAccessor:^(NSURL *url) {
err = realfs.utime(mount, path_for_url_in_mount(mount, url, path), atime, mtime);
}];
return combine_error(error, err);
}
static int iosfs_mkdir(struct mount *mount, const char *path, mode_t_ mode) {
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
NSURL *in_url = url_for_path_in_mount(mount, path);
NSError *error;
__block int err;
[coordinator coordinateWritingItemAtURL:in_url options:NSFileCoordinatorWritingForCreating error:&error byAccessor:^(NSURL *url) {
err = realfs.mkdir(mount, path_for_url_in_mount(mount, url, path), mode);
}];
return combine_error(error, err);
}
static int iosfs_flock(struct fd *fd, int operation) {
return realfs.flock(fd, operation);
}
const struct fs_ops iosfs = {
.name = "ios", .magic = 0x7265616d,
.mount = iosfs_mount,
.umount = iosfs_umount,
.statfs = realfs_statfs,
.open = iosfs_open,
.readlink = iosfs_readlink,
.link = iosfs_link,
.unlink = iosfs_unlink,
.rmdir = iosfs_rmdir,
.rename = iosfs_rename,
.symlink = iosfs_symlink,
.mknod = iosfs_mknod,
.close = iosfs_close,
.stat = iosfs_stat,
.fstat = iosfs_fstat,
.setattr = iosfs_setattr,
.fsetattr = iosfs_fsetattr,
.utime = iosfs_utime,
.getpath = iosfs_getpath,
.flock = iosfs_flock,
.mkdir = iosfs_mkdir,
};
const struct fs_ops iosfs_unsafe = {
.name = "ios-unsafe", .magic = 0x7265616e,
.mount = iosfs_mount,
.umount = iosfs_umount,
.statfs = realfs_statfs,
.open = realfs_open,
.readlink = realfs_readlink,
.link = realfs_link,
.unlink = realfs_unlink,
.rmdir = realfs_rmdir,
.rename = realfs_rename,
.symlink = realfs_symlink,
.mknod = realfs_mknod,
.close = realfs_close,
.stat = realfs_stat,
.fstat = realfs_fstat,
.setattr = realfs_setattr,
.fsetattr = realfs_fsetattr,
.utime = realfs_utime,
.getpath = realfs_getpath,
.flock = realfs_flock,
.mkdir = realfs_mkdir,
};
const struct fd_ops iosfs_fdops = {
.read = realfs_read,
.write = realfs_write,
.readdir = realfs_readdir,
.telldir = realfs_telldir,
.seekdir = realfs_seekdir,
.lseek = realfs_lseek,
.mmap = realfs_mmap,
.poll = realfs_poll,
.fsync = realfs_fsync,
.close = iosfs_close,
.getflags = realfs_getflags,
.setflags = realfs_setflags,
};
+4 -2
View File
@@ -9,6 +9,8 @@ const struct fs_ops *filesystems[] = {
&procfs,
&devptsfs,
&tmpfs,
[IOS_FILESYSTEM_ID] = NULL,
[IOS_UNSAFE_FILESYSTEM_ID] = NULL
};
struct mount *mount_find(char *path) {
@@ -17,7 +19,7 @@ struct mount *mount_find(char *path) {
struct mount *mount = NULL;
assert(!list_empty(&mounts)); // this would mean there's no root FS mounted
list_for_each_entry(&mounts, mount, mounts) {
int n = strlen(mount->point);
size_t n = strlen(mount->point);
if (strncmp(path, mount->point, n) == 0 && (path[n] == '/' || path[n] == '\0'))
break;
}
@@ -120,7 +122,7 @@ dword_t sys_mount(addr_t source_addr, addr_t point_addr, addr_t type_addr, dword
const struct fs_ops *fs = NULL;
for (size_t i = 0; i < sizeof(filesystems)/sizeof(filesystems[0]); i++) {
if (strcmp(filesystems[i]->name, type) == 0) {
if (filesystems[i] && (strcmp(filesystems[i]->name, type) == 0)) {
fs = filesystems[i];
break;
}
+19 -15
View File
@@ -74,17 +74,21 @@ static int open_flags_fake_from_real(int flags) {
return fake_flags;
}
static struct fd *realfs_open(struct mount *mount, const char *path, int flags, int mode) {
struct fd *realfs_open_with_fdops(struct mount *mount, const char *path, int flags, int mode, const struct fd_ops *fdops) {
int real_flags = open_flags_real_from_fake(flags);
int fd_no = openat(mount->root_fd, fix_path(path), real_flags, mode);
if (fd_no < 0)
return ERR_PTR(errno_map());
struct fd *fd = fd_create(&realfs_fdops);
struct fd *fd = fd_create(fdops);
fd->real_fd = fd_no;
fd->dir = NULL;
return fd;
}
struct fd *realfs_open(struct mount *mount, const char *path, int flags, int mode) {
return realfs_open_with_fdops(mount, path, flags, mode, &realfs_fdops);
}
int realfs_close(struct fd *fd) {
if (fd->dir != NULL)
closedir(fd->dir);
@@ -119,7 +123,7 @@ static void copy_stat(struct statbuf *fake_stat, struct stat *real_stat) {
#undef TIMESPEC
}
static int realfs_stat(struct mount *mount, const char *path, struct statbuf *fake_stat) {
int realfs_stat(struct mount *mount, const char *path, struct statbuf *fake_stat) {
struct stat real_stat;
if (fstatat(mount->root_fd, fix_path(path), &real_stat, AT_SYMLINK_NOFOLLOW) < 0)
return errno_map();
@@ -127,7 +131,7 @@ static int realfs_stat(struct mount *mount, const char *path, struct statbuf *fa
return 0;
}
static int realfs_fstat(struct fd *fd, struct statbuf *fake_stat) {
int realfs_fstat(struct fd *fd, struct statbuf *fake_stat) {
struct stat real_stat;
if (fstat(fd->real_fd, &real_stat) < 0)
return errno_map();
@@ -163,7 +167,7 @@ ssize_t realfs_pwrite(struct fd *fd, const void *buf, size_t bufsize, off_t off)
return res;
}
static void realfs_opendir(struct fd *fd) {
void realfs_opendir(struct fd *fd) {
if (fd->dir == NULL) {
int dirfd = dup(fd->real_fd);
fd->dir = fdopendir(dirfd);
@@ -265,7 +269,7 @@ int realfs_mmap(struct fd *fd, struct mem *mem, page_t start, pages_t pages, off
return pt_map(mem, start, pages, memory, correction, prot);
}
static ssize_t realfs_readlink(struct mount *mount, const char *path, char *buf, size_t bufsize) {
ssize_t realfs_readlink(struct mount *mount, const char *path, char *buf, size_t bufsize) {
ssize_t size = readlinkat(mount->root_fd, fix_path(path), buf, bufsize);
if (size < 0)
return errno_map();
@@ -283,42 +287,42 @@ int realfs_getpath(struct fd *fd, char *buf) {
return 0;
}
static int realfs_link(struct mount *mount, const char *src, const char *dst) {
int realfs_link(struct mount *mount, const char *src, const char *dst) {
int res = linkat(mount->root_fd, fix_path(src), mount->root_fd, fix_path(dst), 0);
if (res < 0)
return errno_map();
return res;
}
static int realfs_unlink(struct mount *mount, const char *path) {
int realfs_unlink(struct mount *mount, const char *path) {
int res = unlinkat(mount->root_fd, fix_path(path), 0);
if (res < 0)
return errno_map();
return res;
}
static int realfs_rmdir(struct mount *mount, const char *path) {
int realfs_rmdir(struct mount *mount, const char *path) {
int err = unlinkat(mount->root_fd, fix_path(path), AT_REMOVEDIR);
if (err < 0)
return errno_map();
return 0;
}
static int realfs_rename(struct mount *mount, const char *src, const char *dst) {
int realfs_rename(struct mount *mount, const char *src, const char *dst) {
int err = renameat(mount->root_fd, fix_path(src), mount->root_fd, fix_path(dst));
if (err < 0)
return errno_map();
return err;
}
static int realfs_symlink(struct mount *mount, const char *target, const char *link) {
int realfs_symlink(struct mount *mount, const char *target, const char *link) {
int err = symlinkat(target, mount->root_fd, link);
if (err < 0)
return errno_map();
return err;
}
static int realfs_mknod(struct mount *mount, const char *path, mode_t_ mode, dev_t_ UNUSED(dev)) {
int realfs_mknod(struct mount *mount, const char *path, mode_t_ mode, dev_t_ UNUSED(dev)) {
int err;
if (S_ISFIFO(mode)) {
lock_fchdir(mount->root_fd);
@@ -347,7 +351,7 @@ int realfs_truncate(struct mount *mount, const char *path, off_t_ size) {
return err;
}
static int realfs_setattr(struct mount *mount, const char *path, struct attr attr) {
int realfs_setattr(struct mount *mount, const char *path, struct attr attr) {
path = fix_path(path);
int root = mount->root_fd;
int err;
@@ -371,7 +375,7 @@ static int realfs_setattr(struct mount *mount, const char *path, struct attr att
return err;
}
static int realfs_fsetattr(struct fd *fd, struct attr attr) {
int realfs_fsetattr(struct fd *fd, struct attr attr) {
int real_fd = fd->real_fd;
int err;
switch (attr.type) {
@@ -401,7 +405,7 @@ int realfs_utime(struct mount *mount, const char *path, struct timespec atime, s
return 0;
}
static int realfs_mkdir(struct mount *mount, const char *path, mode_t_ mode) {
int realfs_mkdir(struct mount *mount, const char *path, mode_t_ mode) {
int err = mkdirat(mount->root_fd, fix_path(path), mode);
if (err < 0)
return errno_map();
+9
View File
@@ -7,6 +7,8 @@
objects = {
/* Begin PBXBuildFile section */
40616E3C236642B6008CDF19 /* mount.c in Sources */ = {isa = PBXBuildFile; fileRef = 40616E3B236642B5008CDF19 /* mount.c */; };
408A263A236440F8008A4E81 /* iOSFS.m in Sources */ = {isa = PBXBuildFile; fileRef = 408A2639236440F8008A4E81 /* iOSFS.m */; };
650B337422EA235C00B4C03E /* PasteboardDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 650B337322EA235C00B4C03E /* PasteboardDevice.m */; };
8632A7BF219A59FB00F02325 /* UserPreferences.m in Sources */ = {isa = PBXBuildFile; fileRef = 8632A7BE219A59FB00F02325 /* UserPreferences.m */; };
9A28E4EA219A8B670073D200 /* AboutAppearanceViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A28E4E9219A8B670073D200 /* AboutAppearanceViewController.m */; };
@@ -99,6 +101,9 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
40616E3B236642B5008CDF19 /* mount.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mount.c; sourceTree = "<group>"; };
408A2639236440F8008A4E81 /* iOSFS.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = iOSFS.m; sourceTree = "<group>"; };
408A263B23644102008A4E81 /* iOSFS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = iOSFS.h; sourceTree = "<group>"; };
650B335A22E9E46A00B4C03E /* mem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mem.c; sourceTree = "<group>"; tabWidth = 4; };
650B335B22E9E46A00B4C03E /* mem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mem.h; sourceTree = "<group>"; tabWidth = 4; };
650B335D22E9EF9B00B4C03E /* proc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = proc.c; sourceTree = "<group>"; };
@@ -440,6 +445,8 @@
BB792B561F96D90D00FFB7A4 /* TerminalViewController.h */,
BB792B571F96D90D00FFB7A4 /* TerminalViewController.m */,
BBBF7B5B2415CDBB00EC4C14 /* Settings.bundle */,
408A263B23644102008A4E81 /* iOSFS.h */,
408A2639236440F8008A4E81 /* iOSFS.m */,
BBFB557D21587B2B00DFE6DE /* Bar */,
BB78AB291FAD22440013E782 /* TerminalView.h */,
BB78AB2A1FAD22440013E782 /* TerminalView.m */,
@@ -989,6 +996,7 @@
9A28E4EA219A8B670073D200 /* AboutAppearanceViewController.m in Sources */,
BB1D9D93234A8FE100F364E8 /* AboutNavigationController.m in Sources */,
BB235534235D488500139E00 /* LocationDevice.m in Sources */,
40616E3C236642B6008CDF19 /* mount.c in Sources */,
BB792B581F96D90D00FFB7A4 /* TerminalViewController.m in Sources */,
BB78AB2B1FAD22440013E782 /* TerminalView.m in Sources */,
BB23F58D231E1D1400585522 /* ScrollbarView.m in Sources */,
@@ -1006,6 +1014,7 @@
BBFB5579215876CD00DFE6DE /* AboutViewController.m in Sources */,
650B337422EA235C00B4C03E /* PasteboardDevice.m in Sources */,
BBFB557121586C4800DFE6DE /* UIViewController+Back.m in Sources */,
408A263A236440F8008A4E81 /* iOSFS.m in Sources */,
BBFB558021587B6800DFE6DE /* ArrowBarButton.m in Sources */,
BB792B551F96D90D00FFB7A4 /* AppDelegate.m in Sources */,
);
+33
View File
@@ -108,6 +108,7 @@ void mount_release(struct mount *mount);
// must hold mounts_lock while calling these, or traversing mounts
int do_mount(const struct fs_ops *fs, const char *source, const char *point, int flags);
int do_mount_with_data(const struct fs_ops *fs, const char *source, const char *point, int flags, void *data);
int do_umount(const char *point);
int mount_remove(struct mount *mount);
extern struct list mounts;
@@ -178,6 +179,25 @@ const char *fix_path(const char *path); // TODO reconsider
// real fs
extern const struct fd_ops realfs_fdops;
struct fd *realfs_open_with_fdops(struct mount *mount, const char *path, int flags, int mode, const struct fd_ops *fdops);
struct fd *realfs_open(struct mount *mount, const char *path, int flags, int mode);
ssize_t realfs_readlink(struct mount *mount, const char *path, char *buf, size_t bufsize);
int realfs_link(struct mount *mount, const char *src, const char *dst);
int realfs_unlink(struct mount *mount, const char *path);
int realfs_rmdir(struct mount *mount, const char *path);
int realfs_rename(struct mount *mount, const char *src, const char *dst);
int realfs_symlink(struct mount *mount, const char *target, const char *link);
int realfs_mknod(struct mount *mount, const char *path, mode_t_ mode, dev_t_ UNUSED(dev));
int realfs_stat(struct mount *mount, const char *path, struct statbuf *fake_stat);
int realfs_statfs(struct mount *mount, struct statfsbuf *stat);
int realfs_fstat(struct fd *fd, struct statbuf *fake_stat);
int realfs_setattr(struct mount *mount, const char *path, struct attr attr);
int realfs_fsetattr(struct fd *fd, struct attr attr);
int realfs_mkdir(struct mount *mount, const char *path, mode_t_ mode);
int realfs_truncate(struct mount *mount, const char *path, off_t_ size);
int realfs_utime(struct mount *mount, const char *path, struct timespec atime, struct timespec mtime);
@@ -186,7 +206,16 @@ int realfs_flock(struct fd *fd, int operation);
int realfs_getpath(struct fd *fd, char *buf);
ssize_t realfs_read(struct fd *fd, void *buf, size_t bufsize);
ssize_t realfs_write(struct fd *fd, const void *buf, size_t bufsize);
int realfs_readdir(struct fd *fd, struct dir_entry *entry);
unsigned long realfs_telldir(struct fd *fd);
void realfs_seekdir(struct fd *fd, unsigned long ptr);
off_t realfs_lseek(struct fd *fd, off_t offset, int whence);
int realfs_poll(struct fd *fd);
int realfs_mmap(struct fd *fd, struct mem *mem, page_t start, pages_t pages, off_t offset, int prot, int flags);
int realfs_fsync(struct fd *fd);
int realfs_getflags(struct fd *fd);
int realfs_setflags(struct fd *fd, dword_t arg);
ssize_t realfs_ioctl_size(int cmd);
@@ -203,4 +232,8 @@ extern const struct fs_ops fakefs;
extern const struct fs_ops devptsfs;
extern const struct fs_ops tmpfs;
extern const struct fs_ops *filesystems[];
#define IOS_FILESYSTEM_ID 3
#define IOS_UNSAFE_FILESYSTEM_ID 4
#endif