Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

uv_kill

  • Loading branch information...
Igor Zinkovsky
Igor Zinkovsky committed Nov 2, 2011
1 parent 8d5c64a commit 74b49e821b8ea63052f28cfa1155e813a1b5f07b
Showing with 119 additions and 32 deletions.
  1. +4 −0 include/uv.h
  2. +0 −2 src/unix/dl.c
  3. +11 −0 src/unix/process.c
  4. +3 −0 src/uv-common.c
  5. +2 −0 src/uv-common.h
  6. +0 −3 src/win/error.c
  7. +0 −5 src/win/internal.h
  8. +54 −21 src/win/process.c
  9. +2 −0 test/test-list.h
  10. +43 −1 test/test-spawn.c
@@ -983,6 +983,10 @@ UV_EXTERN int uv_spawn(uv_loop_t*, uv_process_t*,
UV_EXTERN int uv_process_kill(uv_process_t*, int signum);


/* Kills the process with the specified signal. */
UV_EXTERN uv_err_t uv_kill(int pid, int signum);


/*
* uv_work_t is a subclass of uv_req_t
*/
@@ -26,8 +26,6 @@
#include <errno.h>


static const uv_err_t uv_ok_ = { UV_OK, 0 };

uv_err_t uv_dlopen(const char* filename, uv_lib_t* library) {
void* handle = dlopen(filename, RTLD_LAZY);
if (handle == NULL) {
@@ -300,3 +300,14 @@ int uv_process_kill(uv_process_t* process, int signum) {
return 0;
}
}


uv_err_t uv_kill(int pid, int signum) {
int r = kill(pid, signum);

if (r) {
return uv__new_sys_error(errno);
} else {
return uv_ok_;
}
}
@@ -48,6 +48,9 @@ uv_buf_t uv_buf_init(char* base, size_t len) {
}


const uv_err_t uv_ok_ = { UV_OK, 0 };


const char* uv_err_name(uv_err_t err) {
switch (err.code) {
case UV_UNKNOWN: return "UNKNOWN";
@@ -48,6 +48,8 @@ void uv_add_ares_handle(uv_loop_t* loop, uv_ares_task_t* handle);

int uv_ares_handles_empty(uv_loop_t* loop);

extern const uv_err_t uv_ok_;

uv_err_code uv_translate_sys_error(int sys_errno);
void uv__set_error(uv_loop_t* loop, uv_err_code code, int sys_error);
void uv__set_sys_error(uv_loop_t* loop, int sys_error);
@@ -30,9 +30,6 @@
#include "internal.h"


const uv_err_t uv_ok_ = { UV_OK, ERROR_SUCCESS };


/*
* Display an error message and abort the event loop.
*/
@@ -286,11 +286,6 @@ void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle);
int uv_parent_pid();


/*
* Error handling
*/
extern const uv_err_t uv_ok_;

void uv_fatal_error(const int errorno, const char* syscall);

uv_err_code uv_translate_sys_error(int sys_errno);
@@ -26,8 +26,11 @@
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <signal.h>
#include <windows.h>

#define SIGKILL 9

typedef struct env_var {
const char* narrow;
const wchar_t* wide;
@@ -1052,35 +1055,65 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
}


int uv_process_kill(uv_process_t* process, int signum) {
static uv_err_t uv__kill(HANDLE process_handle, int signum) {
DWORD status;
uv_err_t err;

if (signum == SIGTERM || signum == SIGKILL) {
/* Kill the process. On Windows, killed processes normally return 1. */
if (TerminateProcess(process_handle, 1)) {
err = uv_ok_;
} else {
err = uv__new_sys_error(GetLastError());
}
} else if (signum == 0) {
/* Health check: is the process still alive? */
if (GetExitCodeProcess(process_handle, &status) &&
status == STILL_ACTIVE) {
err = uv_ok_;
} else {
err = uv__new_sys_error(GetLastError());
}
} else {
err.code = UV_ENOSYS;
}

return err;
}


int uv_process_kill(uv_process_t* process, int signum) {
uv_err_t err;

if (process->process_handle == INVALID_HANDLE_VALUE) {
uv__set_artificial_error(process->loop, UV_EINVAL);
return -1;
}

if (signum) {
/* Kill the process. On Windows, killed processes normally return 1. */
if (TerminateProcess(process->process_handle, 1)) {
process->exit_signal = signum;
return 0;
}
else {
uv__set_sys_error(process->loop, GetLastError());
return -1;
}
err = uv__kill(process->process_handle, signum);

if (err.code != UV_OK) {
uv__set_error(process->loop, err.code, err.sys_errno_);
return -1;
}
else {
/* Health check: is the process still alive? */
if (GetExitCodeProcess(process->process_handle, &status) && status == STILL_ACTIVE) {
return 0;
}
else {
uv__set_artificial_error(process->loop, UV_EINVAL);
return -1;
}

process->exit_signal = signum;

return 0;
}


uv_err_t uv_kill(int pid, int signum) {
uv_err_t err;
HANDLE process_handle = OpenProcess(PROCESS_TERMINATE |
PROCESS_QUERY_INFORMATION, FALSE, pid);

if (process_handle == INVALID_HANDLE_VALUE) {
return uv__new_sys_error(GetLastError());
}

assert(0 && "unreachable");
err = uv__kill(process_handle, signum);
CloseHandle(process_handle);

return err;
}
@@ -89,6 +89,7 @@ TEST_DECLARE (spawn_stdout)
TEST_DECLARE (spawn_stdin)
TEST_DECLARE (spawn_and_kill)
TEST_DECLARE (spawn_and_ping)
TEST_DECLARE (kill)
TEST_DECLARE (fs_file_noent)
TEST_DECLARE (fs_file_async)
TEST_DECLARE (fs_file_sync)
@@ -227,6 +228,7 @@ TASK_LIST_START
TEST_ENTRY (spawn_stdin)
TEST_ENTRY (spawn_and_kill)
TEST_ENTRY (spawn_and_ping)
TEST_ENTRY (kill)
#ifdef _WIN32
TEST_ENTRY (spawn_detect_pipe_name_collisions_on_windows)
TEST_ENTRY (argument_escaping)
@@ -33,6 +33,7 @@ static uv_process_options_t options;
static char exepath[1024];
static size_t exepath_size = 1024;
static char* args[3];
static int no_term_signal;

#define OUTPUT_SIZE 1024
static char output[OUTPUT_SIZE];
@@ -55,15 +56,23 @@ static void exit_cb(uv_process_t* process, int exit_status, int term_signal) {


static void kill_cb(uv_process_t* process, int exit_status, int term_signal) {
uv_err_t err;

printf("exit_cb\n");
exit_cb_called++;
#ifdef _WIN32
ASSERT(exit_status == 1);
#else
ASSERT(exit_status == 0);
#endif
ASSERT(term_signal == 15);
ASSERT(no_term_signal || term_signal == 15);
uv_close((uv_handle_t*)process, close_cb);

/* Sending signum == 0 should check if the
* child process is still alive, not kill it.
*/
err = uv_kill(process->pid, 0);
ASSERT(err.code != UV_OK);
}


@@ -261,6 +270,39 @@ TEST_IMPL(spawn_and_ping) {
}


TEST_IMPL(kill) {
int r;
uv_err_t err;

#ifdef _WIN32
no_term_signal = 1;
#endif

init_process_options("spawn_helper4", kill_cb);

r = uv_spawn(uv_default_loop(), &process, options);
ASSERT(r == 0);

/* Sending signum == 0 should check if the
* child process is still alive, not kill it.
*/
err = uv_kill(process.pid, 0);
ASSERT(err.code == UV_OK);

/* Kill the process. */
err = uv_kill(process.pid, /* SIGTERM */ 15);
ASSERT(err.code == UV_OK);

r = uv_run(uv_default_loop());
ASSERT(r == 0);

ASSERT(exit_cb_called == 1);
ASSERT(close_cb_called == 1);

return 0;
}


#ifdef _WIN32
TEST_IMPL(spawn_detect_pipe_name_collisions_on_windows) {
int r;

0 comments on commit 74b49e8

Please sign in to comment.
You can’t perform that action at this time.