diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2013-11-27 21:05:51 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2013-11-27 21:05:51 -0800 |
commit | 5285db54f7199cf75c0b740faaeee15cc9cc8c6a (patch) | |
tree | 98afe773267c450f14759e02724a0fa9c2b89c7d /stream.c | |
parent | 6fedaccfe790e33bb7a71d8a5f776e4cfa7e6c62 (diff) | |
download | txr-5285db54f7199cf75c0b740faaeee15cc9cc8c6a.tar.gz txr-5285db54f7199cf75c0b740faaeee15cc9cc8c6a.tar.bz2 txr-5285db54f7199cf75c0b740faaeee15cc9cc8c6a.zip |
* configure: Added check to detect POSIX sleep function.
* eval.c (eval_init): Register new open_tail function as intrinsic.
* match.c (complex_snarf, complex_stream): Update calls to
make_stdio_stream and make_pipe_stream to take fewer arguments.
(match_files): Support a stream object as a data source specification
in place of a string.
* parser.l (parse_reset): Update call to make_stdio_stream to take
fewer arguments.
* stream.c: Inclusion of <unistd.h> made properly conditional.
(struct stdio_handle): pid member defined as pid_t only if we have fork
functionality, otherwise defined as int.
(tail_get_line, tail_get_char, tail_get_byte): New static functions.
(tail_ops): New static structure.
(make_stdio_stream_common): New static structure.
(make_stdio_stream, make_pipe_stream): These functions lose the input
and output parameters, which ended up never used. Reimplemented
in terms of new common function.
(make_tail_stream): New function.
(make_pipevp_stream): Reimplemented in terms of new common function.
(open_file, open_command): Simplified by removal of useless local
variables and their computation, which used to be extra arguments to
make_stdio_stream and make_pipe_stream.
(open_tail): New function.
(stream_init): Calls to make_stdio_stream updated.
* stream.h (make_stdio_stream, make_pipe_stream): Declarations updated.
(make_tail_stream, open_tail): Declared.
* txr.c (txr_main): Calls to make_stdio_stream updated.
Diffstat (limited to 'stream.c')
-rw-r--r-- | stream.c | 134 |
1 files changed, 93 insertions, 41 deletions
@@ -34,9 +34,11 @@ #include <errno.h> #include <ctype.h> #include <wchar.h> +#include "config.h" +#if HAVE_SYS_WAIT || HAVE_SYS_STAT || HAVE_FORK_STUFF || HAVE_POSIX_SLEEP #include <unistd.h> +#endif #include <float.h> -#include "config.h" #if HAVE_SYS_WAIT #include <sys/wait.h> #endif @@ -90,7 +92,11 @@ struct stdio_handle { FILE *f; val descr; utf8_decoder_t ud; +#if HAVE_FORK_STUFF pid_t pid; +#else + int pid; +#endif }; static void stdio_stream_print(val stream, val out) @@ -312,6 +318,55 @@ static struct strm_ops stdio_ops = { stdio_seek }; +static val tail_get_line(val stream) +{ + val ret; + + while ((ret = stdio_get_line(stream)) == nil) + sleep(1); + + return ret; +} + +static val tail_get_char(val stream) +{ + val ret; + + while ((ret = stdio_get_char(stream)) == nil) + sleep(1); + + return ret; +} + +static val tail_get_byte(val stream) +{ + val ret; + + while ((ret = stdio_get_byte(stream)) == nil) + sleep(1); + + return ret; +} + + +static struct strm_ops tail_ops = { + { cobj_equal_op, + stdio_stream_print, + stdio_stream_destroy, + stdio_stream_mark, + cobj_hash_op }, + stdio_put_string, + stdio_put_char, + stdio_put_byte, + tail_get_line, + tail_get_char, + tail_get_byte, + stdio_close, + stdio_flush, + stdio_seek +}; + + #if HAVE_FORK_STUFF static int pipevp_close(FILE *f, pid_t pid) { @@ -762,10 +817,10 @@ static struct strm_ops dir_ops = { }; -val make_stdio_stream(FILE *f, val descr, val input, val output) +static val make_stdio_stream_common(FILE *f, val descr, struct cobj_ops *ops) { struct stdio_handle *h = (struct stdio_handle *) chk_malloc(sizeof *h); - val stream = cobj((mem_t *) h, stream_s, &stdio_ops.cobj_ops); + val stream = cobj((mem_t *) h, stream_s, ops); h->f = f; h->descr = descr; utf8_decoder_init(&h->ud); @@ -773,25 +828,26 @@ val make_stdio_stream(FILE *f, val descr, val input, val output) return stream; } -val make_pipe_stream(FILE *f, val descr, val input, val output) +val make_stdio_stream(FILE *f, val descr) { - struct stdio_handle *h = (struct stdio_handle *) chk_malloc(sizeof *h); - val stream = cobj((mem_t *) h, stream_s, &pipe_ops.cobj_ops); - h->f = f; - h->descr = descr; - utf8_decoder_init(&h->ud); - h->pid = 0; - return stream; + return make_stdio_stream_common(f, descr, &stdio_ops.cobj_ops); +} + +val make_tail_stream(FILE *f, val descr) +{ + return make_stdio_stream_common(f, descr, &tail_ops.cobj_ops); +} + +val make_pipe_stream(FILE *f, val descr) +{ + return make_stdio_stream_common(f, descr, &pipe_ops.cobj_ops); } #if HAVE_FORK_STUFF static val make_pipevp_stream(FILE *f, val descr, pid_t pid) { - struct stdio_handle *h = (struct stdio_handle *) chk_malloc(sizeof *h); - val stream = cobj((mem_t *) h, stream_s, &pipe_ops.cobj_ops); - h->f = f; - h->descr = descr; - utf8_decoder_init(&h->ud); + val stream = make_stdio_stream_common(f, descr, &pipe_ops.cobj_ops); + struct stdio_handle *h = (struct stdio_handle *) stream->co.handle; h->pid = pid; return stream; } @@ -1604,43 +1660,39 @@ val open_directory(val path) val open_file(val path, val mode_str) { FILE *f = w_fopen(c_str(path), c_str(mode_str)); - val input = nil, output = nil; if (!f) uw_throwf(file_error_s, lit("error opening ~a: ~a/~s"), path, num(errno), string_utf8(strerror(errno)), nao); - if (break_str(mode_str, lit("w"))) - output = t; - if (break_str(mode_str, lit("a"))) - output = t; - if (break_str(mode_str, lit("r"))) - input = t; - if (break_str(mode_str, lit("+"))) - input = output = t; + return make_stdio_stream(f, path); +} - return make_stdio_stream(f, path, input, output); +val open_tail(val path, val mode_str, val seek_end_p) +{ + FILE *f = w_fopen(c_str(path), c_str(mode_str)); + + if (!f) + uw_throwf(file_error_s, lit("error opening ~a: ~a/~s"), + path, num(errno), string_utf8(strerror(errno)), nao); + + if (seek_end_p) + if (fseek(f, 0, SEEK_END) < 0) + uw_throwf(file_error_s, lit("error seeking to end of ~a: ~a/~s"), + path, num(errno), string_utf8(strerror(errno)), nao); + + return make_tail_stream(f, path); } val open_command(val path, val mode_str) { FILE *f = w_popen(c_str(path), c_str(mode_str)); - val input = nil, output = nil; if (!f) uw_throwf(file_error_s, lit("error opening pipe ~a: ~a/~s"), path, num(errno), string_utf8(strerror(errno)), nao); - if (break_str(mode_str, lit("w"))) - output = t; - if (break_str(mode_str, lit("a"))) - output = t; - if (break_str(mode_str, lit("r"))) - input = t; - if (break_str(mode_str, lit("+"))) - input = output = t; - - return make_pipe_stream(f, path, input, output); + return make_pipe_stream(f, path); } #if HAVE_FORK_STUFF @@ -1775,10 +1827,10 @@ val open_process(val name, val mode_str, val args) void stream_init(void) { protect(&std_input, &std_output, &std_debug, &std_error, (val *) 0); - std_input = make_stdio_stream(stdin, string(L"stdin"), t, nil); - std_output = make_stdio_stream(stdout, string(L"stdout"), nil, t); - std_debug = make_stdio_stream(stdout, string(L"debug"), nil, t); - std_error = make_stdio_stream(stderr, string(L"stderr"), nil, t); + std_input = make_stdio_stream(stdin, string(L"stdin")); + std_output = make_stdio_stream(stdout, string(L"stdout")); + std_debug = make_stdio_stream(stdout, string(L"debug")); + std_error = make_stdio_stream(stderr, string(L"stderr")); detect_format_string(); dev_k = intern(lit("dev"), keyword_package); |