--- io.c~ 2009-01-03 23:28:14.000000000 +0100 +++ io.c 2009-01-05 22:36:35.000000000 +0100 @@ -148,6 +148,7 @@ size_t rt_len; /* length of terminator */ }; +static DIR *iop_dirp = NULL; static IOBUF *nextfile P((int skipping)); static int inrec P((IOBUF *iop)); static int iop_close P((IOBUF *iop)); @@ -388,9 +389,12 @@ || iop->fd == fileno(stdout) || iop->fd == fileno(stderr)) ret = 0; - else - ret = close(iop->fd); - + else { + if ((iop->flag & IOP_IS_DIR) != 0) + ret = closedir(iop->dirp); + else + ret = close(iop->fd); + } if (iop->close_func != NULL) (*iop->close_func)(iop); @@ -1309,6 +1313,14 @@ /* do not set close-on-exec for inherited fd's */ if (openfd != INVALID_HANDLE) return openfd; + } else if (STREQN(name, "/dir/", 5)) { + cp = (char *) name + 5; + iop_dirp = opendir(cp); + if (iop_dirp == NULL) + openfd = INVALID_HANDLE; + else + openfd = dirfd(iop_dirp); + return openfd; } else if (STREQN(name, "/inet/", 6)) { #ifdef HAVE_SOCKETS /* /inet/protocol/localport/hostname/remoteport */ @@ -1410,8 +1422,11 @@ if (openfd == INVALID_HANDLE) openfd = open(name, flag, 0666); if (openfd != INVALID_HANDLE) { - if (os_isdir(openfd)) - fatal(_("file `%s' is a directory"), name); + if (os_isdir(openfd)) { + openfd = INVALID_HANDLE; + errno = EISDIR; + // fatal(_("file `%s' is a directory"), name); + } os_close_on_exec(openfd, name, "file", ""); } @@ -1556,6 +1571,7 @@ { "/dev/ppid", 9, pidopen }, { "/dev/pgrpid", 11, pidopen }, { "/dev/user", 9, useropen }, + { "/dir/", 5, specfdopen }, }; int devcount = sizeof(table) / sizeof(table[0]); @@ -1565,7 +1581,8 @@ openfd = fileno(stdin); else if (do_traditional) goto strictopen; - else if (STREQN(name, "/dev/", 5) || STREQN(name, "/inet/", 6)) { + else if (STREQN(name, "/dev/", 5) || STREQN(name, "/inet/", 6) || + STREQN(name, "/dir/", 5)) { int i; for (i = 0; i < devcount; i++) { @@ -1591,8 +1608,11 @@ if (openfd == INVALID_HANDLE) openfd = open(name, flag, 0666); if (openfd != INVALID_HANDLE) { - if (os_isdir(openfd)) - fatal(_("file `%s' is a directory"), name); + if (os_isdir(openfd)) { + openfd = INVALID_HANDLE; + errno = EISDIR; + // fatal(_("file `%s' is a directory"), name); + } } /* * At this point, fd could still be INVALID_HANDLE. @@ -2499,10 +2519,16 @@ } if (isatty(iop->fd)) iop->flag |= IOP_IS_TTY; - iop->readsize = iop->size = optimal_bufsize(iop->fd, & sbuf); + if (os_isdir(iop->fd)) { + iop->flag |= IOP_IS_DIR; + iop->dirp = iop_dirp; + iop->readsize = iop->size = NAME_MAX + 1; + } else { + iop->readsize = iop->size = optimal_bufsize(iop->fd, & sbuf); + } iop->sbuf = sbuf; if (do_lint && S_ISREG(sbuf.st_mode) && sbuf.st_size == 0) - lintwarn(_("data file `%s' is empty"), name); + lintwarn(_("data file `%s' is empty"), name); errno = 0; iop->count = iop->scanoff = 0; emalloc(iop->buf, char *, iop->size += 2, "iop_alloc"); @@ -2883,7 +2909,7 @@ } /* = */ -/* get_a_record --- read a record from IOP into out, return length of EOF, set RT */ +/* get_a_record --- read a record from IOP into out, return length or EOF, set RT */ int get_a_record(char **out, /* pointer to pointer to data */ @@ -2903,6 +2929,16 @@ if (iop->get_record != NULL) return (*iop->get_record)(out, iop, errcode); + if (iop->flag & IOP_IS_DIR) { + struct dirent *dent; + dent = readdir(iop->dirp); + if (dent != NULL) { + memcpy(iop->buf, dent->d_name, NAME_MAX); + *out = iop->buf; + return strlen(iop->buf); + } else + return EOF; + } /* = */ if (has_no_data(iop) || no_data_left(iop)) { iop->count = read(iop->fd, iop->buf, iop->readsize); @@ -3171,6 +3207,7 @@ { IOP_AT_EOF, "IOP_AT_EOF" }, { IOP_CLOSED, "IOP_CLOSED" }, { IOP_AT_START, "IOP_AT_START" }, + { IOP_IS_DIR, "IOP_IS_DIR" }, { 0, NULL } };