diff --git a/pkgs/racket-doc/scribblings/foreign/types.scrbl b/pkgs/racket-doc/scribblings/foreign/types.scrbl index 8f5be26795..357ad624a7 100644 --- a/pkgs/racket-doc/scribblings/foreign/types.scrbl +++ b/pkgs/racket-doc/scribblings/foreign/types.scrbl @@ -1023,13 +1023,11 @@ Racket vectors instead of lists.} (_bytes o len-expr)]]{ A @tech{custom function type} that can be used by itself as a simple -type for a byte string as a C pointer. Alternatively, the second form -is for a pointer return value, where the size should be explicitly -specified. - -There is no need for other modes analogous to those of @racket[_ptr]: -input or input/output would be just like @racket[_bytes], since the -string carries its size information.} +type for a byte string as a C pointer. Coercion of a C pointer to +simply @racket[_bytes] (without a specified length) requires that the pointer +refers to a nul-terminated byte string. When the length-specifying form is used +for a function argument, a byte string is allocated with the given +length, including an extra byte for the nul terminator.} @; ------------------------------------------------------------ diff --git a/racket/collects/ffi/unsafe.rkt b/racket/collects/ffi/unsafe.rkt index e4364b11d7..12ad43c6d6 100644 --- a/racket/collects/ffi/unsafe.rkt +++ b/racket/collects/ffi/unsafe.rkt @@ -1046,8 +1046,12 @@ (provide (rename-out [_bytes* _bytes])) (define-fun-syntax _bytes* (syntax-id-rules (o) - [(_ o n) (type: _pointer - pre: (make-sized-byte-string (malloc n) n) + [(_ o n) (type: _gcpointer + pre: (let ([bstr (make-sized-byte-string (malloc (add1 n)) n)]) + ;; Ensure a null terminator, so that the result is + ;; compatible with `_bytes`: + (ptr-set! bstr _byte n 0) + bstr) ;; post is needed when this is used as a function output type post: (x => (make-sized-byte-string x n)))] [(_ . xs) (_bytes . xs)]