diff options
author | Eric Blake <ebb9@byu.net> | 2009-02-18 11:38:54 -0700 |
---|---|---|
committer | Eric Blake <ebb9@byu.net> | 2009-02-18 15:06:20 -0700 |
commit | 028f5c5976a35256f5fa3804f33292a75ba56c6e (patch) | |
tree | 1d72384c7988c80d33b4ce6cfa5521713da08a2d | |
parent | 4cd6b69ea7747052d12c0f2c4c28be082b030b00 (diff) | |
download | m4-028f5c5976a35256f5fa3804f33292a75ba56c6e.tar.gz |
Speed up esyscmd with buffer reads.
* modules/gnu.c (esyscmd): Read blocks directly into obstack,
rather than repeatedly reading bytes. Detect read errors.
Signed-off-by: Eric Blake <ebb9@byu.net>
(cherry picked from commit 1974da270a84d8c0cf2b3e3e08ce5292fdb211f3)
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | modules/gnu.c | 24 |
2 files changed, 25 insertions, 3 deletions
@@ -1,5 +1,9 @@ 2009-02-18 Eric Blake <ebb9@byu.net> + Speed up esyscmd with buffer reads. + * modules/gnu.c (esyscmd): Read blocks directly into obstack, + rather than repeatedly reading bytes. Detect read errors. + Avoid risk of stack overflow. * m4/output.c (insert_file): Avoid stack allocation of large buffer. diff --git a/modules/gnu.c b/modules/gnu.c index f44f0ba4..e6c7691e 100644 --- a/modules/gnu.c +++ b/modules/gnu.c @@ -654,7 +654,6 @@ M4BUILTIN_HANDLER (esyscmd) if (m4_set_sysval && m4_sysval_flush) { FILE *pin; - int ch; if (m4_get_safer_opt (context)) { @@ -684,8 +683,27 @@ M4BUILTIN_HANDLER (esyscmd) } else { - while ((ch = getc (pin)) != EOF) - obstack_1grow (obs, ch); + while (1) + { + size_t avail = obstack_room (obs); + if (!avail) + { + int ch = getc (pin); + if (ch == EOF) + break; + obstack_1grow (obs, ch); + } + else + { + size_t len = fread (obstack_next_free (obs), 1, avail, pin); + if (len <= 0) + break; + obstack_blank_fast (obs, len); + } + } + if (ferror (pin)) + m4_warn (context, errno, me, _("cannot read pipe to command %s"), + quotearg_style (locale_quoting_style, cmd)); m4_set_sysval (pclose (pin)); } } |