我正在尝试实现shell重定向,使用这个我将stdout重定向到fd1
int redirectOut(int fd1)
{
fflush(stdout);
int fd2 = dup(STDOUT_FILENO);
dup2(fd1, STDOUT_FILENO);
close(fd1);
return fd2;
}
然后我分叉并调用一个可执行文件,除了可执行文件使用putchar之外,它的工作原理。
在putchar手册页上写道它使用了stdout。
的putchar(C);相当于putc(c,stdout)。
为什么putchar不会在标准输出和我重定向流的文件中写入任何地方?
我尝试将 putchar 更改为 putc ,但它没有帮助,它可能与 stdout 这一事实有关如果 * FILE 和 STDOUT_FILENO int
如何使我的代码工作?为什么它适用于使用(code for printf)的printf
done = vfprintf (stdout, format, arg);
编辑更多代码
int executeBlocs(execBloc *bloc,int fileIn,int fileOut){
if(bloc->first != NULL){
if (strcmp(bloc->ope, ">") == 0){
int out = open(bloc->command[0], O_WRONLY | O_CREAT | O_TRUNC , 0644);
int returnCode = executeBlocs(bloc->first, STDIN_FILENO, out);
redirectOut(fileOut);
redirectIn(fileIn);
return returnCode;
}
}
else{
redirectIn(fileIn);
redirectOut(fileOut);
return call(bloc->nbWords, bloc->command);
}
}
execBloc是一个结构,它包含一个执行命令(或文件名)和一个运算符(>>,|,> ...)以及对包含该命令其余部分的另一个bloc的引用。
如果用户输入 cat / tmp / testCat> / tmp / testCatRedirection
然后将创建包含运算符&gt; 和命令 / tmp / testCatRedirection 的第一个结构,首先是对包含命令<的第二个结构的引用em> cat / tmp / testCat
int call(int argc, char const *argv[]) {
if (argc > 0){
if (executeProgram(argv) == 1) return 1;
if (executeStandardLibrary(argc, argv) == 1) return 1;
if (executeDynamicLibrary(argc, argv) == 1) return 1;
}
return -1;
}
int executeProgram(char const *argv[]){
//Creation de la chaine de caractère /home/kerdam/cbin/nonExecutable
char *path = strdup(binFolder);
strcat(path, argv[0]);
//Test si le fichier existe et est executable
if (access(path, F_OK|X_OK) != -1){
//Le fichier existe et on peut l'éxecuter
int pid = fork();
// Error
if (pid == -1){
return -1;
}
//Fils
else if (pid == 0) {
// Executer la commande
execv(path, argv);
return 1;
}
// Parent process
else {
// Wait for child process to finish
int childStatus;
waitpid(pid, &childStatus, 0);
return 1;
}
}
else return -1;
}
最后我试图执行的程序代码
#include<stdio.h>
#include<string.h>
#define MAX_FILE_NAME_CHARS 255
int main(int argc, char *argv[])
{
FILE *fp;
char file_name[MAX_FILE_NAME_CHARS], ch;
int i;
/*
* after creating a.out, rename it as mycat for our own cat command
* and it usage is same as standard cat command
*/
if(argc<=1){
printf("Utiliser cat avec aumoin un argument (un fichier) <nomfichier> \n");
return 0;
}
/*
* This is for multiple file in argument
*/
for(i=1; i<=argc;i++){
strncpy(file_name, argv[i], MAX_FILE_NAME_CHARS);
fp=fopen(file_name, "r");
if(fp == NULL) {
printf("%s: No such file or directory\n", file_name);
return 0;
}
/*
* read file and feed contents to STDIO
*/
while((ch=fgetc(fp)) != EOF || ch == '}'){
putchar(ch);
}
fclose(fp);
}
return 0;
}
备注
我不应该更改我尝试执行的可执行文件的代码,因为我的shell用户应该能够执行他们的程序而不受限制他们可以使用的功能。
答案 0 :(得分:0)
我遇到了同样的问题并找到了解决方案。
看一下读取文件argv[1]
并将其内容写入文件argv[2]
的代码,没有空格和换行符。
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, const char* argv[]) {
if (argc != 3) {
printf ("Expected exactly two arguments\n");
return 1;
}
int rd = open(argv[1], O_RDONLY);
if (rd == -1) {
printf ("Failed to open file %s\n", argv[1]);
return 1;
}
int wd = open(argv[2], O_WRONLY | O_TRUNC | O_CREAT, 0666);
if (wd == -1) {
printf ("Failed to open file %s\n", argv[2]);
return 1;
}
int temp_in = dup(0);
int temp_out = dup(1);
dup2(rd, 0);
dup2(wd, 1);
close(rd);
close(wd);
int written_bytes = 0;
int c;
while ((c = getchar()) != EOF) {
if (c == ' ' || c == '\n') {
continue;
}
putchar(c);
written_bytes++;
}
// The instruction below is critically important, because
// putchar by default writes char to an internal buffer,
// so we have to send it to the file descriptor manually
fflush(stdout);
dup2(temp_in, 0);
dup2(temp_out, 1);
printf ("%d bytes have been written\n", written_bytes);
return 0;
}