Я пытаюсь реализовать перенаправление оболочки, используя эту команду перенаправления stdout на fd1
int redirectOut(int fd1)
{
fflush(stdout);
int fd2 = dup(STDOUT_FILENO);
dup2(fd1, STDOUT_FILENO);
close(fd1);
return fd2;
}
Затем я запускаю и вызываю исполняемый файл, он работает, за исключением случая, когда исполняемый файл использует putchar.
На странице руководства putchar написано, что он использует стандартный вывод.
путчар (с);эквивалентно putc (c, stdout).
Почему putchar ничего не записывает ни в стандартный вывод, ни в файл, в который я перенаправил поток?
Я попытался изменить putchar на putc , но это не помогло, это может быть связано с тем, что stdout , если* FILE и STDOUT_FILENO an int
Как заставить мой код работать и почему он работает с 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 - это структура, содержащая команду для выполнения (или имя файла)оператор (>>, |,> ...) и ссылка на другой блок, содержащий остальную часть команды.
Если пользователь введет cat / tmp / testCat> / tmp / testCatRedirection
, то будет создана первая структура, содержащая оператор > икоманда / tmp / testCatRedirection и первая, которая является ссылкой на вторую структуру, содержащую команду 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;
}
Примечание
Я не должен менять код исполняемого файла, который пытаюсь выполнить, поскольку пользователи моей оболочки должныспособны выполнять свои программы без ограничений на то, какую функцию они могут использовать.