5959 char localMiniRoot[MAXPATHLEN];
6060 pthread_t current_command_root_thread; // thread ID of first command
6161 pthread_t lastThreadId; // thread ID of last command
62+ pthread_t mainThreadId; // thread ID of parent command, if any (e.g. vim, which starts "sh -c cd dir && flake8 file")
6263 FILE* stdin;
6364 FILE* stdout;
6465 FILE* stderr;
@@ -76,6 +77,7 @@ static void initSessionParameters(sessionParameters* sp) {
7677 sp->isMainThread = TRUE ;
7778 sp->current_command_root_thread = 0 ;
7879 sp->lastThreadId = 0 ;
80+ sp->mainThreadId = 0 ;
7981 NSString * currentDirectory = [fileManager currentDirectoryPath ];
8082 strcpy (sp->currentDir , [currentDirectory UTF8String ]);
8183 strcpy (sp->previousDirectory , [currentDirectory UTF8String ]);
@@ -96,6 +98,46 @@ void ios_setBookmarkDictionaryName(NSString* name) {
9698 ios_bookmarkDictionaryName = name;
9799}
98100
101+ void ios_printBookmarkedVersion (char * p) {
102+ // p is a directory. See if there is a bookmark that can make it shorter:
103+ NSString * pathString = [NSString stringWithUTF8String: p];
104+ if ([pathString hasPrefix: @" /private" ]) {
105+ pathString = [pathString stringByReplacingOccurrencesOfString: @" /private" withString: @" " ];
106+ }
107+ NSString *homePath;
108+ homePath = [[NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES ) lastObject ] stringByDeletingLastPathComponent ];
109+ if ([homePath hasPrefix: @" /private" ]) {
110+ homePath = [homePath stringByReplacingOccurrencesOfString: @" /private" withString: @" " ];
111+ }
112+ NSLog (@" ios_printBookmarkedVersion: %s %s " , homePath.UTF8String , pathString.UTF8String );
113+ if ([pathString hasPrefix: homePath]) {
114+ pathString = [pathString stringByReplacingOccurrencesOfString: homePath withString: @" " ];
115+ fprintf (thread_stdout, " ~%s \n " , pathString.UTF8String );
116+ return ;
117+ }
118+ if (ios_bookmarkDictionaryName == nil ) {
119+ fprintf (thread_stdout, " %s \n " , p);
120+ return ;
121+ }
122+ NSDictionary *tildeExpansionDictionary = [[NSUserDefaults standardUserDefaults ] dictionaryForKey: ios_bookmarkDictionaryName];
123+ if (tildeExpansionDictionary == nil ) {
124+ fprintf (thread_stdout, " %s \n " , p);
125+ return ;
126+ }
127+ for (NSString * bookmark in tildeExpansionDictionary) {
128+ NSString * bookmarkPath = tildeExpansionDictionary[bookmark];
129+ if ([bookmarkPath hasPrefix: @" /private" ]) {
130+ bookmarkPath = [bookmarkPath stringByReplacingOccurrencesOfString: @" /private" withString: @" " ];
131+ }
132+ if ([pathString hasPrefix: bookmarkPath]) {
133+ pathString = [pathString stringByReplacingOccurrencesOfString: bookmarkPath withString: bookmark];
134+ fprintf (thread_stdout, " ~%s \n " , pathString.UTF8String );
135+ return ;
136+ }
137+ }
138+ fprintf (thread_stdout, " %s \n " , p);
139+ }
140+
99141static NSMutableDictionary * sessionList;
100142static NSMutableDictionary * aliasDictionary;
101143
@@ -145,6 +187,8 @@ void _exit(int n) {
145187//
146188
147189void ios_signal (int signal) {
190+ // This function is probably obsolete now. If we keep using it, remember that currentSession is not necessarily the currentSession
191+ // (if currentSession started sh_session, then we might be sending the signal to the wrong session).
148192 // Signals the threads of the current session:
149193 if (currentSession != NULL ) {
150194 if (currentSession->current_command_root_thread != NULL ) {
@@ -153,6 +197,9 @@ void ios_signal(int signal) {
153197 if (currentSession->lastThreadId != NULL ) {
154198 pthread_kill (currentSession->lastThreadId , signal);
155199 }
200+ if (currentSession->mainThreadId != NULL ) {
201+ pthread_kill (currentSession->mainThreadId , signal);
202+ }
156203 }
157204}
158205
@@ -173,6 +220,16 @@ void ios_setWindowSize(int width, int height, const void* sessionId) {
173220
174221 sprintf (resizedSession->columns , " %d " , width);
175222 sprintf (resizedSession->lines , " %d " ,height);
223+ // Also send SIGWINCH to the main thread of resizedSession:
224+ if (resizedSession->current_command_root_thread != NULL ) {
225+ pthread_kill (resizedSession->current_command_root_thread , SIGWINCH);
226+ }
227+ if (resizedSession->lastThreadId != NULL ) {
228+ pthread_kill (resizedSession->lastThreadId , SIGWINCH);
229+ }
230+ if (resizedSession->mainThreadId != NULL ) {
231+ pthread_kill (resizedSession->mainThreadId , SIGWINCH);
232+ }
176233}
177234
178235extern char * libc_getenv (const char * variableName);
@@ -325,6 +382,9 @@ static void cleanup_function(void* parameters) {
325382 if (currentSession->current_command_root_thread == pthread_self ()) {
326383 currentSession->current_command_root_thread = 0 ;
327384 }
385+ if (currentSession->mainThreadId == pthread_self ()) {
386+ currentSession->mainThreadId = 0 ;
387+ }
328388}
329389
330390// Avoir calling crash_handler several times:
@@ -1380,15 +1440,14 @@ int sh_main(int argc, char** argv) {
13801440 // Only one command left
13811441 argv[0 ][0 ] = ' h' ; // prevent termination?
13821442 pid_t pid = ios_fork ();
1383- NSLog (@" Starting single command in sh -c, stored last_thread= %x pid: %d , command= %s " , currentSession->lastThreadId , pid, newCommand);
13841443 int returnValue = ios_system (newCommand);
13851444 ios_waitpid (pid);
13861445 free (newCommand);
13871446 return returnValue;
13881447 }
13891448 // If we reach this point, we have multiple commands to execute.
13901449 // Store current sesssion, create a new session specific for this, execute commands
1391- id sessionKey = @((NSUInteger )& sh_session);
1450+ id sessionKey = @((NSUInteger )sh_session);
13921451 if (sessionList != nil ) {
13931452 sessionParameters* runningShellSession = (sessionParameters*)[[sessionList objectForKey: sessionKey] pointerValue ];
13941453 if (runningShellSession != NULL ) {
@@ -1411,7 +1470,7 @@ int sh_main(int argc, char** argv) {
14111470 parentSession = currentSession;
14121471 parentDir = [fileManager currentDirectoryPath ];
14131472 }
1414- ios_switchSession (& sh_session); // create a new session
1473+ ios_switchSession (sh_session); // create a new session
14151474 // NSLog(@"after switchSession, currentDir = %s\n", [fileManager currentDirectoryPath].UTF8String);
14161475 currentSession->isMainThread = false ;
14171476 currentSession->context = sh_session;
@@ -1420,6 +1479,7 @@ int sh_main(int argc, char** argv) {
14201479 currentSession->stderr = thread_stderr;
14211480 currentSession->current_command_root_thread = NULL ;
14221481 currentSession->lastThreadId = NULL ;
1482+ currentSession->mainThreadId = parentSession->mainThreadId ;
14231483 // Need to loop twice: over each argument, and inside each argument.
14241484 // &&: keep computing until one command is in error
14251485 // ||: keep computing until one command is not in error
@@ -1453,7 +1513,7 @@ int sh_main(int argc, char** argv) {
14531513 // NSLog(@"Reset current Dir to= %s instead of %s", parentDir.UTF8String, [fileManager currentDirectoryPath].UTF8String);
14541514 [fileManager changeCurrentDirectoryPath: parentDir];
14551515 }
1456- ios_closeSession (& sh_session);
1516+ ios_closeSession (sh_session);
14571517 currentSession = parentSession;
14581518 parentSession = NULL ;
14591519 return returnValue;
@@ -2696,6 +2756,7 @@ int ios_system(const char* inputCmd) {
26962756 while (_tid == NULL ) { }
26972757 // ios_storeThreadId(_tid);
26982758 currentSession->current_command_root_thread = _tid;
2759+ if (currentSession->mainThreadId == NULL ) currentSession->mainThreadId = _tid;
26992760 // Wait for this process to finish:
27002761 if (joinMainThread) {
27012762 pthread_join (_tid, NULL );
@@ -2715,6 +2776,7 @@ int ios_system(const char* inputCmd) {
27152776 while (_tid == NULL ) { }
27162777 // ios_storeThreadId(_tid);
27172778 currentSession->current_command_root_thread = _tid;
2779+ if (currentSession->mainThreadId == NULL ) currentSession->mainThreadId = _tid;
27182780 // Wait for this process to finish:
27192781 if (joinMainThread) {
27202782 pthread_join (_tid, NULL );
0 commit comments