File 2922-erts-Fix-writing-to-std-handler-when-detached.patch of Package erlang
From 0fc54754b4e2cac7c789b5a54d653de8bdd14cbf Mon Sep 17 00:00:00 2001
From: Lukas Larsson <lukas@erlang.org>
Date: Thu, 25 Aug 2022 14:25:01 +0200
Subject: [PATCH 02/34] erts: Fix writing to std handler when detached
When writing using erlang:display* when detached the
write operation would return an error on windows. So
we make sure that the handles are valid so that they
can always be written to.
---
erts/emulator/beam/bif.c | 28 +++++++++++++++++++++++++---
erts/etc/common/erlexec.c | 12 ++++++++++++
2 files changed, 37 insertions(+), 3 deletions(-)
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index c8e7caac15..b78942bd45 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -4191,18 +4191,30 @@ BIF_RETTYPE display_string_2(BIF_ALIST_2)
Sint len;
Sint written;
byte *str;
- int res, fd;
+ int res;
byte *temp_alloc = NULL;
+#ifdef __WIN32__
+ HANDLE fd;
+ if (ERTS_IS_ATOM_STR("stdout", BIF_ARG_1)) {
+ fd = GetStdHandle(STD_OUTPUT_HANDLE);
+ } else if (ERTS_IS_ATOM_STR("stderr", BIF_ARG_1)) {
+ fd = GetStdHandle(STD_ERROR_HANDLE);
+ }
+#else
+ int fd;
if (ERTS_IS_ATOM_STR("stdout", BIF_ARG_1)) {
fd = fileno(stdout);
} else if (ERTS_IS_ATOM_STR("stderr", BIF_ARG_1)) {
fd = fileno(stderr);
+ }
#if defined(HAVE_SYS_IOCTL_H) && defined(TIOCSTI)
- } else if (ERTS_IS_ATOM_STR("stdin", BIF_ARG_1)) {
+ else if (ERTS_IS_ATOM_STR("stdin", BIF_ARG_1)) {
fd = open("/proc/self/fd/0",0);
+ }
#endif
- } else {
+#endif
+ else {
BIF_ERROR(p, BADARG);
}
if (is_list(string) || is_nil(string)) {
@@ -4238,6 +4250,11 @@ BIF_RETTYPE display_string_2(BIF_ALIST_2)
} else
#endif
{
+#ifdef __WIN32__
+ if (!WriteFile(fd, str, len, &written, NULL)) {
+ goto error;
+ }
+#else
written = 0;
do {
res = write(fd, str+written, len-written);
@@ -4245,13 +4262,18 @@ BIF_RETTYPE display_string_2(BIF_ALIST_2)
goto error;
written += res;
} while (written < len);
+#endif
}
if (temp_alloc)
erts_free(ERTS_ALC_T_TMP, (void *) temp_alloc);
BIF_RET(am_true);
error: {
+#ifdef __WIN32__
+ char *errnostr = last_error();
+#else
char *errnostr = erl_errno_id(errno);
+#endif
BIF_P->fvalue = am_atom_put(errnostr, strlen(errnostr));
erts_free(ERTS_ALC_T_TMP, (void *) str);
BIF_ERROR(p, BADARG | EXF_HAS_EXT_INFO);
diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c
index b1e2118b7a..5d4432789b 100644
--- a/erts/etc/common/erlexec.c
+++ b/erts/etc/common/erlexec.c
@@ -453,6 +453,18 @@ int main(int argc, char **argv)
Eargsp[argc] = NULL;
emu = argv[0];
start_emulator_program = strsave(argv[0]);
+ /* We set the stdandard handles to nul in order for prim_tty_nif
+ and erlang:display_string to work without returning ebadf for
+ detached emulators */
+ SetStdHandle(STD_INPUT_HANDLE,
+ CreateFile("nul", GENERIC_READ, 0, NULL, OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, NULL));
+ SetStdHandle(STD_OUTPUT_HANDLE,
+ CreateFile("nul", GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, NULL));
+ SetStdHandle(STD_ERROR_HANDLE,
+ CreateFile("nul", GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, NULL));
goto skip_arg_massage;
}
free_env_val(s);
--
2.35.3