mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-05-20 22:29:16 +02:00
auto-closing gc'ed string ports to prevent memory leaks (issue #41).
also using a separate port field no_closep to indicate ports whose underlying streams shouldn't be closed (stdin/stdout/stderr).
This commit is contained in:
parent
d6c3b04e06
commit
e15c49389c
3 changed files with 26 additions and 20 deletions
24
eval.c
24
eval.c
|
@ -2058,14 +2058,7 @@ static sexp sexp_close_port (sexp ctx, sexp port) {
|
|||
return sexp_type_exception(ctx, "not a port", port);
|
||||
if (! sexp_port_openp(port))
|
||||
return sexp_user_exception(ctx, SEXP_FALSE, "port already closed", port);
|
||||
if (sexp_port_stream(port))
|
||||
fclose(sexp_port_stream(port));
|
||||
#if ! SEXP_USE_STRING_STREAMS
|
||||
if (sexp_port_buf(port) && sexp_oportp(port))
|
||||
free(sexp_port_buf(port));
|
||||
#endif
|
||||
sexp_port_openp(port) = 0;
|
||||
return SEXP_VOID;
|
||||
return sexp_finalize_port(ctx, port);
|
||||
}
|
||||
|
||||
void sexp_warn_undefs (sexp ctx, sexp from, sexp to, sexp out) {
|
||||
|
@ -2588,12 +2581,15 @@ sexp sexp_add_module_directory (sexp ctx, sexp dir, sexp appendp) {
|
|||
|
||||
sexp sexp_load_standard_parameters (sexp ctx, sexp e) {
|
||||
/* add io port and interaction env parameters */
|
||||
sexp_env_define(ctx, e, sexp_global(ctx, SEXP_G_CUR_IN_SYMBOL),
|
||||
sexp_make_input_port(ctx, stdin, SEXP_FALSE));
|
||||
sexp_env_define(ctx, e, sexp_global(ctx, SEXP_G_CUR_OUT_SYMBOL),
|
||||
sexp_make_output_port(ctx, stdout, SEXP_FALSE));
|
||||
sexp_env_define(ctx, e, sexp_global(ctx, SEXP_G_CUR_ERR_SYMBOL),
|
||||
sexp_make_output_port(ctx, stderr, SEXP_FALSE));
|
||||
sexp p = sexp_make_input_port(ctx, stdin, SEXP_FALSE);
|
||||
sexp_port_no_closep(p) = 1;
|
||||
sexp_env_define(ctx, e, sexp_global(ctx, SEXP_G_CUR_IN_SYMBOL), p);
|
||||
p = sexp_make_output_port(ctx, stdout, SEXP_FALSE);
|
||||
sexp_port_no_closep(p) = 1;
|
||||
sexp_env_define(ctx, e, sexp_global(ctx, SEXP_G_CUR_OUT_SYMBOL), p);
|
||||
p = sexp_make_output_port(ctx, stderr, SEXP_FALSE);
|
||||
sexp_port_no_closep(p) = 1;
|
||||
sexp_env_define(ctx, e, sexp_global(ctx, SEXP_G_CUR_ERR_SYMBOL), p);
|
||||
sexp_env_define(ctx, e, sexp_global(ctx, SEXP_G_INTERACTION_ENV_SYMBOL), e);
|
||||
return SEXP_VOID;
|
||||
}
|
||||
|
|
|
@ -190,7 +190,7 @@ struct sexp_struct {
|
|||
struct {
|
||||
FILE *stream;
|
||||
char *buf;
|
||||
char openp, sourcep;
|
||||
char openp, no_closep, sourcep;
|
||||
sexp_uint_t offset, line;
|
||||
size_t size;
|
||||
sexp name;
|
||||
|
@ -544,6 +544,7 @@ SEXP_API sexp sexp_make_unsigned_integer(sexp ctx, sexp_luint_t x);
|
|||
#define sexp_port_name(p) ((p)->value.port.name)
|
||||
#define sexp_port_line(p) ((p)->value.port.line)
|
||||
#define sexp_port_openp(p) ((p)->value.port.openp)
|
||||
#define sexp_port_no_closep(p) ((p)->value.port.no_closep)
|
||||
#define sexp_port_sourcep(p) ((p)->value.port.sourcep)
|
||||
#define sexp_port_cookie(p) ((p)->value.port.cookie)
|
||||
#define sexp_port_buf(p) ((p)->value.port.buf)
|
||||
|
@ -848,6 +849,7 @@ SEXP_API sexp sexp_read_raw(sexp ctx, sexp in);
|
|||
SEXP_API sexp sexp_read(sexp ctx, sexp in);
|
||||
SEXP_API sexp sexp_read_from_string(sexp ctx, char *str);
|
||||
SEXP_API sexp sexp_write_to_string(sexp ctx, sexp obj);
|
||||
SEXP_API sexp sexp_finalize_port (sexp ctx, sexp port);
|
||||
SEXP_API sexp sexp_make_input_port(sexp ctx, FILE* in, sexp name);
|
||||
SEXP_API sexp sexp_make_output_port(sexp ctx, FILE* out, sexp name);
|
||||
SEXP_API sexp sexp_make_input_string_port(sexp ctx, sexp str);
|
||||
|
|
18
sexp.c
18
sexp.c
|
@ -53,13 +53,20 @@ sexp sexp_alloc_tagged(sexp ctx, size_t size, sexp_uint_t tag) {
|
|||
return res;
|
||||
}
|
||||
|
||||
#if SEXP_USE_AUTOCLOSE_PORTS
|
||||
static sexp sexp_finalize_port (sexp ctx, sexp port) {
|
||||
if (sexp_port_openp(port) && sexp_port_stream(port)
|
||||
&& sexp_stringp(sexp_port_name(port)))
|
||||
fclose(sexp_port_stream(port));
|
||||
sexp sexp_finalize_port (sexp ctx, sexp port) {
|
||||
if (sexp_port_openp(port)) {
|
||||
sexp_port_openp(port) = 0;
|
||||
if (sexp_port_stream(port) && ! sexp_port_no_closep(port))
|
||||
fclose(sexp_port_stream(port));
|
||||
#if ! SEXP_USE_STRING_STREAMS
|
||||
if (sexp_port_buf(port) && sexp_oportp(port))
|
||||
free(sexp_port_buf(port));
|
||||
#endif
|
||||
}
|
||||
return SEXP_VOID;
|
||||
}
|
||||
|
||||
#if SEXP_USE_AUTOCLOSE_PORTS
|
||||
#define SEXP_FINALIZE_PORT sexp_finalize_port
|
||||
#else
|
||||
#define SEXP_FINALIZE_PORT NULL
|
||||
|
@ -1032,6 +1039,7 @@ sexp sexp_make_input_port (sexp ctx, FILE* in, sexp name) {
|
|||
sexp_port_line(p) = 1;
|
||||
sexp_port_buf(p) = NULL;
|
||||
sexp_port_openp(p) = 1;
|
||||
sexp_port_no_closep(p) = 0;
|
||||
sexp_port_sourcep(p) = 1;
|
||||
sexp_port_cookie(p) = SEXP_VOID;
|
||||
return p;
|
||||
|
|
Loading…
Add table
Reference in a new issue