Извлечь команду из процесса (используя PID) - PullRequest
1 голос
/ 02 марта 2012

Я реализую простой эмулятор оболочки на C. Он должен поддерживать запуск команды в фоновом режиме (например, sleep 5s &). Поэтому я запускаю эту команду, используя последовательность fork () -> exec (), и жду завершения этой команды, используя обработчик сигнала SIGCHLD. Мой вопрос: есть ли возможность получить команду процесса (имя), которая была указана в вызове exec (). Я приведу вам пример:

//SIGCHLD signal handler (use for notification, when background process ends)
void sighandler(int sig) {
    int status;
    int pid = waitpid(-1, &status, WNOHANG);

    if (WIFEXITED(status)) {
        if (pid != -1 && pid != 0) {
            printf("\n[%d] Done: \n> ", (int) pid); //also need to provide user name (command) of exited process (ex. [PID] Done: sleep)
            fflush(stdout);
        }
    }
}

pid_t fork_pid = fork()

if (fork_pid == 0) { //child
    execl("sleep", "sleep", "5s");
} else { //parent
    ....
}

Что мне нужно, так это как-то имя доступа к команде, которое было указано в вызове exec () (см. Execl ("sleep", "sleep", "5s");) в обработчике сигналов (см. Signalhandler (int sig)) ) чтобы вывести что-то вроде [PID] Готово: сон.

Я не могу использовать простую глобальную переменную последней запущенной команды, потому что после запуска какой-либо команды в фоновом режиме, может появиться больше новой команды на переднем плане, которая перезапишет эту глобальную переменную. Пример:

> sleep 1m & //background command - variable is "sleep"
[PID of sleep process] Running in background
> ls //foreground command - variable is "ls"
> cat output //foreground command - variable is "cat"
.
.
.
[PID of sleep process] Done: sleep
>

Есть ли способ сделать это? Большое спасибо!

1 Ответ

1 голос
/ 02 марта 2012

Вы можете создать список, чтобы связать pids с командами:

void sighandler(int sig) {
            ...
            char *cmd = task_list.get(pid);
            printf("\n[%d] %s, Done: \n> ", (int) pid, cmd);
            ...
}

...    

pid_t fork_pid = fork();
char command[1024] = "sleep";
if (fork_pid == 0) { //child
      execl(command, command, "5s");
} else { //parent
      task_list.insert(pid, command);
}
...