2015-07-16 2 views
0

Я создаю небольшую оболочку, и у меня возникают некоторые проблемы с двумя из моих функций. Они вроде бы вне контекста, но я надеюсь, что вы поймете, что я пытаюсь сделать, поэтому мне не нужно публиковать весь мой код.Создание собственных редиректов и дублирующих функций труб

Моя функция dupPipe: Я хочу дублировать трубу в дескриптор файла ввода-вывода std и закрыть оба конца трубы. Это выглядит так: int dupPipe(int pip[2], int end, int destinfd);. Где конец указывает, какой канал дублировать, либо READ_END, либо WRITE_END, и destinfd сообщает, какой дескриптор файла ввода std заменить.

My Redirect function: Предполагается перенаправить дескриптор файла ввода/вывода std в файл. Похоже, это int redirect(char *file, int flag, int destinfd);. Где флаг указывает, следует ли читать или записывать файл, а destinfd - дескриптор файла std I/O, который я хочу перенаправить.

То, что я сделал:

int dupPipe(int pip[2], int end, int destinfd) 
{ 
if(end == READ_END) 
{ 
    dup2(pip[0], destinfd); 
    close(pip[0]); 
} 
else if(end == WRITE_END) 
{ 
    dup2(pip[1], destinfd); 
    close(pip[1]); 
} 
return destinfd; 
} 

Вторая функция:

int redirect(char *filename, int flags, int destinfd) 
{ 
if(flags == 0) 
{ 
    return destinfd; 
} 
else if(flags == 1) 
{ 
    FILE *f = fopen(filename, "w"); 
    if(! f) 
    { 
     perror(filename); 
     return -1; 
    } 
} 
else if(flags == 2) 
{ 
    FILE *f = fopen(filename, "r"); 
    if(! f) 
    { 
     perror(filename); 
     return -1; 
    } 
} 
return destinfd; 
} 

Я признателен за любую помощь, оказанную, то, что я сделал неправильно или не сделали с функцией, которую я написал хотел ? Благодарю.

+0

is destfd == destinfd? –

+0

Вы не используете dup2 return, и вы должны использовать функцию «open» – eroween

ответ

0

Функция redirect, похоже, не делает то, что вы хотите. Вы открываете файл, используя fopen, но вы не связываете его с destinfd в любом случае. Возможно, вы захотите использовать open, а затем используйте dup2 для перемещения дескриптора файла туда, где хотите.

int redirect(char *filename, int flags, int destinfd) 
{ 
    int newfd; 

    if(flags == 0) { 
     return -1; 
    } else if(flags == 1) { 
     newfd = open(filename, O_WRONLY); 
     if (newfd == -1) { 
      perror("open for write failed"); 
      return -1; 
     } 
    } else if(flags == 2) { 
     newfd = open(filename, O_RDONLY); 
     if (newfd == -1) { 
      perror("open for read failed"); 
      return -1; 
     } 
    } else { 
     return -1; 
    } 
    if (dup2(newfd, destinfd) == -1) { 
     perror("dup2 failed"); 
     close(newfd); 
     return -1; 
    } 
    close(newfd); 
    return destinfd; 
} 
+0

Когда 'dup2 (2)' fail, код, который обрабатывает ошибку, должен закрыть 'newfd' перед возвратом, чтобы избежать« утечки »открытых файловых дескрипторов при ошибках , Обратите внимание, что 'close (2)' может изменить значение 'errno', поэтому вы должны сохранить его заранее и затем восстановить его перед возвратом. OTOH, если 'dup2 (2)' преуспевает, тогда вы должны закрыть 'newfd', если он отличается от' destinfd', иначе 'redirect()' снова оставит дескриптор открытого файла при каждом его вызове. –

+0

Но newfd не отличается от destinfd, переменная «flags» останавливает ее от правильного? – Fjodor

+0

@Fjodor После успешного вызова 'dup2()', 'newfd' и' destinfd' ссылаются на один и тот же открытый файл, даже если их значения различаются. Как сказал Филипе, 'newfd' необходимо закрыть после вызова' dup2() '. Я также обновил свой ответ, чтобы отразить это. – dbush

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