Commit 0eea6c4c authored by jan.koester's avatar jan.koester
Browse files

fixed

parent d96b49e3
Loading
Loading
Loading
Loading
+74 −1
Changes for commands/filesystem/find.cpp: 74 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -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;
@@ -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);