Перенаправление ввода и вывода в оболочке - PullRequest
0 голосов
/ 20 ноября 2018

Я пытаюсь реализовать перенаправление ввода и вывода - это C. Я прочитал все ответы на этот вопрос, но он не работает! Идет до последнего if (execvp).

Я хочу что-то вроде этого:

перенаправление вывода: ls -al > output.txt

перенаправление ввода: sort < input.txt

Вот код, который я написал:

int io_redirection(char * args[], char* inputFile, char* outputFile, int option){

    int err = -1;

    int fileDescriptor = -1; // between 0 and 19
    pid_t pid = -10;
    pid = fork();

    if(pid==-1){
        printf("Child process could not be created\n");
        return;
    }
    if(pid==0){
        // Option 0: output redirection
        if (option == 0){
            // I also tried fileDescriptor = creat(outputFile, 0644);
            fileDescriptor = open(outputFile, O_CREAT | O_TRUNC | O_WRONLY, 0600); 
            dup2(fileDescriptor, STDOUT_FILENO); 
            close(fileDescriptor);


        }
         else if (option == 1){
            // Option 1: input redirection

            fileDescriptor = open(inputFile, O_RDONLY, 0600);  
            dup2(fileDescriptor, STDIN_FILENO);
            close(fileDescriptor);

        }



        if (execvp(args[0],args)==err){
            printf("err");
            kill(getpid(),SIGTERM);
        }        
    }
    waitpid(pid,NULL,0);
}

для перенаправления вывода args содержит ls и -al. А для входного он содержит sort.

Ответы [ 2 ]

0 голосов
/ 20 ноября 2018

Возможно, ваш тест неправильный, я использую следующий code тест правильный.

int main() {
  char* argv[] = {"ls", "-al", NULL};
  io_redirection(argv, NULL, "test", 0);

  return 0;
}
0 голосов
/ 20 ноября 2018

execvp требует NULL в качестве последнего параметра.Я предполагаю, что ваш командный синтез игнорирует это, остальное работает как задумано.

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<fcntl.h>
#include<signal.h>
#include<sys/wait.h>


void print_child_status (int status) {
  if (WIFEXITED (status)) {
    fprintf (stdout, "Child exited with status %d\n", WEXITSTATUS (status));
  } else if (WIFSTOPPED (status)) {
    fprintf (stdout, "Child stopped by signal %d (%s)\n", WSTOPSIG (status), strsignal (WSTOPSIG (status)));
  } else if (WIFSIGNALED (status)) {
    fprintf (stdout, "Child killed by signal %d (%s)\n", WTERMSIG (status), strsignal (WTERMSIG (status)));
  } else {
    fprintf (stdout, "Unknown child status\n");
  }
}

int io_redirection(char * args[], char* inputFile, char* outputFile, int option){

    int err = -1;

    int fileDescriptor = -1; // between 0 and 19
    pid_t pid = -10;
    pid = fork();

    if(pid==-1){
        printf("Child process could not be created\n");
        return -1;
    }
    else if(pid == 0){
        // Option 0: output redirection
        if (option == 0){
            // I also tried fileDescriptor = creat(outputFile, 0644);
            fileDescriptor = open(outputFile, O_CREAT | O_TRUNC | O_WRONLY, 0600); 
            dup2(fileDescriptor, STDOUT_FILENO); 
            close(fileDescriptor);


        }
         else if (option == 1) {
            // Option 1: input redirection
            fileDescriptor = open(inputFile, O_RDONLY);
             printf("Input redirection %d\n", fileDescriptor);
            dup2(fileDescriptor, STDIN_FILENO);
            close(fileDescriptor);

        }
        err = execvp(args[0], args);

        if (err){
            printf("err %d\n", err);
        }
        return err;
    } else {
        int status;
        waitpid(pid, &status,0);
        print_child_status(status);
    }
    return 0;

}

int main() {
    char * args[] = {"ls", "-l", NULL};
    io_redirection(args, NULL, "out.txt", 0);
    char * args1[] = {"grep", "main", NULL};
    io_redirection(args1, "./test.c", NULL, 1);
    return 0;
}
...