15 static HANDLE myCreateChildProcess(
const char *szCmdline) {
16 PROCESS_INFORMATION piProcInfo = { 0 };
17 STARTUPINFO siStartInfo = { 0 };
18 BOOL bSuccess =
FALSE;
19 siStartInfo.cb =
sizeof(STARTUPINFO);
20 siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
21 siStartInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
22 siStartInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
23 siStartInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
25 LPTSTR cmdline_ = rz_sys_conv_utf8_to_win(szCmdline);
29 return bSuccess ? piProcInfo.hProcess :
NULL;
34 #define PIPE_BUF_SIZE 8192
36 static void lang_pipe_run_win(
RzLang *lang) {
37 CHAR
buf[PIPE_BUF_SIZE];
40 DWORD dwRead = 0, dwWritten = 0, dwEvent;
55 TerminateProcess(hproc, 0);
58 OVERLAPPED oRead = { 0 };
61 ReadFile(hPipeInOut,
buf, PIPE_BUF_SIZE,
NULL, &oRead);
62 HANDLE hReadEvents[] = { hRead, hproc };
63 dwEvent = WaitForMultipleObjects(
RZ_ARRAY_SIZE(hReadEvents), hReadEvents,
65 if (dwEvent == WAIT_OBJECT_0 + 1) {
67 }
else if (dwEvent == WAIT_FAILED) {
68 rz_sys_perror(
"lang_pipe_run_win/WaitForMultipleObjects read");
71 bSuccess = GetOverlappedResult(hPipeInOut, &oRead, &dwRead,
TRUE);
75 if (bSuccess && dwRead > 0) {
77 OVERLAPPED oWrite = { 0 };
78 oWrite.hEvent = hWritten;
81 int res_len = strlen(res) + 1;
82 for (
i = 0;
i < res_len;
i++) {
85 int writelen = res_len -
i;
86 WriteFile(hPipeInOut, res +
i,
87 writelen > PIPE_BUF_SIZE ? PIPE_BUF_SIZE : writelen,
89 HANDLE hWriteEvents[] = { hWritten, hproc };
90 dwEvent = WaitForMultipleObjects(
RZ_ARRAY_SIZE(hWriteEvents), hWriteEvents,
92 if (dwEvent == WAIT_OBJECT_0 + 1) {
94 }
else if (dwEvent == WAIT_FAILED) {
95 rz_sys_perror(
"lang_pipe_run_win/WaitForMultipleObjects write");
97 BOOL rc = GetOverlappedResult(hPipeInOut, &oWrite, &dwWritten,
TRUE);
112 WriteFile(hPipeInOut,
"", 1,
NULL, &oWrite);
113 if (!GetOverlappedResult(hPipeInOut, &oWrite, &dwWritten,
TRUE)) {
120 CloseHandle(hWritten);
124 static void env(
const char *
s,
int f) {
134 int safe_in =
dup(0);
140 eprintf(
"rz_lang_pipe: pipe failed on input\n");
147 eprintf(
"rz_lang_pipe: pipe failed on output\n");
175 char *res,
buf[8192];
201 eprintf(
"rz_lang_pipe: NULL reply for (%s)\n",
buf);
211 char *term_in = ttyname(0);
217 eprintf(
"Cannot open ttyname(0) %s\n", term_in);
229 waitpid(child,
NULL, WNOHANG);
233 char *rzpipe_var =
rz_str_newf(
"RZ_PIPE_IN%x", _getpid());
234 char *rzpipe_paz =
rz_str_newf(
"\\\\.\\pipe\\%s", rzpipe_var);
235 LPTSTR rzpipe_paz_ = rz_sys_conv_utf8_to_win(rzpipe_paz);
237 SetEnvironmentVariable(TEXT(
"RZ_PIPE_PATH"), rzpipe_paz_);
238 hPipeInOut = CreateNamedPipe(rzpipe_paz_,
239 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
240 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES,
253 OVERLAPPED oConnect = { 0 };
254 oConnect.hEvent = hConnected;
255 hproc = myCreateChildProcess(
code);
256 BOOL connected =
FALSE;
258 connected = ConnectNamedPipe(hPipeInOut, &oConnect);
260 if (!connected &&
err != ERROR_PIPE_CONNECTED) {
261 if (
err == ERROR_IO_PENDING) {
262 HANDLE hEvents[] = { hConnected, hproc };
265 if (dwEvent == WAIT_OBJECT_0 + 1) {
267 }
else if (dwEvent == WAIT_FAILED) {
268 rz_sys_perror(
"lang_pipe_run/WaitForMultipleObjects connect");
272 connected = GetOverlappedResult(hPipeInOut, &oConnect, &dummy,
TRUE);
273 err = GetLastError();
275 if (!connected &&
err != ERROR_PIPE_CONNECTED) {
280 lang_pipe_run_win(lang);
283 CloseHandle(hConnected);
285 DeleteFile(rzpipe_paz_);
286 CloseHandle(hPipeInOut);
291 return hproc !=
NULL;
RZ_API void * rz_cons_sleep_begin(void)
RZ_API void rz_cons_break_pop(void)
RZ_API void rz_cons_break_push(RzConsBreak cb, void *user)
RZ_API bool rz_cons_is_breaked(void)
RZ_API void rz_cons_sleep_end(void *user)
static static fork const void static count close
RZ_API void Ht_() free(HtName_(Ht) *ht)
#define INVALID_HANDLE_VALUE
return memset(p, 0, total)
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode dup
static static fork const void static count static fd const char static mode const char static pathname const char static path const char static dev const char static group static getpid static getuid void void static data static pause const char static mode static sync const char const char static newpath const char static pathname unsigned long static filedes void static end_data_segment static handler static getegid char static len static pgid const char static path dup2
RZ_IPI int lang_pipe_run(RzLang *lang, const char *code, int len)
static void env(const char *s, int f)
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API int rz_sys_setenv(const char *key, const char *value)
Set an environment variable in the calling process.
RZ_API int rz_sys_pipe(int pipefd[2], bool close_on_exec)
RZ_API void rz_sys_exit(int status, bool nocleanup)
#define rz_sys_xsystem(cmd)
RZ_API int rz_sys_fork(void)
RZ_API int rz_sys_pipe_close(int fd)
#define rz_xwrite(fd, buf, count)
RzCoreCmdStrCallback cmd_str
static bool input(void *ud, zip_uint8_t *data, zip_uint64_t length)
int read(izstream &zs, T *x, Items items)