[m-users.] How to get the file descriptor of a stream

Julien Fischer jfischer at opturion.com
Thu Jul 20 17:01:04 AEST 2023


Hi Volker,

On Thu, 20 Jul 2023, Volker Wysk wrote:

> I would like to have a predicate which returns the file descriptor, which is
> used to implement a stream. Such as the fileno(3) C library function. It's
> for querying the terminal width, of streams that can be connected to a
> terminal. I want to print (error and normal) messages which are formatted
> for the terminal's width.
>
> There's stdout_stream and stderr_stream and you can assume that they have
> the file descriptors 1 and 2. But this isn't foolproof and other streams
> might be connected to a terminal as well (or isn't it?).
>
> It might, for instance, theoretically happen that stdout_stream is closed
> and the file descriptor 1 gets reused later. Then we could end up with a fd
> 1 which doesn't belong to stdout_stream.
>
> I've searched the io and stream libraries, but couldn't find such a
> predicate.

For the C backends, it's straightfoward to get the file descriptor for a
Mercury file stream. Here's how you do it for text streams (binary
file streams would be very similar).

:- pred get_text_input_stream_fd(io.text_input_stream::in, int::out,
      io::di, io::uo) is det.

:- pragma foreign_proc("C",
     get_text_input_stream_fd(Stream::in, FD::out, _IO0::di, _IO::uo),
     [will_not_call_mercury, promise_pure, tabled_for_io],
"
     FD = fileno(MR_file(*MR_unwrap_input_stream(Stream)));
").

:- pred get_text_output_stream_fd(io.text_output_stream::in, int::out,
       io::di, io::uo) is det.

:- pragma foreign_proc("C",
     get_text_output_stream_fd(Stream::in, FD::out, _IO0::di, _IO::uo),
     [will_not_call_mercury, promise_pure, tabled_for_io],
"
     FD = fileno(MR_file(*MR_unwrap_output_stream(Stream)));
").

Julien.


More information about the users mailing list