Skip to content

Commit

Permalink
Logical pwd
Browse files Browse the repository at this point in the history
  • Loading branch information
yury committed Jul 30, 2021
1 parent 2c4a58c commit 2b29dcf
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 12 deletions.
110 changes: 99 additions & 11 deletions ios_system.m
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,14 @@ void ios_setBookmarkDictionaryName(NSString* name) {
void ios_printBookmarkedVersion(char* p) {
// p is a directory. See if there is a bookmark that can make it shorter:
NSString* pathString = [NSString stringWithUTF8String:p];
if ([pathString hasPrefix:@"/private"]) {
pathString = [pathString stringByReplacingOccurrencesOfString:@"/private" withString:@""];
NSString* privatePrefix = @"/private";
if ([pathString hasPrefix:privatePrefix]) {
pathString = [pathString substringFromIndex:[privatePrefix length]];
}
NSString *homePath;
homePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByDeletingLastPathComponent];
if ([homePath hasPrefix:@"/private"]) {
homePath = [homePath stringByReplacingOccurrencesOfString:@"/private" withString:@""];
if ([homePath hasPrefix:privatePrefix]) {
homePath = [homePath substringFromIndex:[privatePrefix length]];
}
NSLog(@"ios_printBookmarkedVersion: %s %s", homePath.UTF8String, pathString.UTF8String);
if ([pathString hasPrefix:homePath]) {
Expand All @@ -126,8 +127,8 @@ void ios_printBookmarkedVersion(char* p) {
}
for (NSString* bookmark in tildeExpansionDictionary) {
NSString* bookmarkPath = tildeExpansionDictionary[bookmark];
if ([bookmarkPath hasPrefix:@"/private"]) {
bookmarkPath = [bookmarkPath stringByReplacingOccurrencesOfString:@"/private" withString:@""];
if ([bookmarkPath hasPrefix:privatePrefix]) {
bookmarkPath = [bookmarkPath substringFromIndex:[privatePrefix length]];
}
if ([pathString hasPrefix:bookmarkPath]) {
pathString = [pathString stringByReplacingOccurrencesOfString:bookmarkPath withString:bookmark];
Expand Down Expand Up @@ -203,6 +204,18 @@ void ios_signal(int signal) {
}
}

NSString *ios_getLogicalPWD(const void* sessionId) {
id sessionKey = @((NSUInteger)sessionId);
if (sessionList == nil) {
return nil;
}
sessionParameters *session = (sessionParameters*)[[sessionList objectForKey: sessionKey] pointerValue];
if (session == nil) {
return nil;
}
return @(session->currentDir);
}

#undef getenv
void ios_setWindowSize(int width, int height, const void* sessionId) {
// You can set the window size for a session that is not currently running (e.g. because "sh_session" is running).
Expand Down Expand Up @@ -244,6 +257,9 @@ void ios_setWindowSize(int width, int height, const void* sessionId) {
if (strcmp(name, "ROWS") == 0) {
return currentSession->lines;
}
if (strcmp(name, "PWD") == 0) {
return currentSession->currentDir;
}
return libc_getenv(name);
}

Expand Down Expand Up @@ -534,6 +550,8 @@ void initializeEnvironment() {
getrlimit(RLIMIT_NOFILE, &limitFilesOpen);
}

NSString * pathJoin(NSString * segmentA, NSString * segmentB);

static char* parseArgument(char* argument, char* command) {
// expand all environment variables, convert "~" to $HOME (only if localFile)
// we also pass the shell command for some specific behaviour (don't do this for that command)
Expand Down Expand Up @@ -641,6 +659,9 @@ void initializeEnvironment() {
}
}
}
if ([argumentString hasPrefix:@"../"] || [argumentString hasPrefix:@"./.."] || [argumentString isEqualToString:@".."]) {
argumentString = pathJoin(@(currentSession->currentDir), argumentString);
}
if (strcmp(command, "export") == 0) {
argumentString = [[variableName stringByAppendingString:@"="] stringByAppendingString:argumentString];
}
Expand Down Expand Up @@ -796,6 +817,7 @@ void __cd_to_dir(NSString *newDir, NSFileManager *fileManager) {

if (__allowed_cd_to_path(resultDir)) {
strcpy(currentSession->previousDirectory, currentSession->currentDir);
strcpy(currentSession->currentDir, [newDir UTF8String]);
return;
}

Expand Down Expand Up @@ -902,29 +924,33 @@ int command_not_found(int argc, char** argv) {
}

extern void newPreviousDirectory();


int cd_main(int argc, char** argv) {
if (currentSession == NULL) {
return 1;
}
NSFileManager *fileManager = [[NSFileManager alloc] init];

if (argc > 1) {
NSString* newDir = @(argv[1]);
if (strcmp(argv[1], "-") == 0) {
// "cd -" option to pop back to previous directory
newDir = [NSString stringWithCString:currentSession->previousDirectory encoding:NSUTF8StringEncoding];
newDir = @(currentSession->previousDirectory);
}
newDir = pathJoin(@(currentSession->currentDir), newDir);
__cd_to_dir(newDir, fileManager);
} else { // [cd] Help, I'm lost, bring me back home
strcpy(currentSession->previousDirectory, [[fileManager currentDirectoryPath] UTF8String]);

if (miniRoot != nil) {
[fileManager changeCurrentDirectoryPath:miniRoot];
} else {
[fileManager changeCurrentDirectoryPath:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]];
}

strcpy(currentSession->previousDirectory, currentSession->currentDir);
strcpy(currentSession->currentDir, fileManager.currentDirectoryPath.UTF8String);
}
strcpy(currentSession->currentDir, [[fileManager currentDirectoryPath] UTF8String]);

newPreviousDirectory(); // If a command is running, this changes the directory it goes back to.
return 0;
}
Expand Down Expand Up @@ -2835,3 +2861,65 @@ int ios_system(const char* inputCmd) {
fflush(thread_stderr);
return currentSession->global_errno;
}

NSArray<NSString *> * pathNormalizeArray(NSArray<NSString *> * parts, BOOL allowAboveRoot) {
NSMutableArray<NSString *> * res = [[NSMutableArray alloc] init];
for (NSString * p in parts) {
// ignore empty parts
if (p.length == 0 || [p isEqualToString:@"."] || [p isEqualToString:@"/"]) {
continue;
}

if ([p isEqualToString: @".."]) {
if (res.count && ![@".." isEqualToString: [res lastObject]]) {
[res removeLastObject];
} else if (allowAboveRoot) {
[res addObject: p];
}
} else {
[res addObject: p];
}
}

return res;
}

NSString * pathNormalize(NSString *path) {
BOOL isAbsolute = [path hasPrefix:@"/"];
BOOL trailingSlash = [path hasSuffix:@"/"];

NSString * result = [pathNormalizeArray([path pathComponents], !isAbsolute) componentsJoinedByString: @"/"];

if (!result.length && !isAbsolute) {
result = @".";
}

if (result.length && trailingSlash) {
result = [result stringByAppendingString:@"/"];
}

return [(isAbsolute ? @"/" : @"") stringByAppendingString:result];
}


NSString * pathJoin(NSString * segmentA, NSString * segmentB) {
NSMutableString *path = [[NSMutableString alloc] init];
NSString * a = segmentA ?: @"";
NSString * b = segmentB ?: @"";

if ([b hasPrefix:@"/"]) {
return pathNormalize(b);
}

if (a.length) {
[path appendString: a];
if (b.length) {
[path appendString:@"/"];
[path appendString:b];
}
} else if (b.length) {
[path appendString: b];
}

return pathNormalize(path);
}
3 changes: 2 additions & 1 deletion ios_system/ios_system.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ extern NSArray* environmentAsArray(void);
extern void storeEnvironment(char* envp[]);
extern pid_t ios_fork(void);
extern void ios_waitpid(pid_t pid);
extern void ios_signal(int signal);
extern void ios_signal(int signal);
extern NSString *ios_getLogicalPWD(const void* sessionId);
void ios_setWindowSize(int width, int height, const void* sessionId);

extern NSString* commandsAsString(void);
Expand Down

0 comments on commit 2b29dcf

Please sign in to comment.