Интересно отметить, что вы используете K & R 1st Edition 1978 года, а не второе издание. Второе издание имеет различные структуры и т. Д. На тот момент в книге.
Этот код из первого издания больше не работает на многих Unix-подобных системах. Очень мало машин Unix осталось с файловыми системами, которые ограничивают имена файлов до 14-символьного ограничения, и этот код работает только в этих системах. В частности, он не работает на MacOS X (10.6.2) или Solaris (10) или Linux (SuSE Linux Enterprise Edition 10, ядро 2.6.16.60-0.21-smp). С тестовым кодом, показанным ниже, результат:
read failed: (21: Is a directory)
Текущие выпуски POSIX явно разрешают реализации ограничивать то, что вы можете делать с файловым дескриптором, открытым в каталоге. По сути, он может использоваться в системных вызовах 'fchdir()
' и, возможно, нескольких родственниках, но это все.
Чтобы прочитать содержимое каталога, вы должны использовать семейство функций opendir()
, а затем readdir()
и т. Д. Второе издание K & R продолжается используйте эти системные вызовы вместо open()
и read()
и т. д.
В целом, неудивительно, что код более 30 лет назад работает не совсем так, как раньше.
В Windows вы можете использовать подсистему POSIX или ее эмуляцию, такую как Cygwin или MingW, и в любом случае вам придется использовать семейство вызовов функций opendir()
и readdir()
, а не прямые open()
и read()
в дескрипторе файла каталога.
Или вы можете использовать собственный Windows API, на который ссылается BillyONeal, FindFirstFile и родственников.
Тестовый код:
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
int main()
{
int fd = open(".", O_RDONLY);
if (fd != -1)
{
char buffer[256];
ssize_t n = read(fd, buffer, sizeof(buffer));
if (n < 0)
{
int errnum = errno;
printf("read failed: (%d: %s)\n", errnum, strerror(errnum));
}
else
printf("read OK: %d bytes (%s)\n", (int)n, buffer);
close(fd);
}
return(0);
}