diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2015-04-10 22:18:50 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2015-04-10 22:18:50 -0700 |
commit | 6a350fd788f3114629c9993aa4d1ec5c292182f5 (patch) | |
tree | 5b2319bf1f8d7144bfadcf9055264e809017e750 | |
parent | cc9bd9efeb1a0b49819e086020c09656abeac768 (diff) | |
download | txr-6a350fd788f3114629c9993aa4d1ec5c292182f5.tar.gz txr-6a350fd788f3114629c9993aa4d1ec5c292182f5.tar.bz2 txr-6a350fd788f3114629c9993aa4d1ec5c292182f5.zip |
Functions open-fileno and fileno.
* stream.c (fd_k): New keyword variable.
(stdio_get_prop): Handle the :fd property by returning
the file descriptor.
(open_fileno): New function.
(stream_init): Initialize fd_k, and register fileno and open-fileno.
* stream.h (open_fileno): Declared.
* txr.1: Documented open-fileno and fileno.
* utf8.c (w_fdopen): New function.
* utf8.h (w_fdopen): Declared.
-rw-r--r-- | ChangeLog | 18 | ||||
-rw-r--r-- | stream.c | 21 | ||||
-rw-r--r-- | stream.h | 1 | ||||
-rw-r--r-- | txr.1 | 36 | ||||
-rw-r--r-- | utf8.c | 8 | ||||
-rw-r--r-- | utf8.h | 1 |
6 files changed, 84 insertions, 1 deletions
@@ -1,5 +1,23 @@ 2015-04-10 Kaz Kylheku <kaz@kylheku.com> + Functions open-fileno and fileno. + + * stream.c (fd_k): New keyword variable. + (stdio_get_prop): Handle the :fd property by returning + the file descriptor. + (open_fileno): New function. + (stream_init): Initialize fd_k, and register fileno and open-fileno. + + * stream.h (open_fileno): Declared. + + * txr.1: Documented open-fileno and fileno. + + * utf8.c (w_fdopen): New function. + + * utf8.h (w_fdopen): Declared. + +2015-04-10 Kaz Kylheku <kaz@kylheku.com> + * gc.c (sweep): Fix comment referring to nonexistent identifier. 2015-04-10 Kaz Kylheku <kaz@kylheku.com> @@ -64,7 +64,7 @@ val dev_k, ino_k, mode_k, nlink_k, uid_k; val gid_k, rdev_k, size_k, blksize_k, blocks_k; val atime_k, mtime_k, ctime_k; val from_start_k, from_current_k, from_end_k; -val real_time_k, name_k; +val real_time_k, name_k, fd_k; val format_s; static void common_destroy(val obj) @@ -291,6 +291,8 @@ static val stdio_get_prop(val stream, val ind) return h->is_real_time ? t : nil; } else if (ind == name_k) { return h->descr; + } else if (ind == fd_k) { + return h->f ? num(fileno(h->f)) : nil; } return nil; } @@ -2310,6 +2312,20 @@ val open_file(val path, val mode_str) return set_mode_props(m, make_stdio_stream(f, path)); } +val open_fileno(val fd, val mode_str) +{ + struct stdio_mode m; + FILE *f = w_fdopen(c_num(fd), c_str(normalize_mode(&m, mode_str))); + + if (!f) + uw_throwf(file_error_s, lit("error opening descriptor ~a: ~a/~s"), + fd, num(errno), string_utf8(strerror(errno)), nao); + + return set_mode_props(m, make_stdio_stream(f, format(nil, + lit("fd ~a"), + fd, nao))); +} + val open_tail(val path, val mode_str, val seek_end_p) { struct stdio_mode m; @@ -2821,6 +2837,7 @@ void stream_init(void) from_end_k = intern(lit("from-end"), keyword_package); real_time_k = intern(lit("real-time"), keyword_package); name_k = intern(lit("name"), keyword_package); + fd_k = intern(lit("fd"), keyword_package); format_s = intern(lit("format"), user_package); reg_var(stdin_s = intern(lit("*stdin*"), user_package), @@ -2868,10 +2885,12 @@ void stream_init(void) reg_fun(intern(lit("real-time-stream-p"), user_package), func_n1(real_time_stream_p)); reg_fun(intern(lit("stream-set-prop"), user_package), func_n3(stream_set_prop)); reg_fun(intern(lit("stream-get-prop"), user_package), func_n2(stream_get_prop)); + reg_fun(intern(lit("fileno"), user_package), curry_12_1(func_n2(stream_get_prop), fd_k)); reg_fun(intern(lit("make-catenated-stream"), user_package), func_n0v(make_catenated_stream)); reg_fun(intern(lit("cat-streams"), user_package), func_n1(make_catenated_stream)); reg_fun(intern(lit("open-directory"), user_package), func_n1(open_directory)); reg_fun(intern(lit("open-file"), user_package), func_n2o(open_file, 1)); + reg_fun(intern(lit("open-fileno"), user_package), func_n2o(open_fileno, 1)); reg_fun(intern(lit("open-tail"), user_package), func_n3o(open_tail, 1)); reg_fun(intern(lit("open-command"), user_package), func_n2o(open_command, 1)); reg_fun(intern(lit("open-pipe"), user_package), func_n2(open_command)); @@ -117,6 +117,7 @@ val get_string(val stream, val nchars, val close_after_p); val statf(val path); val open_directory(val path); val open_file(val path, val mode_str); +val open_fileno(val fd, val mode_str); val open_tail(val path, val mode_str, val seek_end_p); val open_command(val path, val mode_str); val open_process(val path, val mode_str, val args); @@ -24816,6 +24816,42 @@ or .codn nil , rather than zero or nonzero. The others return integer values. +.SS* Unix File Descriptors + +.coNP Function @ open-fileno +.synb +.mets (open-fileno < file-descriptor <> [ mode-string ]) +.syne +The +.code open-fileno +function creates a \*(TX stream over a file descriptor. The +.meta file-descriptor +argument must be an integer denoting a valid file descriptor. + +For a description of +.metn mode-string , +see the +.code open-file +function. + +.coNP Function @ fileno +.synb +.mets (fileno << stream ) +.syne +.desc +The +.code fileno +function returns the underlying file descriptor of +.metn stream , +if it has one. Otherwise, it returns +.codn nil. + +This is equivalent to querying the stream using +.code stream-get-prop +for the +.code :fd +property. + .SS* Unix Itimers Itimers ("interval timers") can be used in combination with signal handling to execute asynchronous actions. Itimers deliver delayed, one-time signals, @@ -387,6 +387,14 @@ FILE *w_freopen(const wchar_t *wname, const wchar_t *wmode, FILE *fold) return f; } +FILE *w_fdopen(int fd, const wchar_t *wmode) +{ + char *mode = utf8_dup_to(wmode); + FILE *f = fdopen(fd, mode); + free(mode); + return f; +} + int w_remove(const wchar_t *wpath) { char *path = utf8_dup_to(wpath); @@ -52,5 +52,6 @@ wint_t utf8_decode(utf8_decoder_t *,int (*get)(mem_t *ctx), mem_t *ctx); FILE *w_fopen(const wchar_t *, const wchar_t *); FILE *w_popen(const wchar_t *, const wchar_t *); FILE *w_freopen(const wchar_t *, const wchar_t *, FILE *); +FILE *w_fdopen(int, const wchar_t *); int w_remove(const wchar_t *); int w_rename(const wchar_t *, const wchar_t *); |