Я написал модуль Zsh. Там у меня встроенная функция, сопоставленная с командой Zsh. Эта функция дублирует его STDIN дескриптора файла:dup (fileno (stdin)), а затем порождает 32 потока -> ошибки ввода/вывода
/* Duplicate standard input */
oconf->stream = fdopen(dup(fileno(stdin)), "r");
Затем нить порождена, получающий oconf
структуры. В этой теме, я делаю:
errno = 0;
/* Read e.g. 5 characters, putting them after previous portion */
int count = fread(buf + index, 1, read_size, oconf->stream);
/* Ensure that our whole data is a string - null terminated */
buf[ index + count ] = '\0';
if (errno) {
fprintf(oconf->err, "Read error (descriptor: %d): %s\n", fileno(oconf->stream), strerror(errno) >
}
Если я нерест 32 нити в Zsh:
for ((i=1; i<=32; i ++)); do
ls -R /Users/myuser/Documents | mybuiltin -A myhash_$i $i
done
Затем 2-3 нити имеют ошибку I/O сообщили из приведенного выше fprintf()
, например:
ошибка чтения (дескриптор: 7): Ввод/вывод ошибки
ошибки чтения (дескриптор: 5): недопустимый IOCTL для устройства
ошибка чтения (Дескриптор: 14): неприемлемое IOCTL для устройства
Debugger говорит, что эти нити, после нескольких (5-20) Fread() повторов, блокируются в ядро-х __read_nocancel()
. Так что что-то действительно плохое происходит с файловым дескриптором.
В противном случае это сработает. Труба правильно передает данные от ls -R
, она считывается пользовательским встроенным. Так где же опасность? Как получилось, что dup()
в главной теме приводит к чему-то нечитаемому до fread()
? У меня были сомнения, если бы я сделал dup()
во вторичной теме. Но я держу это только в надежном месте - основной нити, чтобы затем передать готовый поток FILE *
к вторичной теме. Также попытался с POSIX open()
, read()
и close()
, результат будет таким же.