Loading commands/filesystem/find.cpp +74 −1 Changes for commands/filesystem/find.cpp: 74 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -608,7 +608,7 @@ namespace fresh { namespace cmd { } public: int runCommand(int argc,const char **argv){ int executeFind(int argc,const char **argv){ State s; s.now=time(nullptr); int i=1; Loading Loading @@ -686,6 +686,79 @@ namespace fresh { namespace cmd { std::cout.flush(); return s.status; } int runCommand(int argc,const char **argv){ int pipe_idx = -1; for(int j = 1; j < argc; ++j){ if(std::string(argv[j]) == "|"){ pipe_idx = j; break; } } if(pipe_idx == -1){ return executeFind(argc, argv); } if(pipe_idx + 1 >= argc){ std::cerr << "find: missing command after '|'" << std::endl; return 1; } int pipefds[2]; if(pipe(pipefds) < 0){ std::cerr << "find: pipe failed: " << strerror(errno) << std::endl; return 1; } pid_t pid = fork(); if(pid < 0){ std::cerr << "find: fork failed: " << strerror(errno) << std::endl; close(pipefds[0]); close(pipefds[1]); return 1; } if(pid == 0){ close(pipefds[1]); dup2(pipefds[0], STDIN_FILENO); close(pipefds[0]); std::vector<std::string> down_args; for(int j = pipe_idx + 1; j < argc; ++j){ down_args.push_back(argv[j]); } std::vector<const char*> cargv; for(auto &a: down_args) cargv.push_back(a.c_str()); cargv.push_back(nullptr); ShellCommand *cmd = Shell::instance().find(down_args[0]); if(cmd) _exit(cmd->runCommand((int)down_args.size(), cargv.data())); execvp(down_args[0].c_str(), const_cast<char *const*>(cargv.data())); std::cerr << "find: " << down_args[0] << ": " << strerror(errno) << std::endl; _exit(127); } close(pipefds[0]); int saved_stdout = dup(STDOUT_FILENO); dup2(pipefds[1], STDOUT_FILENO); close(pipefds[1]); int find_status = executeFind(pipe_idx, argv); fflush(stdout); std::cout.flush(); close(STDOUT_FILENO); dup2(saved_stdout, STDOUT_FILENO); close(saved_stdout); int status = 0; while(waitpid(pid, &status, 0) < 0 && errno == EINTR){} int child_status = WIFEXITED(status) ? WEXITSTATUS(status) : 128; return (find_status != 0) ? find_status : child_status; } }; FRESH_REGISTER_COMMAND(FindCommand); Loading Loading
commands/filesystem/find.cpp +74 −1 Changes for commands/filesystem/find.cpp: 74 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -608,7 +608,7 @@ namespace fresh { namespace cmd { } public: int runCommand(int argc,const char **argv){ int executeFind(int argc,const char **argv){ State s; s.now=time(nullptr); int i=1; Loading Loading @@ -686,6 +686,79 @@ namespace fresh { namespace cmd { std::cout.flush(); return s.status; } int runCommand(int argc,const char **argv){ int pipe_idx = -1; for(int j = 1; j < argc; ++j){ if(std::string(argv[j]) == "|"){ pipe_idx = j; break; } } if(pipe_idx == -1){ return executeFind(argc, argv); } if(pipe_idx + 1 >= argc){ std::cerr << "find: missing command after '|'" << std::endl; return 1; } int pipefds[2]; if(pipe(pipefds) < 0){ std::cerr << "find: pipe failed: " << strerror(errno) << std::endl; return 1; } pid_t pid = fork(); if(pid < 0){ std::cerr << "find: fork failed: " << strerror(errno) << std::endl; close(pipefds[0]); close(pipefds[1]); return 1; } if(pid == 0){ close(pipefds[1]); dup2(pipefds[0], STDIN_FILENO); close(pipefds[0]); std::vector<std::string> down_args; for(int j = pipe_idx + 1; j < argc; ++j){ down_args.push_back(argv[j]); } std::vector<const char*> cargv; for(auto &a: down_args) cargv.push_back(a.c_str()); cargv.push_back(nullptr); ShellCommand *cmd = Shell::instance().find(down_args[0]); if(cmd) _exit(cmd->runCommand((int)down_args.size(), cargv.data())); execvp(down_args[0].c_str(), const_cast<char *const*>(cargv.data())); std::cerr << "find: " << down_args[0] << ": " << strerror(errno) << std::endl; _exit(127); } close(pipefds[0]); int saved_stdout = dup(STDOUT_FILENO); dup2(pipefds[1], STDOUT_FILENO); close(pipefds[1]); int find_status = executeFind(pipe_idx, argv); fflush(stdout); std::cout.flush(); close(STDOUT_FILENO); dup2(saved_stdout, STDOUT_FILENO); close(saved_stdout); int status = 0; while(waitpid(pid, &status, 0) < 0 && errno == EINTR){} int child_status = WIFEXITED(status) ? WEXITSTATUS(status) : 128; return (find_status != 0) ? find_status : child_status; } }; FRESH_REGISTER_COMMAND(FindCommand); Loading