1515#include <buildin/path.h>
1616
1717#define GET_CWD (cwd ) char cwd[64] = { 0 }; set_env(SYS_GET_PWD_ID, cwd)
18- #define PIPE_BUFFER_SIZE 65536
1918
20- static pipe_t * make_pipe (char * buffer , int size , int pos ) {
19+ pipe_t * make_pipe (char * buffer , int size , int pos ) {
2120 pipe_t * p = malloc (sizeof (pipe_t ));
2221 p -> buffer = buffer ;
2322 p -> size = size ;
2423 p -> pos = pos ;
2524 return p ;
2625}
2726
28- bool command_received (char * command , bool * should_break , pipe_t * stdin_pipe ) {
27+ bool command_received (char * command , bool * should_break , pipe_t * stdin_pipe , pipe_t * stdout_final_pipe ) {
2928 * should_break = false;
3029
3130 int token_pos = 0 ;
@@ -37,7 +36,7 @@ bool command_received(char* command, bool* should_break, pipe_t* stdin_pipe) {
3736 pipe_t * command_stdin = stdin_pipe ;
3837
3938 if (cmd_type == NORMAL ) { //Normal command, just run it and send the stdin
40- int found_command = run_command (command , terminal_envp , should_break , command_stdin , NULL );
39+ int found_command = run_command (command , terminal_envp , should_break , command_stdin , & stdout_final_pipe );
4140 if (!found_command ) {
4241 printf ("Error: Command not found: '%s'\n" , command );
4342 }
@@ -101,7 +100,7 @@ bool command_received(char* command, bool* should_break, pipe_t* stdin_pipe) {
101100 stdout_pipe -> size = stdout_pipe -> pos ;
102101 stdout_pipe -> pos = 0 ;
103102 }
104- found_command = command_received (next_command , should_break , stdout_pipe );
103+ found_command = command_received (next_command , should_break , stdout_pipe , stdout_final_pipe );
105104 }
106105
107106 if (stdout_pipe != NULL ) { //Make sure to free the stdout if it was allocated
@@ -147,12 +146,72 @@ static int pipe_printf(pipe_t* out, const char *fmt, ...) {
147146 return printed ;
148147}
149148
150- bool command_received (char * command , bool * should_break , pipe_t * stdin_pipe );
151149void system_command_handler (char * in ) {
152150 bool should_break = false;
153- command_received (in , & should_break , NULL );
151+ command_received (in , & should_break , NULL , NULL );
154152}
155153
154+ void append_char (char * * result , int * result_capacity , int * result_len , char c ) {
155+ if (* result_len + 1 >= * result_capacity ) {
156+ * result_capacity *= 2 ;
157+ * result = realloc (* result , * result_capacity );
158+ }
159+ (* result )[(* result_len )++ ] = c ;
160+ (* result )[* result_len ] = '\0' ;
161+ }
162+
163+ char * execute_command_substitutions (char * command ) {
164+ char * result = malloc (512 );
165+ int result_capacity = 512 ;
166+ int result_len = 0 ;
167+
168+ while (* command ) {
169+ char * substitution = malloc (65 );
170+ int substitution_capacity = 64 ;
171+ int substitution_len = 0 ;
172+
173+ if (command [0 ] == '$' && command [1 ] == '(' ) {
174+ command += 2 ; // Skip past '$('
175+
176+ char prev = '(' ;
177+ while (* command != ')' || prev == '\\' ) {
178+ prev = * command ++ ;
179+ if (prev == '\\' ) {
180+ continue ;
181+ }
182+
183+ append_char (& substitution , & substitution_capacity , & substitution_len , prev );
184+ }
185+
186+
187+ bool should_break ;
188+ pipe_t * stdout_final_pipe = make_pipe (malloc (PIPE_BUFFER_SIZE ), PIPE_BUFFER_SIZE , 0 );
189+ command_received (substitution , & should_break , NULL , stdout_final_pipe );
190+
191+ for (int j = 0 ; j < stdout_final_pipe -> pos ; j ++ ) {
192+ append_char (& result , & result_capacity , & result_len , stdout_final_pipe -> buffer [j ]);
193+ }
194+
195+ free (stdout_final_pipe -> buffer );
196+ free (stdout_final_pipe );
197+
198+ free (substitution );
199+
200+ command ++ ; // Skip past ')'
201+
202+ if (result_len > 0 && result [result_len - 1 ] == '\n' ) {
203+ result [result_len - 1 ] = '\0' ;
204+ result_len -- ;
205+ }
206+ } else {
207+ append_char (& result , & result_capacity , & result_len , * command ++ );
208+ }
209+ }
210+
211+ return result ;
212+ }
213+
214+
156215bool run_command (char * command , char * * terminal_envp , bool * should_break , pipe_t * stdin_pipe , pipe_t * * stdout_pipe ) {
157216 pipe_t * outgoing_stdout = stdout_pipe ? * stdout_pipe : NULL ;
158217 pipe_t * incoming_stdin = stdin_pipe ;
@@ -170,8 +229,10 @@ bool run_command(char* command, char** terminal_envp, bool* should_break, pipe_t
170229 } else if (strncmp (command , (char * )"pwd" , 3 ) == 0 ) {
171230 pwd (outgoing_stdout );
172231 } else if (strncmp (command , (char * )"export " , 7 ) == 0 ) {
173- char * argv_str = read_env (command );
232+ char * new_command = execute_command_substitutions (command );
233+ char * argv_str = read_env (new_command );
174234 export (argv_str , outgoing_stdout );
235+ free (new_command );
175236 free (argv_str );
176237 } else if (strncmp (command , (char * )"fault " , 6 ) == 0 ) {
177238 char * argv_str = read_env (command );
@@ -182,15 +243,18 @@ bool run_command(char* command, char** terminal_envp, bool* should_break, pipe_t
182243 } else if (strcmp (command , (char * )"exit" ) == 0 ) {
183244 * should_break = true;
184245 } else {
185- char * * argv = argv_split (command );
246+ char * new_command = execute_command_substitutions (command );
247+ char * * argv = argv_split (new_command );
186248 argv = argv_env_process (argv );
187249
188250 int pid = spawn_process (argv , terminal_envp , outgoing_stdout , incoming_stdin );
189251 if (pid == -1 ) {
252+ free (new_command );
190253 free_argv (argv );
191254 return false;
192255 }
193256
257+ free (new_command );
194258 free_argv (argv );
195259 }
196260
@@ -401,7 +465,7 @@ int spawn_process(char** argv, char** terminal_envp, pipe_t* stdout, pipe_t* std
401465 char out [0x1000 ] = { 0 };
402466 if (ipc_message_ready (IPC_CONNECTION_TERMINAL , (void * ) out )) {
403467 bool should_break = false;
404- command_received (out , & should_break , NULL );
468+ command_received (out , & should_break , NULL , NULL );
405469 ipc_ok (IPC_CONNECTION_TERMINAL );
406470 }
407471 set_wait_and_yield ();
@@ -417,4 +481,4 @@ int spawn_process(char** argv, char** terminal_envp, pipe_t* stdout, pipe_t* std
417481done :
418482 free (executable );
419483 return pid ;
420- }
484+ }
0 commit comments