I agree that leaving it implementation-dependent is dangerous, but I think this will require deep hooks into the implementation's port system, as Harold says.

On Sun, Aug 16, 2020 at 8:28 AM Shiro Kawai <xxxxxx@gmail.com> wrote:
I think "it depends" will make it tricky to make sure you won't leak fds or accidentally calls close on an already-closed fd (which is dangerous, for the fd may be reused by another thread after it was closed).  If you don't know, I think the safe way would be (1) you never call close on the port created by fd->*-port and (2) do not forget to call flush before closing the fd, in case it's an output port. 

I think the text you quoted suggests fds are not closed when the port created by fd->*port is closed, but unless anyone can definitely tell, it is better to be clarified.



On Sun, Aug 16, 2020 at 1:49 AM <xxxxxx@ancell-ent.com> wrote:
In reviewing all the issues Arthur had marked as unresolved, I noticed this question never got an answer; note one of the very last changes made to SRFI 170 was renaming "fdes", inherited from scsh, to the infinitely more common and standard since the 1970s "fd":

From: Shiro Kawai <xxxxxx@gmail.com>
Date: Friday, July 24, 2020 2:36 AM

Is it correct that I create a port from fdes[fd] by one of fdes[fd]->*-port, then close the port, the underlying fdes isn't automatically closed?

I guess it's the case from the paragraph 5 of "3.2 I/O", but I feel it can be explicitly noted in fdes[fd]->*-port section.

Given the addition of optional buffer-mode options for these procedures (in part, to allow multiple writers to take advantage of open/append when writing to a log file without overlapping due to blindly buffered output), a SRFI 170 implementor may get more deep into a Scheme implementation's port code than the simple case of mimicking the normal opening of a port (which is all I did for the Chibi Scheme sample implementation).

Still, it's likely the underlying close behavior will be that of the implementation's so I suppose the answer is, "it depends."  Here's John's introductory text for section 3.2 I/O; there is no further discussion of this issue in the procedure descriptions.

Dealing with POSIX file descriptors in a Scheme environment is difficult. In POSIX, open files are part of the process environment, and are referenced by small exact integers called file descriptors. Open file descriptors are the fundamental way I/O redirections are passed to subprocesses and executed programs, since file descriptors are preserved across fork and exec operations.

If a Scheme program only used Scheme ports, and never actually used file descriptors, this would not be a problem. But Scheme code needs to descend to the file descriptor level in at least two circumstances: when interfacing to foreign code, and when interfacing to a subprocess.

This causes a problem. Suppose we have a Scheme port constructed on top of file descriptor 3. We intend to execute a successor program that will expect this file descriptor. If we drop references to the port, the garbage collector may prematurely close file 3 before we fork the subprocess.

Unfortunately, there is no even vaguely portable solution to this problem. Scsh and Guile undertake heroic measures to open new file descriptors for ports when the old file descriptors are repurposed for something else, and to track when closing a port implies closing its file descriptor or not. But doing so involves more changes than an implementation should have to make in order to provide this SRFI.

Consequently, this SRFI assumes that file descriptors will only be used at the edges of the program, and that most I/O operations will be performed on ports. As an exception, open-file is provided, because it allows arguments that the Scheme standard does not. It returns a file descriptor that can then be converted to a port.


Shiro, does this sufficiently answer your concerns?

- Harold