diff --git a/pkgs/racket-doc/scribblings/foreign/misc.scrbl b/pkgs/racket-doc/scribblings/foreign/misc.scrbl index 566b19f07f..03670206ef 100644 --- a/pkgs/racket-doc/scribblings/foreign/misc.scrbl +++ b/pkgs/racket-doc/scribblings/foreign/misc.scrbl @@ -26,11 +26,16 @@ internal representation of @racket[vec].} Returns a pointer to an array of @racket[_double] values, which is the internal representation of @racket[flvec].} -@defproc[(saved-errno) exact-integer?]{ +@defproc*[([(saved-errno) exact-integer?] + [(saved-errno [new-value exact-integer?]) void?])]{ -Returns the value most recently saved (in the current thread) after a -foreign call with a non-@racket[#f] @racket[#:save-errno] option (see -@racket[_fun] and @racket[_cprocedure]).} +Returns or sets the error code saved for the current Racket +thread. The saved error code is set after a foreign call with a +non-@racket[#f] @racket[#:save-errno] option (see @racket[_fun] and +@racket[_cprocedure]), but it can also be set explicitly (for example, +to create mock foreign functions for testing). + +@history[#:changed "6.4.0.9"]{Added the one-argument variant.}} @defproc[(lookup-errno [sym (or/c 'EINTR 'EEXIST 'EAGAIN)]) exact-integer?]{ diff --git a/racket/src/foreign/foreign.c b/racket/src/foreign/foreign.c index 01147ed9ff..805b571bdd 100644 --- a/racket/src/foreign/foreign.c +++ b/racket/src/foreign/foreign.c @@ -4290,7 +4290,16 @@ static void save_errno_values(int kind) static Scheme_Object *foreign_saved_errno(int argc, Scheme_Object *argv[]) { Scheme_Thread *p = scheme_current_thread; - return scheme_make_integer_value(p->saved_errno); + if (argc == 0) { + return scheme_make_integer_value(p->saved_errno); + } else { + intptr_t v; + if (!scheme_get_int_val(argv[0], &v)) { + wrong_intptr(MYNAME, 0, argc, argv); + } + p->saved_errno = v; + return scheme_void; + } } #undef MYNAME @@ -4552,7 +4561,7 @@ void scheme_init_foreign(Scheme_Env *env) scheme_add_global_constant("ffi-callback", scheme_make_noncm_prim(foreign_ffi_callback, "ffi-callback", 3, 6), menv); scheme_add_global_constant("saved-errno", - scheme_make_immed_prim(foreign_saved_errno, "saved-errno", 0, 0), menv); + scheme_make_immed_prim(foreign_saved_errno, "saved-errno", 0, 1), menv); scheme_add_global_constant("lookup-errno", scheme_make_immed_prim(foreign_lookup_errno, "lookup-errno", 1, 1), menv); scheme_add_global_constant("make-stubborn-will-executor", @@ -4923,7 +4932,7 @@ void scheme_init_foreign(Scheme_Env *env) scheme_add_global_constant("ffi-callback", scheme_make_noncm_prim((Scheme_Prim *)unimplemented, "ffi-callback", 3, 6), menv); scheme_add_global_constant("saved-errno", - scheme_make_immed_prim((Scheme_Prim *)unimplemented, "saved-errno", 0, 0), menv); + scheme_make_immed_prim((Scheme_Prim *)unimplemented, "saved-errno", 0, 1), menv); scheme_add_global_constant("lookup-errno", scheme_make_immed_prim((Scheme_Prim *)unimplemented, "lookup-errno", 1, 1), menv); scheme_add_global_constant("make-stubborn-will-executor", diff --git a/racket/src/foreign/foreign.rktc b/racket/src/foreign/foreign.rktc index c9d81905c4..4581da12e6 100755 --- a/racket/src/foreign/foreign.rktc +++ b/racket/src/foreign/foreign.rktc @@ -3441,9 +3441,18 @@ static void save_errno_values(int kind) p->saved_errno = errno; } -@cdefine[saved-errno 0 #:kind immed]{ +@cdefine[saved-errno 0 1 #:kind immed]{ Scheme_Thread *p = scheme_current_thread; - return scheme_make_integer_value(p->saved_errno); + if (argc == 0) { + return scheme_make_integer_value(p->saved_errno); + } else { + intptr_t v; + if (!scheme_get_int_val(argv[0], &v)) { + wrong_intptr(MYNAME, 0, argc, argv); + } + p->saved_errno = v; + return scheme_void; + } } @cdefine[lookup-errno 1 #:kind immed]{