I see, so a socket can be assigned to a file descriptor with _open_osfhandle. I wasn't sure if it would work and I was aware that sockets cannot be closed with CloseHandle, so they must be closed with appropriate Win32 API.
This is all troubles for future me. Now I'm trying to finalize my implementation of newlocale/uselocale and once it's done I think I'll finally upload it to GitHub. ________________________________ From: Pali Rohár <[email protected]> Sent: Tuesday, September 9, 2025 7:43 PM To: Kirill Makurin <[email protected]> Cc: mingw-w64-public <[email protected]> Subject: Re: _getmode It is possible to assign a file descriptor for socket. There is a _open_osfhandle() function which can do that. Perl is using it (or used in the past when I was looking it at) as it at some level provides POSIX functions. That _pioinfo was needed exactly for socket usage as WinAPI socket must not be closed with CloseHandle (which is internally used by CRT fd), and perl deassigned WinAPI handle from CRT fd via _pioinfo. I have not looked which code page is used by putwc <--> putc conversion, but I guess that it would be codepage set by setlocale. If the stdout / stderr is associated with Windows console then also the codepage used by the console play role. It may be different than the one used by CRT setlocale and also different from the ACP and OCP. On Tuesday 09 September 2025 10:22:47 Kirill Makurin wrote: > 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
