c - 从进程中提取命令(使用 PID)

标签 c exec fork signals

我正在用 C 实现简单的 shell 模拟器。它应该支持在后台运行命令(例如 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] Done: sleep 的内容。

我不能使用上次运行的命令的简单全局变量,因为在后台运行一些命令后,前台可能会出现更多新命令,并将重写该全局变量。示例:

> 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
>

有什么办法吗?非常感谢!

最佳答案

您可以创建一个列表来将 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);
}

关于c - 从进程中提取命令(使用 PID),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9532634/

相关文章:

html - 用C从html文件中提取纯文本

c - 我如何找到由套接字 SOCK_DGRAM 选项创建的 ip/udp header

c++ - 在 C++ 中将一维数组作为二维数组访问

c - Widechar 排序并从文件加载

exec - 您已经激活了 rake 10.1 .1,但您的 Gemfile 需要 rake 10.4.2。在您的通讯前面添加 `bundle exec` 可能会解决此问题。

java - 带有 cat 命令的 android getRuntime().exec()

php - 使用 php 使用 sudo 执行命令

c - 尝试调用 execvp 来运行通过标准输入提供的程序名,但每次调用都失败

php - 在后台线程/进程中调用函数( fork )

c - 这些 fork() 语句的进程树是什么样子的?