aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--awk.h1
-rw-r--r--io.c56
-rw-r--r--profile.c21
4 files changed, 72 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index 90ddba7d..bb02ecf3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/awk.h b/awk.h
index 5c3d76af..1eb26880 100644
--- a/awk.h
+++ b/awk.h
@@ -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);
diff --git a/io.c b/io.c
index 1d15d887..2344c2ad 100644
--- a/io.c
+++ b/io.c
@@ -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;
}
diff --git a/profile.c b/profile.c
index fe411e43..74fc4f9c 100644
--- a/profile.c
+++ b/profile.c
@@ -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"));