A closed fd 1 is a fd 1 waiting to be handed to something else
The merged exit closes stdout so the compiler reads EOF and learns the program has finished. POSIX then hands descriptor 1 to the next thing that asks — a socket, a module's object file — and the llc after that inherits it as its stdout. /dev/null takes the slot back, and the EOF is unaffected because the pipe's write end is genuinely gone. Verified beyond the headless suite: sand.flan builds and runs merged under Xvfb, one process with no children, and a game-draw typed in at the socket is drawing frames a second later.
This commit is contained in:
parent
884d6a4d47
commit
1b39de32b0
@ -1888,6 +1888,7 @@ let merged_main_source = {c|
|
||||
#include <caml/callback.h>
|
||||
#include <caml/mlvalues.h>
|
||||
#include <pthread.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdatomic.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@ -1918,6 +1919,11 @@ static void flan_merged_exit(int32_t status) {
|
||||
(void)status;
|
||||
fflush(NULL);
|
||||
close(1);
|
||||
/* ...and take fd 1 straight back, because POSIX hands out the lowest free
|
||||
* descriptor: leave it open and the compiler thread's next socket or file
|
||||
* becomes this process's stdout, and the next llc inherits it. The EOF is
|
||||
* unaffected — the pipe's write end is genuinely gone. */
|
||||
if (open("/dev/null", O_WRONLY) < 0) { /* nothing useful to do about it */ }
|
||||
for (;;) pause();
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user