C语言 尝试使用dup2()和open()和execv()将文件重定向到stdin时出现问题



编辑:问题是echo显然不从stdin读取。谢谢@Jonathan Leffler

我有一个编程练习,我的代码如下:
int processProgram(char **tokens, int requireWait) {
char *cmd = tokens[0];
if (access(cmd, R_OK) == -1) {
printf("%s not foundn", cmd);
return -1;
}
int index = 1;
char *iterator = tokens[index];
int inputTokenIndex = 0;
// Look for a < to figure out where the redirection is
while (iterator != NULL) {
if (strcmp(iterator, "<") == 0) {                      // <---- THIS IS WHERE I ATTEMPT TO FIND THE INDEX OF "<"
if (access(tokens[index + 1], R_OK) == -1) {
printf("%s does not existn", tokens[index + 1]);
return -1;
}
// set null at <
tokens[index] = NULL;
inputTokenIndex = index + 1;
break;
}
index++;
iterator = tokens[index];
}
// basically create a struct to store pids and stuff....
processList *process = addNewProcess();
int childPid = fork();
if (childPid == 0) {
// is the child
if (inputTokenIndex > 0) {
// if previously strcmp "<" is true
// set redirection for input....
int fd = open(tokens[inputTokenIndex], O_RDONLY);   // <----- THIS IS WHERE I DO THE REDIRECTING FOR STDIN!
dup2(fd, STDIN_FILENO);
close(fd);
}
// start from where inputTokenIndex could have left off
// since > is always at least after < in our test cases
index = inputTokenIndex + 1;
iterator = tokens[index];
while (iterator != NULL) {                            // <--- LOOKING FOR ">" and "2>", CURRENTLY THIS WORKS FINE
// look for output redirection FROM previous while loop onwards
int out = 0;
if (strcmp(iterator, ">") == 0) {
// stdout
out = STDOUT_FILENO;
} else if (strcmp(iterator, "2>") == 0) {
// stderr
out = STDERR_FILENO;
}
if (out != 0) {
int fd = open(tokens[index + 1], O_WRONLY | O_TRUNC | O_CREAT, 0777);
dup2(fd, out);
tokens[index] = NULL;
close(fd);
}
index++;
iterator = tokens[index];
}

int value = execv(cmd, tokens);                  // <----- EXEC IS HERE!!
if (value == -1) {
exit(errno);
}
exit(0);
} else {
int status;
if (requireWait == 1) {
// wait for process to finish
process->pid = childPid;
wait(&status);
process->running = 0;
process->status = status;
if (status != 0) {
printf("%s failed", cmd);
}
} else {
process->pid = childPid;
printf("Child[%d] in backgroundn", childPid);
// no return should be expected
status = 0;
}
return status;
}
}

这个想法是模拟linux重定向使用<和在>

tokens是提供给shell的字符串数组。

向"a.t txt"写入hello的示例调用:/bin/echo hello>。/a.txt

它不能用于重定向in,即"/bin/echo

文件a.txt是使用这个程序创建的。完整的例子是

/bin/echo hellooooo>。/a.txt

/bin/echo & lt;。/a.txt

,其中第一个命令成功创建并写入a.t txt,但第二个命令只生成一个空行

如何帮助

假设tokens是正确的,并且文件名存在,为什么execv()调用不从文件名中接收输入(假设我重定向了它????)

谢谢你的阅读!!

正如我在评论中指出的那样,echo命令不读取标准输入,因此您将无法判断echo(或sleep)的输入重定向是否成功。

使用一个读取标准输入的命令——cat是最简单的例子,但trsed可能是明智的选择。

相关内容

  • 没有找到相关文章

最新更新