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