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

openSUSE Build Service is sponsored by