2016-04-07 2 views
0

Привет, я программировал оболочку в c, и я застрял при попытке перенаправления. Хотя перенаправление stdout в моей программе работает, stdin этого не делает.Перенаправление ввода и вывода в оболочке

void redirect(node_t* node){ 
    // mode 0: >$%d mode 1: < mode 2: > mode 3: >> 
    int input = 0; 
    if(node->redirect.mode == 2){ 
     input = 1; // > 
    } else{ 
     input = 0; // < 
    } 
    int pid = 0; 
    int *status = 0; 
    char * filename = node->redirect.target; // filename 
    int fd; 
    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC); 
    if((pid = fork()) == 0){ 
     dup2(fd, input); // STDIN OR STDOUT 
     close(fd); 
     node_t* node2 = node->redirect.child; 
     execvp(node2->command.program, node2->command.argv); // execute program 
     printf("failed to execvp\n"); 
     exit(1);   
    } else { 
     wait(status); 
    } 
} 

Я новичок в fork(), но мой вопрос, что я здесь делаю неправильно, что перенаправление STDOUT работы, но это стандартный ввод ничего не пишет к данному файлу.

+1

С момента открытия filedescriptor 'O_WRONLY | O_CREAT | O_TRUNC', дочерний процесс не может читать данные из него. Вам нужно будет открыть его 'O_RDONLY' в случае перенаправления stdin. – Ctx

+0

@Ctx Я заменил 'O_WRONLY' на' O_RDONLY', но это не повлияло. Но почему он должен готовить любые данные, так как мне нужно написать stdin? –

+1

Перенаправление stdin процесса обычно означает дать ему filedescriptor _read_ (это просто соглашение, технически, конечно, можно писать и в stdin). – Ctx

ответ

1

Как указано в комментариях, вам нужно использовать разные открытые опции в зависимости от того, открываете ли вы файл для перенаправления ввода или вывода. Вы можете поместить это в свой if.

int flags; 
if(node->redirect.mode == 2){ 
    input = 1; // > 
    flags = O_WRONLY | O_CREAT | O_TRUNC; 
} else{ 
    input = 0; // < 
    flags = O_RDONLY; 
} 
int pid = 0; 
int *status = 0; 
char * filename = node->redirect.target; // filename 
int fd; 
fd = open(filename, flags, 0666); 

Также необходимо указать режимы разрешений для случая, когда создается выходной файл. Все в порядке, чтобы указать этот аргумент все время, он будет игнорироваться, если O_CREAT не находится в флагах.

+0

Это сработало благодаря вашему ответу. Этот вопрос оказался «как правильно открыть регистраторы». –

Смежные вопросы