sexp sexp_fdopen (sexp ctx, sexp self, sexp_sint_t n, sexp fd, sexp mode) { FILE *f; if (! sexp_integerp(fd)) return sexp_type_exception(ctx, self, SEXP_FIXNUM, fd); if (! sexp_stringp(mode)) return sexp_type_exception(ctx, self, SEXP_STRING, mode); f = fdopen(sexp_unbox_fixnum(fd), sexp_string_data(mode)); if (! f) return sexp_user_exception(ctx, SEXP_FALSE, "fdopen failed", fd); /* maybe use fd2path to get the name of the fd */ if (sexp_string_data(mode)[0] == 'w') return sexp_make_output_port(ctx, f, SEXP_FALSE); else return sexp_make_input_port(ctx, f, SEXP_FALSE); }
static sexp sexp_make_custom_port (sexp ctx, sexp self, char *mode, sexp read, sexp write, sexp seek, sexp close) { FILE *in; sexp res; sexp_gc_var1(vec); if (sexp_truep(read) && ! sexp_procedurep(read)) return sexp_type_exception(ctx, self, SEXP_PROCEDURE, read); if (sexp_truep(write) && ! sexp_procedurep(write)) return sexp_type_exception(ctx, self, SEXP_PROCEDURE, write); if (sexp_truep(seek) && ! sexp_procedurep(seek)) return sexp_type_exception(ctx, self, SEXP_PROCEDURE, seek); if (sexp_truep(close) && ! sexp_procedurep(close)) return sexp_type_exception(ctx, self, SEXP_PROCEDURE, close); sexp_gc_preserve1(ctx, vec); vec = sexp_make_vector(ctx, SEXP_SIX, SEXP_VOID); sexp_cookie_ctx_set(vec, ctx); sexp_cookie_buffer_set(vec, sexp_make_string(ctx, sexp_make_fixnum(SEXP_PORT_BUFFER_SIZE), SEXP_VOID)); sexp_cookie_read_set(vec, read); sexp_cookie_write_set(vec, write); sexp_cookie_seek_set(vec, seek); sexp_cookie_close_set(vec, close); #if SEXP_BSD in = funopen(vec, (sexp_procedurep(read) ? sexp_cookie_reader : NULL), (sexp_procedurep(write) ? sexp_cookie_writer : NULL), NULL, /* (sexp_procedurep(seek) ? sexp_cookie_reader : NULL), */ (sexp_procedurep(close) ? sexp_cookie_cleaner : NULL)); #else in = fopencookie(vec, mode, (sexp_truep(seek) ? sexp_cookie : sexp_cookie_no_seek)); #endif if (! in) { res = sexp_user_exception(ctx, self, "couldn't make custom port", read); } else { res = sexp_make_input_port(ctx, in, SEXP_FALSE); sexp_port_cookie(res) = vec; /* for gc preserving */ } if (mode && mode[0] == 'w') sexp_pointer_tag(res) = SEXP_OPORT; sexp_gc_release1(ctx); return res; }