diff options
author | Arnold D. Robbins <arnold@skeeve.com> | 2012-07-29 16:33:00 +0300 |
---|---|---|
committer | Arnold D. Robbins <arnold@skeeve.com> | 2012-07-29 16:33:00 +0300 |
commit | 82816b279615b27f7c4f87349a8c830a96939d8c (patch) | |
tree | cf30bf71692e090ca6ca4934e65184aa990a3055 | |
parent | 207fc1458c7f168822e454a89f23428c64163427 (diff) | |
download | egawk-82816b279615b27f7c4f87349a8c830a96939d8c.tar.gz egawk-82816b279615b27f7c4f87349a8c830a96939d8c.tar.bz2 egawk-82816b279615b27f7c4f87349a8c830a96939d8c.zip |
Finish work on iop management. New readdir test.
-rw-r--r-- | ChangeLog | 17 | ||||
-rw-r--r-- | awk.h | 3 | ||||
-rw-r--r-- | io.c | 104 | ||||
-rw-r--r-- | pc/ChangeLog | 5 | ||||
-rw-r--r-- | pc/gawkmisc.pc | 7 | ||||
-rw-r--r-- | posix/ChangeLog | 5 | ||||
-rw-r--r-- | posix/gawkmisc.c | 7 | ||||
-rw-r--r-- | test/ChangeLog | 5 | ||||
-rw-r--r-- | test/Makefile.am | 11 | ||||
-rw-r--r-- | test/Makefile.in | 11 | ||||
-rw-r--r-- | test/readdir.awk | 7 | ||||
-rw-r--r-- | test/readdir0.awk | 9 | ||||
-rw-r--r-- | vms/ChangeLog | 5 | ||||
-rw-r--r-- | vms/gawkmisc.vms | 7 |
14 files changed, 160 insertions, 43 deletions
@@ -1,3 +1,20 @@ +2012-07-29 Arnold D. Robbins <arnold@skeeve.com> + + * awk.h (os_isreadable): Adjust declaration. + (struct iobuf): Add new member `valid'. + * io.c (iop_alloc): Remove do_input_parsers parameter, it's + always true. Adjust logic to set things to invalid if could not + find an input parser. + (after_beginfile): Use valid member to check if iobuf is valid. + Don't clear iop->errcode. + (nextfile): Adjust logic to clear errcode if valid is true and + also to update ERRNO. + (redirect): Check iop->valid and cleanup as necessary, including + setting ERRNO. + (two_way_open): Ditto. + (gawk_popen): Ditto. + (devopen): Remove check for directory. + 2012-07-27 Arnold D. Robbins <arnold@skeeve.com> * awk.h (set_RT): Change to take a NODE * parameter. @@ -906,6 +906,7 @@ typedef struct iobuf { */ ssize_t (*read_func)(); + bool valid; int errcode; int flag; @@ -1532,7 +1533,7 @@ extern int os_devopen(const char *name, int flag); extern void os_close_on_exec(int fd, const char *name, const char *what, const char *dir); extern int os_isatty(int fd); extern int os_isdir(int fd); -extern int os_isreadable(int fd); +extern int os_isreadable(int fd, bool *isdir); extern int os_is_setuid(void); extern int os_setbinmode(int fd, int mode); extern void os_restore_mode(int fd); @@ -203,7 +203,7 @@ static int close_redir(struct redirect *rp, bool exitwarn, two_way_close_type ho static int wait_any(int interesting); #endif static IOBUF *gawk_popen(const char *cmd, struct redirect *rp); -static IOBUF *iop_alloc(int fd, const char *name, bool do_input_parsers); +static IOBUF *iop_alloc(int fd, const char *name); static int gawk_pclose(struct redirect *rp); static int str2mode(const char *mode); static int two_way_open(const char *str, struct redirect *rp); @@ -315,15 +315,16 @@ after_beginfile(IOBUF **curfile) if (iop->public.fd == INVALID_HANDLE) { const char *fname; int errcode; + bool valid; fname = iop->public.name; errcode = iop->errcode; - iop->errcode = 0; + valid = iop->valid; errno = 0; update_ERRNO_int(errno); iop_close(iop); *curfile = NULL; - if (errcode == EISDIR && ! do_traditional) { + if (! valid && errcode == EISDIR && ! do_traditional) { warning(_("command line argument `%s' is a directory: skipped"), fname); return; /* read next file */ } @@ -409,11 +410,15 @@ nextfile(IOBUF **curfile, bool skipping) mpz_set_ui(MFNR, 0); #endif FNR = 0; - iop = *curfile = iop_alloc(fd, fname, false); + iop = *curfile = iop_alloc(fd, fname); if (fd == INVALID_HANDLE) iop->errcode = errcode; - else + else if (iop->valid) iop->errcode = 0; + + if (! do_traditional && iop->errcode != 0) + update_ERRNO_int(iop->errcode); + return ++i; /* run beginfile block */ } } @@ -429,7 +434,7 @@ nextfile(IOBUF **curfile, bool skipping) FILENAME_node->var_value = make_string("-", 1); FILENAME_node->var_value->flags |= MAYBE_NUM; /* be pedantic */ fname = "-"; - iop = *curfile = iop_alloc(fileno(stdin), fname, false); + iop = *curfile = iop_alloc(fileno(stdin), fname); if (iop->public.fd == INVALID_HANDLE) { errcode = errno; @@ -802,7 +807,13 @@ redirect(NODE *redir_exp, int redirtype, int *errflg) /* do not free rp, saving it for reuse (save_rp = rp) */ return NULL; } - rp->iop = iop_alloc(fd, str, true); + rp->iop = iop_alloc(fd, str); + if (! rp->iop->valid) { + if (! do_traditional && rp->iop->errcode != 0) + update_ERRNO_int(rp->iop->errcode); + iop_close(rp->iop); + rp->iop = NULL; + } break; case redirect_twoway: direction = "to/from"; @@ -1605,13 +1616,6 @@ strictopen: } #endif if (openfd != INVALID_HANDLE) { - if (os_isdir(openfd)) { - (void) close(openfd); /* don't leak fds */ - /* Set useful error number. */ - errno = EISDIR; - return INVALID_HANDLE; - } - if (openfd > fileno(stderr)) os_close_on_exec(openfd, name, "file", ""); } @@ -1646,9 +1650,12 @@ two_way_open(const char *str, struct redirect *rp) } os_close_on_exec(fd, str, "socket", "to/from"); os_close_on_exec(newfd, str, "socket", "to/from"); - rp->iop = iop_alloc(newfd, str, true); - if (rp->iop == NULL) { - close(newfd); + rp->iop = iop_alloc(newfd, str); + if (! rp->iop->valid) { + if (! do_traditional && rp->iop->errcode != 0) + update_ERRNO_int(rp->iop->errcode); + iop_close(rp->iop); + rp->iop = NULL; fclose(rp->fp); return false; } @@ -1842,9 +1849,12 @@ two_way_open(const char *str, struct redirect *rp) } rp->pid = pid; - rp->iop = iop_alloc(master, str, true); - if (rp->iop == NULL) { - (void) close(master); + rp->iop = iop_alloc(master, str); + if (! rp->iop->valid) { + if (! do_traditional && rp->iop->errcode != 0) + update_ERRNO_int(rp->iop->errcode); + iop_close(rp->iop); + rp->iop = NULL; (void) kill(pid, SIGKILL); return false; } @@ -1995,9 +2005,12 @@ use_pipes: /* parent */ rp->pid = pid; - rp->iop = iop_alloc(ctop[0], str, true); - if (rp->iop == NULL) { - (void) close(ctop[0]); + rp->iop = iop_alloc(ctop[0], str); + if (! rp->iop->valid) { + if (! do_traditional && rp->iop->errcode != 0) + update_ERRNO_int(rp->iop->errcode); + iop_close(rp->iop); + rp->iop = NULL; (void) close(ctop[1]); (void) close(ptoc[0]); (void) close(ptoc[1]); @@ -2159,9 +2172,13 @@ gawk_popen(const char *cmd, struct redirect *rp) } #endif os_close_on_exec(p[0], cmd, "pipe", "from"); - rp->iop = iop_alloc(p[0], cmd, true); - if (rp->iop == NULL) - (void) close(p[0]); + rp->iop = iop_alloc(p[0], cmd); + if (! rp->iop->valid) { + if (! do_traditional && rp->iop->errcode != 0) + update_ERRNO_int(rp->iop->errcode); + iop_close(rp->iop); + rp->iop = NULL; + } return rp->iop; } @@ -2204,9 +2221,14 @@ gawk_popen(const char *cmd, struct redirect *rp) if (current == NULL) return NULL; os_close_on_exec(fileno(current), cmd, "pipe", "from"); - rp->iop = iop_alloc(fileno(current), cmd, true); - if (rp->iop == NULL) { + rp->iop = iop_alloc(fileno(current), cmd); + if (! rp->iop->valid) { + if (! do_traditional && rp->iop->errcode != 0) + update_ERRNO_int(rp->iop->errcode); (void) pclose(current); + rp->iop->public.fd = INVALID_HANDLE; + iop_close(rp->iop); + rp->iop = NULL; current = NULL; } rp->ifp = current; @@ -2629,10 +2651,11 @@ find_input_parser(IOBUF *iop) /* iop_alloc --- allocate an IOBUF structure for an open fd */ static IOBUF * -iop_alloc(int fd, const char *name, bool do_input_parsers) +iop_alloc(int fd, const char *name) { struct stat sbuf; IOBUF *iop; + bool isdir; emalloc(iop, IOBUF *, sizeof(IOBUF), "iop_alloc"); @@ -2640,16 +2663,22 @@ iop_alloc(int fd, const char *name, bool do_input_parsers) iop->public.fd = fd; iop->public.name = name; iop->read_func = ( ssize_t(*)() ) read; + iop->valid = false; - if (do_input_parsers) { - find_input_parser(iop); - /* tried to find open parser and could not */ - if (iop->public.fd == INVALID_HANDLE) { - efree(iop); - return NULL; - } - } else if (iop->public.fd == INVALID_HANDLE) + find_input_parser(iop); + + /* tried to find open parser and could not */ + if ( iop->public.get_record == NULL + && ! os_isreadable(iop->public.fd, & isdir)) { + if (isdir) + iop->errcode = EISDIR; + close(iop->public.fd); + iop->public.fd = INVALID_HANDLE; + } + + if (iop->public.fd == INVALID_HANDLE) { return iop; + } if (os_isatty(iop->public.fd)) iop->flag |= IOP_IS_TTY; @@ -2664,6 +2693,7 @@ iop_alloc(int fd, const char *name, bool do_input_parsers) iop->dataend = NULL; iop->end = iop->buf + iop->size; iop->flag |= IOP_AT_START; + iop->valid = true; return iop; } diff --git a/pc/ChangeLog b/pc/ChangeLog index 43221928..28dfb72b 100644 --- a/pc/ChangeLog +++ b/pc/ChangeLog @@ -1,3 +1,8 @@ +2012-07-29 Arnold D. Robbins <arnold@skeeve.com> + + * gawkmisc.c (os_isreadable): Add isdir pointer parameter to be + set to true if fd is for a directory. + 2012-07-26 Arnold D. Robbins <arnold@skeeve.com> * gawkmisc.pc (os_isreadable): New function. diff --git a/pc/gawkmisc.pc b/pc/gawkmisc.pc index 999167ca..d79a3207 100644 --- a/pc/gawkmisc.pc +++ b/pc/gawkmisc.pc @@ -235,10 +235,12 @@ int fd; /* os_isreadable --- fd can be read from */ int -os_isreadable(int fd) +os_isreadable(int fd, bool *isdir) { struct stat sbuf; + *isdir = false; + if (fstat(fd, &sbuf) != 0) return false; @@ -252,6 +254,9 @@ os_isreadable(int fd) case S_IFIFO: #endif return true; + case S_IFDIR: + *isdir = true; + /* fall through */ default: return false; } diff --git a/posix/ChangeLog b/posix/ChangeLog index a3ee87db..d49ff49e 100644 --- a/posix/ChangeLog +++ b/posix/ChangeLog @@ -1,3 +1,8 @@ +2012-07-29 Arnold D. Robbins <arnold@skeeve.com> + + * gawkmisc.c (os_isreadable): Add isdir pointer parameter to be + set to true if fd is for a directory. + 2012-07-26 Arnold D. Robbins <arnold@skeeve.com> * gawkmisc.c (os_isreadable): New function. diff --git a/posix/gawkmisc.c b/posix/gawkmisc.c index 87a6747c..a5c3a619 100644 --- a/posix/gawkmisc.c +++ b/posix/gawkmisc.c @@ -207,10 +207,12 @@ os_isdir(int fd) /* os_isreadable --- fd can be read from */ int -os_isreadable(int fd) +os_isreadable(int fd, bool *isdir) { struct stat sbuf; + *isdir = false; + if (fstat(fd, &sbuf) != 0) return false; @@ -224,6 +226,9 @@ os_isreadable(int fd) case S_IFIFO: #endif return true; + case S_IFDIR: + *isdir = true; + /* fall through */ default: return false; } diff --git a/test/ChangeLog b/test/ChangeLog index b38cf279..a3fb627a 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,8 @@ +2012-07-29 Arnold D. Robbins <arnold@skeeve.com> + + * Makefile.am (readdir): New test. + * readdir0.awk, readdir.awk: New files. + 2012-07-16 Arnold D. Robbins <arnold@skeeve.com> * fnmatch.awk, fnmatch.ok: Portability updates. diff --git a/test/Makefile.am b/test/Makefile.am index 78fd3117..5aa31b41 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -623,6 +623,8 @@ EXTRA_DIST = \ range1.awk \ range1.in \ range1.ok \ + readdir0.awk \ + readdir.awk \ rebt8b1.awk \ rebt8b1.ok \ rebt8b2.awk \ @@ -894,7 +896,7 @@ LOCALE_CHARSET_TESTS = \ SHLIB_TESTS = \ assignconst fnmatch filefuncs fork fork2 ordchr ordchr2 \ - readfile rwarray testext time + readdir readfile rwarray testext time # List of the tests which should be run with --lint option: NEED_LINT = \ @@ -1603,6 +1605,13 @@ assignconst: done 2>&1 | grep -v at_exit > _$@ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ +readdir: + @echo $@ + @touch $@.out1 $@.out2 # create directory entries first + @ls -fli | sed 1d | $(AWK) -f $(srcdir)/readdir0.awk > $@.out1 + @$(AWK) -f $(srcdir)/readdir.awk . > $@.out2 + @-$(CMP) $@.out1 $@.out2 && rm -f $@.out[12] + # Targets generated for other tests: include Maketests diff --git a/test/Makefile.in b/test/Makefile.in index 4868bdc6..5375aaee 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -836,6 +836,8 @@ EXTRA_DIST = \ range1.awk \ range1.in \ range1.ok \ + readdir0.awk \ + readdir.awk \ rebt8b1.awk \ rebt8b1.ok \ rebt8b2.awk \ @@ -1103,7 +1105,7 @@ LOCALE_CHARSET_TESTS = \ SHLIB_TESTS = \ assignconst fnmatch filefuncs fork fork2 ordchr ordchr2 \ - readfile rwarray testext time + readdir readfile rwarray testext time # List of the tests which should be run with --lint option: @@ -1985,6 +1987,13 @@ assignconst: do $(AWK) -f $(srcdir)/$@.awk $$i ; \ done 2>&1 | grep -v at_exit > _$@ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ + +readdir: + @echo $@ + @touch $@.out1 $@.out2 # create directory entries first + @ls -fli | sed 1d | $(AWK) -f $(srcdir)/readdir0.awk > $@.out1 + @$(AWK) -f $(srcdir)/readdir.awk . > $@.out2 + @-$(CMP) $@.out1 $@.out2 && rm -f $@.out[12] Gt-dummy: # file Maketests, generated from Makefile.am by the Gentests program addcomma: diff --git a/test/readdir.awk b/test/readdir.awk new file mode 100644 index 00000000..4d35be6a --- /dev/null +++ b/test/readdir.awk @@ -0,0 +1,7 @@ +@load "readdir" + +BEGIN { + readdir_do_ftype(1) +} + +{ print } diff --git a/test/readdir0.awk b/test/readdir0.awk new file mode 100644 index 00000000..54306f10 --- /dev/null +++ b/test/readdir0.awk @@ -0,0 +1,9 @@ +{ + ino = $1 + name = $NF + type = substr($2, 1, 1) + if (type == "-") + type = "f" + + printf "%s/%s/%s\n", ino, name, type +} diff --git a/vms/ChangeLog b/vms/ChangeLog index c4cb6ed9..f65274f9 100644 --- a/vms/ChangeLog +++ b/vms/ChangeLog @@ -1,3 +1,8 @@ +2012-07-29 Arnold D. Robbins <arnold@skeeve.com> + + * gawkmisc.c (os_isreadable): Add isdir pointer parameter to be + set to true if fd is for a directory. + 2012-07-26 Arnold D. Robbins <arnold@skeeve.com> * gawkmisc.vms (os_isreadable): New function. diff --git a/vms/gawkmisc.vms b/vms/gawkmisc.vms index f373b5f2..773b3556 100644 --- a/vms/gawkmisc.vms +++ b/vms/gawkmisc.vms @@ -147,10 +147,12 @@ int fd; /* os_isreadable --- fd can be read from */ int -os_isreadable(int fd) +os_isreadable(int fd, bool *isdir) { struct stat sbuf; + *isdir = false; + if (fstat(fd, &sbuf) != 0) return false; @@ -164,6 +166,9 @@ os_isreadable(int fd) case S_IFIFO: #endif return true; + case S_IFDIR: + *isdir = true; + /* fall through */ default: return false; } |