Alien-uv
view release on metacpan or search on metacpan
libuv/src/win/process.c view on Meta::CPAN
required_vars[i].len,
*ptr_copy);
}
if (cmp < 0) {
/* missing required var */
len = required_vars_value_len[i];
if (len) {
wcscpy(ptr, required_vars[i].wide_eq);
ptr += required_vars[i].len;
var_size = GetEnvironmentVariableW(required_vars[i].wide,
ptr,
(int) (env_len - (ptr - dst)));
if (var_size != (DWORD) (len - 1)) { /* TODO: handle race condition? */
uv_fatal_error(GetLastError(), "GetEnvironmentVariableW");
}
}
i++;
} else {
/* copy var from env_block */
len = wcslen(*ptr_copy) + 1;
wmemcpy(ptr, *ptr_copy, len);
ptr_copy++;
if (cmp == 0)
i++;
}
}
/* Terminate with an extra NULL. */
assert(env_len == (size_t) (ptr - dst));
*ptr = L'\0';
uv__free(dst_copy);
*dst_ptr = dst;
return 0;
}
/*
* Attempt to find the value of the PATH environment variable in the child's
* preprocessed environment.
*
* If found, a pointer into `env` is returned. If not found, NULL is returned.
*/
static WCHAR* find_path(WCHAR *env) {
for (; env != NULL && *env != 0; env += wcslen(env) + 1) {
if ((env[0] == L'P' || env[0] == L'p') &&
(env[1] == L'A' || env[1] == L'a') &&
(env[2] == L'T' || env[2] == L't') &&
(env[3] == L'H' || env[3] == L'h') &&
(env[4] == L'=')) {
return &env[5];
}
}
return NULL;
}
/*
* Called on Windows thread-pool thread to indicate that
* a child process has exited.
*/
static void CALLBACK exit_wait_callback(void* data, BOOLEAN didTimeout) {
uv_process_t* process = (uv_process_t*) data;
uv_loop_t* loop = process->loop;
assert(didTimeout == FALSE);
assert(process);
assert(!process->exit_cb_pending);
process->exit_cb_pending = 1;
/* Post completed */
POST_COMPLETION_FOR_REQ(loop, &process->exit_req);
}
/* Called on main thread after a child process has exited. */
void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) {
int64_t exit_code;
DWORD status;
assert(handle->exit_cb_pending);
handle->exit_cb_pending = 0;
/* If we're closing, don't call the exit callback. Just schedule a close
* callback now. */
if (handle->flags & UV_HANDLE_CLOSING) {
uv_want_endgame(loop, (uv_handle_t*) handle);
return;
}
/* Unregister from process notification. */
if (handle->wait_handle != INVALID_HANDLE_VALUE) {
UnregisterWait(handle->wait_handle);
handle->wait_handle = INVALID_HANDLE_VALUE;
}
/* Set the handle to inactive: no callbacks will be made after the exit
* callback. */
uv__handle_stop(handle);
if (GetExitCodeProcess(handle->process_handle, &status)) {
exit_code = status;
} else {
/* Unable to obtain the exit code. This should never happen. */
exit_code = uv_translate_sys_error(GetLastError());
}
/* Fire the exit callback. */
if (handle->exit_cb) {
handle->exit_cb(handle, exit_code, handle->exit_signal);
}
}
void uv_process_close(uv_loop_t* loop, uv_process_t* handle) {
uv__handle_closing(handle);
if (handle->wait_handle != INVALID_HANDLE_VALUE) {
/* This blocks until either the wait was cancelled, or the callback has
* completed. */
BOOL r = UnregisterWaitEx(handle->wait_handle, INVALID_HANDLE_VALUE);
if (!r) {
/* This should never happen, and if it happens, we can't recover... */
uv_fatal_error(GetLastError(), "UnregisterWaitEx");
}
( run in 0.366 second using v1.01-cache-2.11-cpan-acebb50784d )