From: "Óscar Fuentes" <ofv@wanadoo.es>
To: Eli Zaretskii <eliz@gnu.org>
Cc: 73444@debbugs.gnu.org
Subject: bug#73444: 30.0.50; mingw-w64: Emacs uses CRT's `read` when _FORTIFY_SOURCE > 0
Date: Tue, 24 Sep 2024 14:55:56 +0200 [thread overview]
Message-ID: <87ed59xlb7.fsf@telefonica.net> (raw)
In-Reply-To: <86setpe0gm.fsf@gnu.org> (Eli Zaretskii's message of "Tue, 24 Sep 2024 14:48:57 +0300")
Eli Zaretskii <eliz@gnu.org> writes:
>> From: Óscar Fuentes <ofv@wanadoo.es>
>> Date: Tue, 24 Sep 2024 00:15:11 +0200
>>
>>
>> On Onssee
>> When the macro _FORTIFY_SOURCE > 0, mingw-64 provides an inline
>> definition of `read` on io.h:
>>
>> __mingw_bos_extern_ovr
>> int read(int __fh, void * __dst, unsigned int __n)
>> {
>> return _read(__fh, __dst, __n);
>> }
>
> Isn't that a bug in MinGW64's io.h? They should have used
>
> __mingw_bos_extern_ovr
> int (read)(int __fh, void * __dst, unsigned int __n)
> {
> return _read(__fh, __dst, __n);
> }
>
> Then we could modify the macro slightly as follows:
>
> #define read(h,d,n) sys_read(h,d,n)
>
> and avoid the problem. The above is how you protect your functions
> from being interpreted as macro invocations.
Well, AFAIK we are not supposed to #define names on the CRT namespace.
> But I guess this is water under the bridge now?
Yep, so discussing this is moot.
>> A hack that avoids this consists on doing something like:
>>
>> #define read dummy_read
>> // etc
>> #include <io.h>
>> // etc
>> #undef read
>> #define read sys_read
>> int sys_read (int, char *, unsigned int);
>
> This indeed needs the prototype for sys_read, which is less desirable,
> because we lose the ability to have the prototype exactly match io.h
> without knowing what's in io.h. But I guess there's no better way,
> sigh...
>
>> or simpler but untested:
>>
>> #define _read sys_read
>> // etc
>> #include <io.h>
>> // etc
>
> That's simply wrong: we do NOT want to replace the Microsoft '_read',
> we want to replace the Posix 'read' where it is used by Emacs.
Ok.
>> Either way it is necessary to condition the hack on the value of
>> _FORTIFY_SOURCE.
>
> We could do that unconditionally, no?
>
> Does the MinGW64 build with _FORTIFY_SOURCE work, after taking
> care of that?
I tested that Emacs/MinGW64 + _FORTIFY_SOURCE works with the
#define read dummy_read
hack. Once we put the prototype for sys_read on ms-w32.h, maybe there is
no need to put a conditional on _FORTIFY_SOURCE as well. I can check
that.
>> More generally, the way Emacs/NT overrides the CRT functions is
>> susceptible to break anytime upstream does something like, this case,
>> adding an inline definition, or some other unanticipated change. AFAIK
>> the C standard says that precisely what Emacs is doing incurs on
>> undefined behavior.
>>
>> Any ideas about how to future-proof the solution for this problem?
>
> Not elegant ones, no. We are redirecting Posix functions to our
> implementations where Emacs expects them to do something the MS
> runtime doesn't, and we don't want to reproduce all the stuff in the
> system headers that is related to those functions, including specific
> data types, symbols, etc.
>
>> BTW, the initial bug report for this was in March 2023 and only today
>> was succesfully analyzed (1) This gives an idea of how problematic this
>> practice of redefining standard functions can be.
>
> Trying to make Emacs work well on MS-Windows is problematic in itself,
> so we shouldn't be surprised it uses some "unconventional" techniques.
Indeed. I was hoping for a trick from some of you C wizards.
So, ok to install the workaround? On which branch?
1 file changed, 6 insertions(+), 1 deletion(-)
nt/inc/ms-w32.h | 7 ++++++-
modified nt/inc/ms-w32.h
@@ -257,7 +257,7 @@ extern void w32_reset_stack_overflow_guard (void);
#define link sys_link
#define localtime sys_localtime
#undef read
-#define read sys_read
+#define read unwanted_read // Override the CRT read, see #73444
#define rename sys_rename
#define rmdir sys_rmdir
#define select sys_select
@@ -380,6 +380,11 @@ extern struct tm *localtime_r (time_t const * restrict, struct tm * restrict);
#define fileno _fileno
#endif
+// Here we override CRT read with our own, see #73444
+#undef read
+#define read sys_read
+int sys_read (int, char *, unsigned int);
+
/* Defines that we need that aren't in the standard signal.h. */
#define SIGHUP 1 /* Hang up */
#define SIGQUIT 3 /* Quit process */
next prev parent reply other threads:[~2024-09-24 12:55 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-23 22:15 bug#73444: 30.0.50; mingw-w64: Emacs uses CRT's `read` when _FORTIFY_SOURCE > 0 Óscar Fuentes
[not found] ` <handler.73444.B.17271297536353.ack@debbugs.gnu.org>
2024-09-23 22:29 ` Óscar Fuentes
2024-09-24 11:51 ` Eli Zaretskii
2024-09-24 12:34 ` Óscar Fuentes
2024-09-24 13:12 ` Eli Zaretskii
2024-09-24 14:06 ` Óscar Fuentes
2024-09-24 15:36 ` Eli Zaretskii
2024-09-24 11:48 ` Eli Zaretskii
2024-09-24 12:55 ` Óscar Fuentes [this message]
2024-09-24 13:27 ` Eli Zaretskii
[not found] <PAWPR10MB776986E318800B89028B74F7F0682@PAWPR10MB7769.EURPRD10.PROD.OUTLOOK.COM>
2024-09-25 10:13 ` Óscar Fuentes
2024-09-25 11:46 ` Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87ed59xlb7.fsf@telefonica.net \
--to=ofv@wanadoo.es \
--cc=73444@debbugs.gnu.org \
--cc=eliz@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).