【发布时间】:2021-05-31 07:25:43
【问题描述】:
static int pipefd[2];
static pid_t cpid = 0;
void sigtimeout(int num) {
kill(cpid, 9);
close(pipefd[1]);
close(pipefd[0]);
pipe(pipefd);
write(pipefd[1], "T/O\n", 5);
}
void settimer(float time) {
struct itimerval timer;
timer.it_value.tv_sec = (int)time;
timer.it_value.tv_usec = (timeout - (int)time) * 1000000;
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 0;
setitimer(ITIMER_REAL, &timer, NULL);
}
pid_t popen2(char *cmd) {
if (pipe(pipefd) == -1)
return -1;
int pid;
if ((pid = fork()) == -1)
return -1;
if (pid == 0) {
close(STDIN_FILENO);
close(STDERR_FILENO);
dup2(pipefd[1], STDOUT_FILENO);
close(pipefd[0]);
close(pipefd[1]);
execlp("sh", "sh", "-c", cmd, NULL);
_exit(EXIT_SUCCESS);
} else
settimer(timeout);
return pid;
}
void getcmd(const Block *block, char *output)
{
if (block->signal)
{
output[0] = block->signal;
output++;
}
strcpy(output, block->icon);
char *cmd;
if (button)
{
cmd = strcat(exportstring, block->command);
cmd[14] = '0' + button;
cpid = popen2(cmd);
if (cpid == -1) {
close(pipefd[0]);
close(pipefd[1]);
return;
}
cmd[16] = '\0';
}
else
{
cmd = block->command;
cpid = popen2(cmd);
if (cpid == -1) {
close(pipefd[0]);
close(pipefd[1]);
return;
}
}
button = 0;
waitpid(cpid, 0, 0);
settimer(0);
kill(cpid, 9);
close(pipefd[1]);
int i = strlen(block->icon);
read(pipefd[0], output+i, CMDLENGTH-i-delimLen);
close(pipefd[0]);
for (char *c = output; *c; c++)
if (*c == '\n') {
c[1] = '\0';
break;
}
i = strlen(output);
if (delim[0] != '\0') {
//only chop off newline if one is present at the end
i = output[i-1] == '\n' ? i-1 : i;
strncpy(output+i, delim, delimLen);
}
else
output[i++] = '\0';
}
所以我正在尝试修改 dwmblocks 以添加超时功能。这样,如果命令挂起,整个状态栏不会冻结。
似乎一切正常,但有一个小问题。
我的代码使我的整个 linux 系统崩溃,因为它每次运行命令时都会打开一些文件描述符。您可能知道,Linux 对此有保护,因此我系统上尝试打开文件描述符的所有其他应用程序也会崩溃。
问题是,我实际上是在关闭我在代码中打开的每个管道,即使是在你 fork 时自动打开的管道。我就是想不通是什么问题。
非常感谢任何帮助。
顺便说一句:我只是把相关代码放在这里,因为问题出在文件描述符上。这是我在代码中使用文件描述符的唯一地方。
如果您觉得在某些方面相关,请随时询问更多代码部分:)
【问题讨论】: