mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 22:02:44 +00:00 
			
		
		
		
	
							parent
							
								
									c6e79bd53a
								
							
						
					
					
						commit
						aee99b05a6
					
				
					 3 changed files with 72 additions and 37 deletions
				
			
		|  | @ -60,7 +60,9 @@ Vector<Subcommand> Parser::parse() | |||
|             if (ch == '>') { | ||||
|                 commit_token(); | ||||
|                 begin_redirect_write(STDOUT_FILENO); | ||||
|                 m_state = State::InRedirectionPath; | ||||
| 
 | ||||
|                 // Search for another > for append.
 | ||||
|                 m_state = State::InWriteAppendOrRedirectionPath; | ||||
|                 break; | ||||
|             } | ||||
|             if (ch == '<') { | ||||
|  | @ -79,6 +81,18 @@ Vector<Subcommand> Parser::parse() | |||
|             } | ||||
|             m_token.append(ch); | ||||
|             break; | ||||
|         case State::InWriteAppendOrRedirectionPath: | ||||
|             if (ch == '>') { | ||||
|                 commit_token(); | ||||
|                 m_state = State::InRedirectionPath; | ||||
|                 ASSERT(m_redirections.size()); | ||||
|                 m_redirections[m_redirections.size() - 1].type = Redirection::FileWriteAppend; | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
|             // Not another > means that it's probably a path.
 | ||||
|             m_state = InRedirectionPath; | ||||
|             [[fallthrough]]; | ||||
|         case State::InRedirectionPath: | ||||
|             if (ch == '<') { | ||||
|                 commit_token(); | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ | |||
| #include <AK/Vector.h> | ||||
| 
 | ||||
| struct Redirection { | ||||
|     enum Type { Pipe, FileWrite, FileRead, Rewire }; | ||||
|     enum Type { Pipe, FileWrite, FileWriteAppend, FileRead, Rewire }; | ||||
|     Type type; | ||||
|     int fd { -1 }; | ||||
|     int rewire_fd { -1 }; | ||||
|  | @ -33,6 +33,7 @@ private: | |||
|         Free, | ||||
|         InSingleQuotes, | ||||
|         InDoubleQuotes, | ||||
|         InWriteAppendOrRedirectionPath, | ||||
|         InRedirectionPath, | ||||
|     }; | ||||
|     State m_state { Free }; | ||||
|  |  | |||
|  | @ -233,24 +233,27 @@ static int run_command(const String& cmd) | |||
| #ifdef SH_DEBUG | ||||
|     for (int i = 0; i < subcommands.size(); ++i) { | ||||
|         for (int j = 0; j < i; ++j) | ||||
|             printf("    "); | ||||
|             dbgprintf("    "); | ||||
|         for (auto& arg : subcommands[i].args) { | ||||
|             printf("<%s> ", arg.characters()); | ||||
|             dbgprintf("<%s> ", arg.characters()); | ||||
|         } | ||||
|         printf("\n"); | ||||
|         dbgprintf("\n"); | ||||
|         for (auto& redirecton : subcommands[i].redirections) { | ||||
|             for (int j = 0; j < i; ++j) | ||||
|                 printf("    "); | ||||
|             printf("  "); | ||||
|                 dbgprintf("    "); | ||||
|             dbgprintf("  "); | ||||
|             switch (redirecton.type) { | ||||
|             case Redirection::Pipe: | ||||
|                 printf("Pipe\n"); | ||||
|                 dbgprintf("Pipe\n"); | ||||
|                 break; | ||||
|             case Redirection::FileRead: | ||||
|                 printf("fd:%d = FileRead: %s\n", redirecton.fd, redirecton.path.characters()); | ||||
|                 dbgprintf("fd:%d = FileRead: %s\n", redirecton.fd, redirecton.path.characters()); | ||||
|                 break; | ||||
|             case Redirection::FileWrite: | ||||
|                 printf("fd:%d = FileWrite: %s\n", redirecton.fd, redirecton.path.characters()); | ||||
|                 dbgprintf("fd:%d = FileWrite: %s\n", redirecton.fd, redirecton.path.characters()); | ||||
|                 break; | ||||
|             case Redirection::FileWriteAppend: | ||||
|                 dbgprintf("fd:%d = FileWriteAppend: %s\n", redirecton.fd, redirecton.path.characters()); | ||||
|                 break; | ||||
|             default: | ||||
|                 break; | ||||
|  | @ -267,36 +270,53 @@ static int run_command(const String& cmd) | |||
|     for (int i = 0; i < subcommands.size(); ++i) { | ||||
|         auto& subcommand = subcommands[i]; | ||||
|         for (auto& redirection : subcommand.redirections) { | ||||
|             if (redirection.type == Redirection::Pipe) { | ||||
|                 int pipefd[2]; | ||||
|                 int rc = pipe(pipefd); | ||||
|                 if (rc < 0) { | ||||
|                     perror("pipe"); | ||||
|                     return 1; | ||||
|             switch (redirection.type) { | ||||
|                 case Redirection::Pipe: { | ||||
|                     int pipefd[2]; | ||||
|                     int rc = pipe(pipefd); | ||||
|                     if (rc < 0) { | ||||
|                         perror("pipe"); | ||||
|                         return 1; | ||||
|                     } | ||||
|                     subcommand.redirections.append({ Redirection::Rewire, STDOUT_FILENO, pipefd[1] }); | ||||
|                     auto& next_command = subcommands[i + 1]; | ||||
|                     next_command.redirections.append({ Redirection::Rewire, STDIN_FILENO, pipefd[0] }); | ||||
|                     fds.add(pipefd[0]); | ||||
|                     fds.add(pipefd[1]); | ||||
|                     break; | ||||
|                 } | ||||
|                 subcommand.redirections.append({ Redirection::Rewire, STDOUT_FILENO, pipefd[1] }); | ||||
|                 auto& next_command = subcommands[i + 1]; | ||||
|                 next_command.redirections.append({ Redirection::Rewire, STDIN_FILENO, pipefd[0] }); | ||||
|                 fds.add(pipefd[0]); | ||||
|                 fds.add(pipefd[1]); | ||||
|             } | ||||
|             if (redirection.type == Redirection::FileWrite) { | ||||
|                 int fd = open(redirection.path.characters(), O_WRONLY | O_CREAT, 0666); | ||||
|                 if (fd < 0) { | ||||
|                     perror("open"); | ||||
|                     return 1; | ||||
|                 case Redirection::FileWriteAppend: { | ||||
|                     int fd = open(redirection.path.characters(), O_WRONLY | O_CREAT | O_APPEND, 0666); | ||||
|                     if (fd < 0) { | ||||
|                         perror("open"); | ||||
|                         return 1; | ||||
|                     } | ||||
|                     subcommand.redirections.append({ Redirection::Rewire, redirection.fd, fd }); | ||||
|                     fds.add(fd); | ||||
|                     break; | ||||
|                 } | ||||
|                 subcommand.redirections.append({ Redirection::Rewire, redirection.fd, fd }); | ||||
|                 fds.add(fd); | ||||
|             } | ||||
|             if (redirection.type == Redirection::FileRead) { | ||||
|                 int fd = open(redirection.path.characters(), O_RDONLY); | ||||
|                 if (fd < 0) { | ||||
|                     perror("open"); | ||||
|                     return 1; | ||||
|                 case Redirection::FileWrite: { | ||||
|                     int fd = open(redirection.path.characters(), O_WRONLY | O_CREAT, 0666); | ||||
|                     if (fd < 0) { | ||||
|                         perror("open"); | ||||
|                         return 1; | ||||
|                     } | ||||
|                     subcommand.redirections.append({ Redirection::Rewire, redirection.fd, fd }); | ||||
|                     fds.add(fd); | ||||
|                     break; | ||||
|                 } | ||||
|                 subcommand.redirections.append({ Redirection::Rewire, redirection.fd, fd }); | ||||
|                 fds.add(fd); | ||||
|                 case Redirection::FileRead: { | ||||
|                     int fd = open(redirection.path.characters(), O_RDONLY); | ||||
|                     if (fd < 0) { | ||||
|                         perror("open"); | ||||
|                         return 1; | ||||
|                     } | ||||
|                     subcommand.redirections.append({ Redirection::Rewire, redirection.fd, fd }); | ||||
|                     fds.add(fd); | ||||
|                     break; | ||||
|                 } | ||||
|                 case Redirection::Rewire: | ||||
|                     break; // ignore
 | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Robin Burchell
						Robin Burchell