У меня есть короткое, легкое для понимания части кода:
#include <stdio.h>
#include <unistd.h>
int main(){
char buff[0x10];
read(STDIN_FILENO, buff, 0x10);
int result = write(STDIN_FILENO, buff, 0x10);
printf("\n%d\n", result);
return 0;
}
Я записал эту крошечную программу для наблюдения различия между предоставлением, введенным путем ввода с клавиатуры по сравнению с путем перенаправления из файла. Когда я ввел вход abcdefgh12345678
затем хит Входит, программа дала результат:
abcdefgh12345678
abcdefgh12345678
16
Но затем я создал названный файл input
который содержавший abcdefgh12345678
затем дал его нашей программе, как введено ./program < input
результат программы был:
-1
Я отладил и узнал, что код ошибки равнялся 9, который означал, что STDIN был занят, поскольку он открывался для чтения в buff
.
Мой вопрос: Что может я делать, или что является обходным решением для предоставления входа программе, не имея необходимость вводить с клавиатуры так, чтобы это не вызывало ошибку когда write()
функция вызвана?
write(STDIN_FILENO, ...)
возвратится-1 когда STDIN_FILENO
не подключен к терминалу, например, когда он прибывает из канала как в ./main < input
. Можно использовать isatty(3)
проверять, подключен ли stdin к терминалу. Как заметка на полях, это - хорошая практика для проверки write()
код возврата в программе и позволил пользователю знать, что вещи были неправильными путем печати соответствующего сообщения errno и только для записи столько же символов, сколько считано read()
. Ваша программа могла быть похожей на это:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
int main(void){
char buff[0x10];
size_t count = read(STDIN_FILENO, buff, 0x10);
printf("isatty(STDIN_FILENO): %d\n", isatty(STDIN_FILENO));
int result = write(STDIN_FILENO, buff, count);
if (result == -1)
{
perror("write");
return EXIT_FAILURE;
}
printf("\nresult: %d\n", result);
return 0;
}
Результат:
$ ./main
abcdefgh12345678
isatty(STDIN_FILENO): 1
abcdefgh12345678
result: 16
$ ./main < input
isatty(STDIN_FILENO): 0
write: Bad file descriptor