I am not sure if it is possible to assign a file descriptor for socket and 
whether CRT's _read/_write will work with such file descriptor. My guess is no, 
but I didn't test it.

The reason why I wonder about getting current translation mode is my project 
I'm working on. At some point (not soon, apparently) I'll get to implementing 
POSIX-compatible printf/scanf functions and knowing what translation mode is 
set on FILE would be crucial.

If it is any of _O_{W|U8|U16}TEXT (so it does not really matter which 
particular one is set), then it possible to simply use fputws or _lock_file + 
_fputwc_nolock to write the formatted string to the stream. It is also possible 
to use wide versions on _O_TEXT file descriptors, but this raises some 
questions:

1) What code page is used for output? Active locale when FILE object was 
created? Current active locale (which may be a thread-specific locale since 
msvcr80.dll)?
2) Since CRT's C89/C95 conversion functions perform loosy (best-fit) conversion 
it is possible that written text will not be the same. This is a data loss and 
unacceptable.

I didn't test these, yet. There may be more issues to consider.
________________________________
From: Pali Rohár <[email protected]>
Sent: Tuesday, September 9, 2025 6:51 PM
To: Kirill Makurin <[email protected]>
Cc: mingw-w64-public <[email protected]>
Subject: Re: _getmode

I think that there is no any official way.

I also does not like it but sometimes there is no other way. For example
perl is using that _pioinfo code (or used it in the past), I originally
took and reused that logic from perl.

DuplicateHandle is problematic, for example it must not be called on the
network socket handles.

So if it is not necessary I would avoid trying to get current mode.

Note that the type of return value of _setmode is not same as the type
of its input argument. _O_U16TEXT and _O_U8TEXT are not returned.
Instead _O_WTEXT is returned for those two cases.

I had an idea to call _setmode under the same recursive lock as _setmode
is internally using, to get the current mode and set it back. But that
is not possible due to above difference.

On Tuesday 09 September 2025 09:34:48 Kirill Makurin wrote:
> I was thinking it could be implemented with something like this
>
> ```
> Int _getmode (int fd) {
>   int copy = _dup (fd);
>   int mode = _setmode (copy, _O_BINARY);
>  _close (copy)
>  return mode;
> }
> ```
>
> However,
>
> 1) call to _dup() seems expensive to me; I am not sure if _dup() calls 
> DuplicateHandle underneath
> 2) fd's buffer must be flushed before calling _setmode() or it may result in 
> data corruption
>
> I personally don't like accessing CRTs private objects. Thanks for looking 
> into it anyway.
>
> - Kirill Makurin
> ________________________________
> From: Pali Rohár <[email protected]>
> Sent: Tuesday, September 9, 2025 3:36 AM
> To: Kirill Makurin <[email protected]>
> Cc: mingw-w64-public <[email protected]>
> Subject: _getmode
>
> On Monday 08 September 2025 19:09:24 Pali Rohár wrote:
> > On Monday 08 September 2025 09:19:52 Kirill Makurin wrote:
> > > Speaking of _setmode, I wonder if there is a way to obtain which 
> > > translation mode is set on particular file descriptor? It's kinda dumb 
> > > that there is no way to get it other than calling _setmode (it returns 
> > > previous translation mode).
> >
> > I will look at this. I have an idea how to get this information.
>
> Here is implementation of _getmode() macro. It reads the mode
> information from global array __pioinfo which is exported since
> msvcrt.dll (4.2) version and then all later version. But it is not in
> UCRT. That _pioinfo(fh) definition I used more times in the past.
>
>   #include <stdio.h>
>   #include <stddef.h>
>   #include <fcntl.h>
>   #include <windows.h>
>   typedef struct {
>     intptr_t osfhnd;
>     char osfile;
>     char pipech;
>     int lockinitflag;
>     CRITICAL_SECTION lock;
>     char textmode;
>     char reminders[];
>   } ioinfo;
>   extern __declspec(dllimport) ioinfo* __pioinfo[];
>   #define IOINFO_L2E 5
>   #define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
>   #define _ioinfo_size (_msize((void*)__pioinfo[0]) / IOINFO_ARRAY_ELTS)
>   #define _pioinfo(fh) ((ioinfo *) \
>     (((size_t)__pioinfo[(fh) >> IOINFO_L2E])/* * to head of array ioinfo [] 
> */\
>      /* offset to the head of a particular ioinfo struct */ \
>      + (((fh) & (IOINFO_ARRAY_ELTS - 1)) * _ioinfo_size)) \
>    )
>   #define FTEXT 0x80
>   #define _osfile(fh) (_pioinfo(fh)->osfile)
>   #define _textmode(fh) (_ioinfo_size >= (offsetof(ioinfo, textmode) + 
> sizeof(char)) ? (_pioinfo(fh)->textmode) : 0)
>   #define _getmode(fh) ((!(_osfile(fh) & FTEXT)) ? _O_BINARY : (_textmode(fh) 
> == 0) ? _O_TEXT : _O_WTEXT)

_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to