diff --git a/collects/tests/racket/place-ports.rkt b/collects/tests/racket/place-ports.rkt index e4a9063f09..7c70695df0 100644 --- a/collects/tests/racket/place-ports.rkt +++ b/collects/tests/racket/place-ports.rkt @@ -7,6 +7,16 @@ (define (main) + (test-exn + "using a closed port with place*" + (lambda (x) (void)) + (let () + (define op (open-output-bytes)) + (call-with-output-file "foo.foo" #:exists 'replace (lambda (op) + (close-output-port op) + (let-values ([(p pin pout perr) (place* #:out op ch (printf "Hello3\n"))]) + (place-wait p)))))) + (place-wait (place ch (printf "Hello1\n"))) (place-wait (place ch (eprintf "Hello2\n"))) (place-wait (place ch (printf "~a\n" (read)))) ; # diff --git a/src/racket/src/place.c b/src/racket/src/place.c index f4094b08c8..5772b24c77 100644 --- a/src/racket/src/place.c +++ b/src/racket/src/place.c @@ -349,6 +349,8 @@ Scheme_Object *scheme_place(int argc, Scheme_Object *args[]) { int errorno; if (SCHEME_TRUEP(in_arg)) { + if (scheme_port_closed_p(in_arg)) + scheme_arg_mismatch("dynamic-place", "port is closed: ", in_arg); scheme_get_port_file_descriptor(in_arg, &tmpfd); tmpfd = scheme_dup_file(tmpfd); if (tmpfd == -1) { @@ -365,6 +367,8 @@ Scheme_Object *scheme_place(int argc, Scheme_Object *args[]) { } if (SCHEME_TRUEP(out_arg)) { + if (scheme_port_closed_p(out_arg)) + scheme_arg_mismatch("dynamic-place", "port is closed: ", out_arg); scheme_get_port_file_descriptor(out_arg, &tmpfd); tmpfd = scheme_dup_file(tmpfd); if (tmpfd == -1) { @@ -381,6 +385,8 @@ Scheme_Object *scheme_place(int argc, Scheme_Object *args[]) { } if (SCHEME_TRUEP(err_arg)) { + if (scheme_port_closed_p(err_arg)) + scheme_arg_mismatch("dynamic-place", "port is closed: ", err_arg); scheme_get_port_file_descriptor(err_arg, &tmpfd); tmpfd = scheme_dup_file(tmpfd); if (tmpfd == -1) { diff --git a/src/racket/src/portfun.c b/src/racket/src/portfun.c index 365a34ecb7..b0757f1900 100644 --- a/src/racket/src/portfun.c +++ b/src/racket/src/portfun.c @@ -2182,6 +2182,10 @@ static Scheme_Object *port_closed_p (int argc, Scheme_Object *argv[]) } } +intptr_t scheme_port_closed_p (Scheme_Object *port) { + return (port_closed_p(1, &port) == scheme_false) ? 0 : 1; +} + static Scheme_Object *current_input_port(int argc, Scheme_Object *argv[]) { return scheme_param_config("current-input-port", scheme_make_integer(MZCONFIG_INPUT_PORT), diff --git a/src/racket/src/schpriv.h b/src/racket/src/schpriv.h index bb998ccc03..61d10c33c9 100644 --- a/src/racket/src/schpriv.h +++ b/src/racket/src/schpriv.h @@ -3495,6 +3495,7 @@ int scheme_byte_ready_or_user_port_ready(Scheme_Object *p, Scheme_Schedule_Info int scheme_pipe_char_count(Scheme_Object *p); void scheme_alloc_global_fdset(); Scheme_Object *scheme_port_name(Scheme_Object *p); +intptr_t scheme_port_closed_p (Scheme_Object *port); #define CURRENT_INPUT_PORT(config) scheme_get_param(config, MZCONFIG_INPUT_PORT) #define CURRENT_OUTPUT_PORT(config) scheme_get_param(config, MZCONFIG_OUTPUT_PORT)