运行此代码片段以试验管道和信号。我试图学习如何在管道之间正确使用select()函数。
这个过程会分叉。如果有从stdIn读取的内容,则将其写入管道的写入端。它应该执行通过终端输入的基本命令,或者在代码中运行硬编码命令。 (它现在正在运行硬代码,因为" ls。")
当我运行此片段时,当我按下字母时,它应该退出并完全停止运行" q"然后是ENTER,或者它应该在运行其分配的进程后退出。
相反,即使在我点击" q"或者运行它不会完全停止程序的过程。它仍在等待输入。一旦我按下ENTER,它将停止运行,但它甚至从未执行我的进程。
例如,如果我编译并运行它作为" ./ test ls"或者甚至只是运行" ./ test" (因为ls是硬编码的,所以我应该只运行),它不会运行命令ls。程序将继续运行,直到我再次点击ENTER。
我确定我对select()的基本理解与此问题有关。我很确定我的select()语句需要在某些时候中断,但我不知道检查这个的内容或方法。
我被告知有一种方法WIFEXITED()可以帮助我,但我不确定它在这种情况下是如何应用的。
我也想知道如何检查你的管道是否空了!
我知道我希望这能够从终端获取输入并记录它并运行内置函数。
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <stdio.h>
int main() {
int in[2]; // parent writes; child reads
pipe(in);
if (fork() == 0) {
// instantiate the values that will be execed
char *a[2];
//a[0] = "./test3";
a[0] = "ls";
a[1] = NULL;
// redirects what is being read from stdin to the pipe
//this redirection is for a separate test that is not included
close(in[1]);
close(0);
dup(in[0]);
close(in[0]); // close read
execvp(a[0], a);
}
else {
close(in[0]); // only want parent to write
// select() params
int nfds = 3;
int check = -1;
int done = 0;
fd_set readfds;
fd_set writefds;
FD_ZERO(&readfds); // set select params
FD_SET(0, &readfds);
FD_SET(in[1], &writefds);
while ((check = select(nfds, &readfds, &writefds, NULL, NULL)) > 0) {
int size = 0;
char buf[1000];
// write to pipe for child
if (FD_ISSET(0, &readfds) && FD_ISSET(in[1], &writefds)) {
while ((size = read(0, buf, sizeof(buf))) != 0) {
write(in[1], buf, size);
}
}
// reset
FD_ZERO(&readfds);
FD_SET(0, &readfds);
FD_SET(in[1], &writefds);
}
printf("%d --------------- %d\n", (FD_ISSET(in[1], &writefds)),
FD_ISSET(0, &readfds));
}
return 0;
}
如果取消注释[0] = ./test并且评论了[0] = ls,则可以使用上面的剪辑运行测试代码的潜在集合。
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/select.h>
int main () {
int fd;
char buf[11];
int ret, sret;
int flag = 0;
fd = 0;
fd_set readfds;
struct timeval timeout;
while(1) {
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
timeout.tv_sec = 5;
timeout.tv_usec = 0;
sret = select(fd + 1, &readfds, NULL, NULL, NULL);
memset((void *) buf, 0, 11);
ret = read(fd, (void *) buf, 10);
flag = strcmp(buf, "q\n") == 0;
if (flag) {
return 0;
}
printf("ret = %d\n", ret);
if(ret != -1) {
printf(" buf = %s\n", buf);
}
}
return 0;
}