Skip to content
This repository has been archived by the owner on May 4, 2018. It is now read-only.

Commit

Permalink
uv_kill
Browse files Browse the repository at this point in the history
  • Loading branch information
Igor Zinkovsky committed Nov 2, 2011
1 parent 8d5c64a commit 31f94db
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 22 deletions.
4 changes: 4 additions & 0 deletions include/uv.h
Expand Up @@ -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
*/
Expand Down
11 changes: 11 additions & 0 deletions src/unix/process.c
Expand Up @@ -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_;

This comment has been minimized.

Copy link
@ry

ry Nov 2, 2011

Contributor

uv_ok_ is defined in src/win/error.c and src/unix/dl.c. Probably It should be moved to src/common.c and an extern added to common.h?

This comment has been minimized.

Copy link
@piscisaureus

piscisaureus Nov 2, 2011

I agree.

}
}
75 changes: 54 additions & 21 deletions src/win/process.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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)) {
return uv_ok_;
} else {
return uv__new_sys_error(GetLastError());
}
} else if (signum == 0) {
/* Health check: is the process still alive? */
if (GetExitCodeProcess(process_handle, &status) &&
status == STILL_ACTIVE) {
return uv_ok_;
} else {
err.code = UV_EINVAL;

This comment has been minimized.

Copy link
@piscisaureus

piscisaureus Nov 2, 2011

Same as the other comment - there could be other error conditions than EINVAL.

return err;
}
}

This comment has been minimized.

Copy link
@piscisaureus

piscisaureus Nov 2, 2011

Do not ignore other signals, return some error (UV_ENOSYS I think?)


return uv_ok_;
}


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) {
err.code = UV_EINVAL;

This comment has been minimized.

Copy link
@piscisaureus

piscisaureus Nov 2, 2011

Why would always return EINVAL? I assume there may be other reasons a pid can't be opened (e.g. security).

return err;
}

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

return err;
}
2 changes: 2 additions & 0 deletions test/test-list.h
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
44 changes: 43 additions & 1 deletion test/test-spawn.c
Expand Up @@ -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];
Expand All @@ -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_EINVAL);
}


Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 31f94db

Please sign in to comment.