1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-02 04:40:29 +02:00

Add support for "e" flag (O_CLOEXEC) to 'open-file'.

* libguile/fports.c (scm_i_mode_to_open_flags): Add 'e' case.
(scm_open_file_with_encoding): Document it.
* test-suite/standalone/test-close-on-exec: New file.
* test-suite/standalone/Makefile.am (check_SCRIPTS, TESTS): Add it.
* doc/ref/api-io.texi (File Ports): Document it.
* NEWS: Update.
This commit is contained in:
Ludovic Courtès 2022-09-07 17:48:12 +02:00
parent 3cd4881504
commit a356ceebee
5 changed files with 59 additions and 2 deletions

7
NEWS
View file

@ -11,6 +11,13 @@ Changes in 3.0.9 (since 3.0.8)
* New interfaces and functionality * New interfaces and functionality
** `open-file' now supports an "e" flag for O_CLOEXEC
Until now, the high-level `open-file' facility did not provide a way to
pass O_CLOEXEC to the underlying `open' call. It can now be done by
appending "e" to the `mode' string passed as a second argument. See
"File Ports" in the manual for more info.
** Abstract Unix-domain sockets are supported ** Abstract Unix-domain sockets are supported
It is now possible to create an AF_UNIX socket with a leading zero byte It is now possible to create an AF_UNIX socket with a leading zero byte

View file

@ -996,6 +996,9 @@ Also, open the file using the binary-compatible character encoding
@item + @item +
Open the port for both input and output. E.g., @code{r+}: open Open the port for both input and output. E.g., @code{r+}: open
an existing file for both input and output. an existing file for both input and output.
@item e
Mark the underlying file descriptor as close-on-exec, as per the
@code{O_CLOEXEC} flag.
@item 0 @item 0
Create an "unbuffered" port. In this case input and output Create an "unbuffered" port. In this case input and output
operations are passed directly to the underlying port operations are passed directly to the underlying port

View file

@ -1,4 +1,4 @@
/* Copyright 1995-2004,2006-2015,2017-2020 /* Copyright 1995-2004,2006-2015,2017-2020,2022
Free Software Foundation, Inc. Free Software Foundation, Inc.
This file is part of Guile. This file is part of Guile.
@ -208,6 +208,9 @@ scm_i_mode_to_open_flags (SCM mode, int *is_binary, const char *FUNC_NAME)
flags |= O_BINARY; flags |= O_BINARY;
#endif #endif
break; break;
case 'e':
flags |= O_CLOEXEC;
break;
case '0': /* unbuffered: handled later. */ case '0': /* unbuffered: handled later. */
case 'l': /* line buffered: handled during output. */ case 'l': /* line buffered: handled during output. */
break; break;
@ -368,6 +371,9 @@ SCM_DEFINE (scm_i_open_file, "open-file", 2, 0, 1,
"@item +\n" "@item +\n"
"Open the port for both input and output. E.g., @code{r+}: open\n" "Open the port for both input and output. E.g., @code{r+}: open\n"
"an existing file for both input and output.\n" "an existing file for both input and output.\n"
"@item e\n"
"Mark the underlying file descriptor as close-on-exec, as per the\n"
"@code{O_CLOEXEC} flag.\n"
"@item 0\n" "@item 0\n"
"Create an \"unbuffered\" port. In this case input and output\n" "Create an \"unbuffered\" port. In this case input and output\n"
"operations are passed directly to the underlying port\n" "operations are passed directly to the underlying port\n"

View file

@ -1,7 +1,7 @@
## Process this file with automake to produce Makefile.in. ## Process this file with automake to produce Makefile.in.
## ##
## Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, ## Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
## 2011, 2012, 2013, 2014, 2020, 2021 Free Software Foundation, Inc. ## 2011, 2012, 2013, 2014, 2020, 2021, 2022 Free Software Foundation, Inc.
## ##
## This file is part of GUILE. ## This file is part of GUILE.
## ##
@ -301,4 +301,7 @@ TESTS += test-stack-overflow
check_SCRIPTS += test-out-of-memory check_SCRIPTS += test-out-of-memory
TESTS += test-out-of-memory TESTS += test-out-of-memory
check_SCRIPTS += test-close-on-exec
TESTS += test-close-on-exec
EXTRA_DIST += ${check_SCRIPTS} EXTRA_DIST += ${check_SCRIPTS}

View file

@ -0,0 +1,38 @@
#!/bin/sh
exec guile -q -s "$0" "$@"
!#
;;; Exercise the 'e' flag to 'open-file' (O_CLOEXEC).
(define file
(string-append (or (getenv "TMPDIR") "/tmp")
"/guile-test-close-on-exec-"
(number->string (getpid)) ".txt"))
;;; Since fcntl(2) F_GETFD does not return flags such as O_CLOEXEC,
;;; create a child process, call 'exec', and make sure it doesn't
;;; inherit the file descriptor.
(let ((port (open-file file "we")))
(display "Hello!\n" port)
(let ((pid (primitive-fork)))
(if (zero? pid)
(dynamic-wind
(const #t)
(lambda ()
(execlp "guile" "guile" "-c"
(object->string
`(catch #t
(lambda ()
(fdopen ,(fileno port) "w")
(primitive-exit 0))
(lambda (key . args)
(pk 'child-exception args)
(if (and (eq? key 'system-error)
(= EBADF (system-error-errno (cons key args))))
(primitive-exit 1)
(primitive-exit 2)))))))
(lambda ()
(primitive-exit 3)))
(let ((status (pk 'child-status (cdr (waitpid pid)))))
(false-if-exception (delete-file file))
(exit (equal? (status:exit-val status) 1))))))