Skip to content

Commit 21b930e

Browse files
authored
Merge pull request holzschu#122 from yury/logical-pwd
Logical pwd
2 parents 2c4a58c + 2b29dcf commit 21b930e

File tree

2 files changed

+101
-12
lines changed

2 files changed

+101
-12
lines changed

ios_system.m

Lines changed: 99 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,14 @@ void ios_setBookmarkDictionaryName(NSString* name) {
101101
void ios_printBookmarkedVersion(char* p) {
102102
// p is a directory. See if there is a bookmark that can make it shorter:
103103
NSString* pathString = [NSString stringWithUTF8String:p];
104-
if ([pathString hasPrefix:@"/private"]) {
105-
pathString = [pathString stringByReplacingOccurrencesOfString:@"/private" withString:@""];
104+
NSString* privatePrefix = @"/private";
105+
if ([pathString hasPrefix:privatePrefix]) {
106+
pathString = [pathString substringFromIndex:[privatePrefix length]];
106107
}
107108
NSString *homePath;
108109
homePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByDeletingLastPathComponent];
109-
if ([homePath hasPrefix:@"/private"]) {
110-
homePath = [homePath stringByReplacingOccurrencesOfString:@"/private" withString:@""];
110+
if ([homePath hasPrefix:privatePrefix]) {
111+
homePath = [homePath substringFromIndex:[privatePrefix length]];
111112
}
112113
NSLog(@"ios_printBookmarkedVersion: %s %s", homePath.UTF8String, pathString.UTF8String);
113114
if ([pathString hasPrefix:homePath]) {
@@ -126,8 +127,8 @@ void ios_printBookmarkedVersion(char* p) {
126127
}
127128
for (NSString* bookmark in tildeExpansionDictionary) {
128129
NSString* bookmarkPath = tildeExpansionDictionary[bookmark];
129-
if ([bookmarkPath hasPrefix:@"/private"]) {
130-
bookmarkPath = [bookmarkPath stringByReplacingOccurrencesOfString:@"/private" withString:@""];
130+
if ([bookmarkPath hasPrefix:privatePrefix]) {
131+
bookmarkPath = [bookmarkPath substringFromIndex:[privatePrefix length]];
131132
}
132133
if ([pathString hasPrefix:bookmarkPath]) {
133134
pathString = [pathString stringByReplacingOccurrencesOfString:bookmarkPath withString:bookmark];
@@ -203,6 +204,18 @@ void ios_signal(int signal) {
203204
}
204205
}
205206

207+
NSString *ios_getLogicalPWD(const void* sessionId) {
208+
id sessionKey = @((NSUInteger)sessionId);
209+
if (sessionList == nil) {
210+
return nil;
211+
}
212+
sessionParameters *session = (sessionParameters*)[[sessionList objectForKey: sessionKey] pointerValue];
213+
if (session == nil) {
214+
return nil;
215+
}
216+
return @(session->currentDir);
217+
}
218+
206219
#undef getenv
207220
void ios_setWindowSize(int width, int height, const void* sessionId) {
208221
// You can set the window size for a session that is not currently running (e.g. because "sh_session" is running).
@@ -244,6 +257,9 @@ void ios_setWindowSize(int width, int height, const void* sessionId) {
244257
if (strcmp(name, "ROWS") == 0) {
245258
return currentSession->lines;
246259
}
260+
if (strcmp(name, "PWD") == 0) {
261+
return currentSession->currentDir;
262+
}
247263
return libc_getenv(name);
248264
}
249265

@@ -534,6 +550,8 @@ void initializeEnvironment() {
534550
getrlimit(RLIMIT_NOFILE, &limitFilesOpen);
535551
}
536552

553+
NSString * pathJoin(NSString * segmentA, NSString * segmentB);
554+
537555
static char* parseArgument(char* argument, char* command) {
538556
// expand all environment variables, convert "~" to $HOME (only if localFile)
539557
// we also pass the shell command for some specific behaviour (don't do this for that command)
@@ -641,6 +659,9 @@ void initializeEnvironment() {
641659
}
642660
}
643661
}
662+
if ([argumentString hasPrefix:@"../"] || [argumentString hasPrefix:@"./.."] || [argumentString isEqualToString:@".."]) {
663+
argumentString = pathJoin(@(currentSession->currentDir), argumentString);
664+
}
644665
if (strcmp(command, "export") == 0) {
645666
argumentString = [[variableName stringByAppendingString:@"="] stringByAppendingString:argumentString];
646667
}
@@ -796,6 +817,7 @@ void __cd_to_dir(NSString *newDir, NSFileManager *fileManager) {
796817

797818
if (__allowed_cd_to_path(resultDir)) {
798819
strcpy(currentSession->previousDirectory, currentSession->currentDir);
820+
strcpy(currentSession->currentDir, [newDir UTF8String]);
799821
return;
800822
}
801823

@@ -902,29 +924,33 @@ int command_not_found(int argc, char** argv) {
902924
}
903925

904926
extern void newPreviousDirectory();
927+
928+
905929
int cd_main(int argc, char** argv) {
906930
if (currentSession == NULL) {
907931
return 1;
908932
}
909933
NSFileManager *fileManager = [[NSFileManager alloc] init];
910-
934+
911935
if (argc > 1) {
912936
NSString* newDir = @(argv[1]);
913937
if (strcmp(argv[1], "-") == 0) {
914938
// "cd -" option to pop back to previous directory
915-
newDir = [NSString stringWithCString:currentSession->previousDirectory encoding:NSUTF8StringEncoding];
939+
newDir = @(currentSession->previousDirectory);
916940
}
941+
newDir = pathJoin(@(currentSession->currentDir), newDir);
917942
__cd_to_dir(newDir, fileManager);
918943
} else { // [cd] Help, I'm lost, bring me back home
919-
strcpy(currentSession->previousDirectory, [[fileManager currentDirectoryPath] UTF8String]);
920-
921944
if (miniRoot != nil) {
922945
[fileManager changeCurrentDirectoryPath:miniRoot];
923946
} else {
924947
[fileManager changeCurrentDirectoryPath:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]];
925948
}
949+
950+
strcpy(currentSession->previousDirectory, currentSession->currentDir);
951+
strcpy(currentSession->currentDir, fileManager.currentDirectoryPath.UTF8String);
926952
}
927-
strcpy(currentSession->currentDir, [[fileManager currentDirectoryPath] UTF8String]);
953+
928954
newPreviousDirectory(); // If a command is running, this changes the directory it goes back to.
929955
return 0;
930956
}
@@ -2835,3 +2861,65 @@ int ios_system(const char* inputCmd) {
28352861
fflush(thread_stderr);
28362862
return currentSession->global_errno;
28372863
}
2864+
2865+
NSArray<NSString *> * pathNormalizeArray(NSArray<NSString *> * parts, BOOL allowAboveRoot) {
2866+
NSMutableArray<NSString *> * res = [[NSMutableArray alloc] init];
2867+
for (NSString * p in parts) {
2868+
// ignore empty parts
2869+
if (p.length == 0 || [p isEqualToString:@"."] || [p isEqualToString:@"/"]) {
2870+
continue;
2871+
}
2872+
2873+
if ([p isEqualToString: @".."]) {
2874+
if (res.count && ![@".." isEqualToString: [res lastObject]]) {
2875+
[res removeLastObject];
2876+
} else if (allowAboveRoot) {
2877+
[res addObject: p];
2878+
}
2879+
} else {
2880+
[res addObject: p];
2881+
}
2882+
}
2883+
2884+
return res;
2885+
}
2886+
2887+
NSString * pathNormalize(NSString *path) {
2888+
BOOL isAbsolute = [path hasPrefix:@"/"];
2889+
BOOL trailingSlash = [path hasSuffix:@"/"];
2890+
2891+
NSString * result = [pathNormalizeArray([path pathComponents], !isAbsolute) componentsJoinedByString: @"/"];
2892+
2893+
if (!result.length && !isAbsolute) {
2894+
result = @".";
2895+
}
2896+
2897+
if (result.length && trailingSlash) {
2898+
result = [result stringByAppendingString:@"/"];
2899+
}
2900+
2901+
return [(isAbsolute ? @"/" : @"") stringByAppendingString:result];
2902+
}
2903+
2904+
2905+
NSString * pathJoin(NSString * segmentA, NSString * segmentB) {
2906+
NSMutableString *path = [[NSMutableString alloc] init];
2907+
NSString * a = segmentA ?: @"";
2908+
NSString * b = segmentB ?: @"";
2909+
2910+
if ([b hasPrefix:@"/"]) {
2911+
return pathNormalize(b);
2912+
}
2913+
2914+
if (a.length) {
2915+
[path appendString: a];
2916+
if (b.length) {
2917+
[path appendString:@"/"];
2918+
[path appendString:b];
2919+
}
2920+
} else if (b.length) {
2921+
[path appendString: b];
2922+
}
2923+
2924+
return pathNormalize(path);
2925+
}

ios_system/ios_system.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ extern NSArray* environmentAsArray(void);
4747
extern void storeEnvironment(char* envp[]);
4848
extern pid_t ios_fork(void);
4949
extern void ios_waitpid(pid_t pid);
50-
extern void ios_signal(int signal);
50+
extern void ios_signal(int signal);
51+
extern NSString *ios_getLogicalPWD(const void* sessionId);
5152
void ios_setWindowSize(int width, int height, const void* sessionId);
5253

5354
extern NSString* commandsAsString(void);

0 commit comments

Comments
 (0)