diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | awk.h | 1 | ||||
-rw-r--r-- | io.c | 56 | ||||
-rw-r--r-- | profile.c | 21 |
4 files changed, 72 insertions, 17 deletions
@@ -1,3 +1,14 @@ +2015-04-08 Arnold D. Robbins <arnold@skeeve.com> + + Factor out opening of /dev/XXX files from /inet. + Enable interpretation of special filenames for profiling output. + + * awk.h (devopen_simple): Add declaration. + * io.c (devopen_simple): New routine. + (devopen): Call devopen_simple as appropriate. + * profile.c (set_prof_file): Call devopen_simple as appropriate, + some additonal logic to hande fd to fp conversion. + 2015-04-08 Eli Zaretskii <eliz@gnu.org> * profile.c (set_prof_file): Interpret a file name of "-" to mean @@ -1483,6 +1483,7 @@ extern struct redirect *redirect(NODE *redir_exp, int redirtype, int *errflg); extern NODE *do_close(int nargs); extern int flush_io(void); extern int close_io(bool *stdio_problem); +extern int devopen_simple(const char *name, const char *mode, bool try_real_open); extern int devopen(const char *name, const char *mode); extern int srcopen(SRCFILE *s); extern char *find_source(const char *src, struct stat *stb, int *errcode, int is_extlib); @@ -1551,12 +1551,8 @@ nextrres: } #endif /* HAVE_SOCKETS */ -/* devopen --- handle /dev/std{in,out,err}, /dev/fd/N, regular files */ -/* - * Strictly speaking, "name" is not a "const char *" because we temporarily - * change the string. - */ +/* devopen_simple --- handle "-", /dev/std{in,out,err}, /dev/fd/N */ /* * 9/2014: Flow here is a little messy. @@ -1570,22 +1566,25 @@ nextrres: */ int -devopen(const char *name, const char *mode) +devopen_simple(const char *name, const char *mode, bool try_real_open) { int openfd; char *cp; char *ptr; int flag = 0; - struct inet_socket_info isi; - if (strcmp(name, "-") == 0) - return fileno(stdin); + if (strcmp(name, "-") == 0) { + if (mode[0] == 'r') + return fileno(stdin); + else + return fileno(stdout); + } flag = str2mode(mode); openfd = INVALID_HANDLE; if (do_posix) - goto strictopen; + goto done; if ((openfd = os_devopen(name, flag)) != INVALID_HANDLE) { os_close_on_exec(openfd, name, "file", ""); @@ -1602,7 +1601,7 @@ devopen(const char *name, const char *mode) else if (strcmp(cp, "stderr") == 0 && (flag & O_ACCMODE) == O_WRONLY) openfd = fileno(stderr); else if (do_traditional) - goto strictopen; + goto done; else if (strncmp(cp, "fd/", 3) == 0) { struct stat sbuf; @@ -1613,9 +1612,36 @@ devopen(const char *name, const char *mode) openfd = INVALID_HANDLE; } /* do not set close-on-exec for inherited fd's */ - if (openfd != INVALID_HANDLE) - return openfd; - } else if (do_traditional) { + } +done: + if (try_real_open) + openfd = open(name, flag, 0666); + + return openfd; +} + +/* devopen --- handle /dev/std{in,out,err}, /dev/fd/N, /inet, regular files */ + +/* + * Strictly speaking, "name" is not a "const char *" because we temporarily + * change the string. + */ + +int +devopen(const char *name, const char *mode) +{ + int openfd; + char *cp; + int flag; + struct inet_socket_info isi; + + openfd = devopen_simple(name, mode, false); + if (openfd != INVALID_HANDLE) + return openfd; + + flag = str2mode(mode); + + if (do_traditional) { goto strictopen; } else if (inetfile(name, & isi)) { #ifdef HAVE_SOCKETS @@ -1683,7 +1709,7 @@ strictopen: not permitted. */ struct stat buf; - if (!inetfile(name, NULL) + if (! inetfile(name, NULL) && stat(name, & buf) == 0 && S_ISDIR(buf.st_mode)) errno = EISDIR; } @@ -65,12 +65,29 @@ static long indent_level = 0; void set_prof_file(const char *file) { + int fd; + assert(file != NULL); - if (strcmp(file, "-") == 0) + fd = devopen_simple(file, "w", true); + if (fd == INVALID_HANDLE) + prof_fp = NULL; + else if (fd == fileno(stdout)) prof_fp = stdout; + else if (fd == fileno(stderr)) + prof_fp = stderr; else - prof_fp = fopen(file, "w"); + prof_fp = fdopen(fd, "w"); + if (prof_fp == NULL) { + /* don't leak file descriptors */ + int e = errno; + + if ( fd != INVALID_HANDLE + && fd != fileno(stdout) + && fd != fileno(stderr)) + (void) close(fd); + + errno = e; warning(_("could not open `%s' for writing: %s"), file, strerror(errno)); warning(_("sending profile to standard error")); |