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

Zero the initial file port revealed count.

Fixes <https://bugs.gnu.org/41204>.
Reported by Caleb Ristvedt <caleb.ristvedt@cune.org>.

Until now, Guile would leak the file descriptors of all the file ports
not explicitly closed.

* libguile/fports.c (scm_i_fdes_to_port): Initialize fp->revealed.
* test-suite/tests/ports.test ("initial revealed count")
("non-revealed port is closed"): New tests.
("close-port & revealed port"): Check (port-revealed port).
("revealed port fdes not closed"): Likewise.
This commit is contained in:
Ludovic Courtès 2020-05-12 14:55:09 +02:00
parent 2ba61b8aea
commit b1bdd791ce
2 changed files with 36 additions and 2 deletions

View file

@ -1,4 +1,4 @@
/* Copyright 1995-2004,2006-2015,2017-2019 /* Copyright 1995-2004,2006-2015,2017-2020
Free Software Foundation, Inc. Free Software Foundation, Inc.
This file is part of Guile. This file is part of Guile.
@ -452,6 +452,7 @@ scm_i_fdes_to_port (int fdes, long mode_bits, SCM name, unsigned options)
"file port"); "file port");
fp->fdes = fdes; fp->fdes = fdes;
fp->options = options; fp->options = options;
fp->revealed = 0;
port = scm_c_make_port (scm_file_port_type, mode_bits, (scm_t_bits)fp); port = scm_c_make_port (scm_file_port_type, mode_bits, (scm_t_bits)fp);

View file

@ -2,7 +2,7 @@
;;;; Jim Blandy <jimb@red-bean.com> --- May 1999 ;;;; Jim Blandy <jimb@red-bean.com> --- May 1999
;;;; ;;;;
;;;; Copyright (C) 1999, 2001, 2004, 2006, 2007, 2009, 2010, ;;;; Copyright (C) 1999, 2001, 2004, 2006, 2007, 2009, 2010,
;;;; 2011, 2012, 2013, 2014, 2015, 2017, 2019 Free Software Foundation, Inc. ;;;; 2011, 2012, 2013, 2014, 2015, 2017, 2019, 2020 Free Software Foundation, Inc.
;;;; ;;;;
;;;; This library is free software; you can redistribute it and/or ;;;; This library is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU Lesser General Public ;;;; modify it under the terms of the GNU Lesser General Public
@ -602,10 +602,40 @@
(pass-if "unread residue" (pass-if "unread residue"
(string=? (read-line) "moon")))) (string=? (read-line) "moon"))))
(pass-if-equal "initial revealed count" ;<https://bugs.gnu.org/41204>
0
(let* ((port (open-input-file "/dev/null"))
(revealed (port-revealed port)))
(close-port port)
revealed))
(pass-if-equal "non-revealed port is closed"
EBADF
(let* ((port (open-input-file "/dev/null"))
(fdes (fileno port))) ;leaves revealed count unchanged
(unless (zero? (port-revealed port))
(error "wrong revealed count" (port-revealed port)))
(set! port #f)
(gc)
(catch 'system-error
(lambda ()
(seek fdes 0 SEEK_CUR)
;; If we get here, it might be because PORT was not GC'd, we
;; don't know (and we can't use a guardian because it would keep
;; PORT alive.)
(close-fdes fdes)
(throw 'unresolved))
(lambda args
(system-error-errno args)))))
(pass-if-equal "close-port & revealed port" (pass-if-equal "close-port & revealed port"
EBADF EBADF
(let* ((port (open-file "/dev/null" "r0")) (let* ((port (open-file "/dev/null" "r0"))
(fdes (port->fdes port))) ;increments revealed count of PORT (fdes (port->fdes port))) ;increments revealed count of PORT
(unless (= 1 (port-revealed port))
(error "wrong revealed count" (port-revealed port)))
(close-port port) ;closes FDES as a side-effect (close-port port) ;closes FDES as a side-effect
(catch 'system-error (catch 'system-error
(lambda () (lambda ()
@ -617,6 +647,9 @@
(pass-if "revealed port fdes not closed" (pass-if "revealed port fdes not closed"
(let* ((port (open-file "/dev/null" "r0")) (let* ((port (open-file "/dev/null" "r0"))
(fdes (port->fdes port))) (fdes (port->fdes port)))
(unless (= 1 (port-revealed port))
(error "wrong revealed count" (port-revealed port)))
(set! port #f) (set! port #f)
(gc) (gc)