Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support windows. #1

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion mrbgem.rake
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
MRuby::Gem::Specification.new('mruby-process') do |spec|
MRuby::Gem::Specification.new('mruby-process-win32') do |spec|
# based on https://github.com/iij/mruby-process
spec.license = 'MIT'
spec.authors = 'mruby developers'

Expand Down
85 changes: 82 additions & 3 deletions src/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,69 @@
#include "error.h"

#include <sys/types.h>
#ifndef _WIN32
#include <sys/time.h>
#include <sys/wait.h>
#include <sys/select.h>
#else
#include <windows.h>
#endif
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#ifndef _MSC_VER
#include <unistd.h>
#endif
#include <errno.h>

#ifdef _WIN32
static const char*
emsg(DWORD err)
{
static char buf[256];
if (err == 0) return "succeeded";
FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
err,
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
buf,
sizeof buf,
NULL);
return buf;
}

#ifndef SIGKILL
#define SIGKILL 9
#endif

int
kill(int pid, int sig)
{
HANDLE handle;
switch (sig) {
case SIGTERM:
case SIGKILL:
case SIGINT:
handle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
if (!TerminateProcess(handle, 1))
return -1;
default:
return -1;
}
return 0;
}

unsigned int
sleep(unsigned int seconds)
{
Sleep(seconds * 1000);
return seconds;
}

#endif

mrb_value
mrb_f_kill(mrb_state *mrb, mrb_value klass)
{
Expand Down Expand Up @@ -59,6 +112,7 @@ mrb_f_kill(mrb_state *mrb, mrb_value klass)
static mrb_value
mrb_f_fork(mrb_state *mrb, mrb_value klass)
{
#ifndef _WIN32
mrb_value b, result;
int pid;

Expand All @@ -79,13 +133,18 @@ mrb_f_fork(mrb_state *mrb, mrb_value klass)
default:
return mrb_fixnum_value(pid);
}
#else
mrb_raise(mrb, E_RUNTIME_ERROR, emsg(ERROR_CALL_NOT_IMPLEMENTED));
return mrb_nil_value();
#endif
}

static int
mrb_waitpid(int pid, int flags, int *st)
{
int result;

#ifndef _WIN32
retry:
result = waitpid(pid, st, flags);
if (result < 0) {
Expand All @@ -94,6 +153,10 @@ mrb_waitpid(int pid, int flags, int *st)
}
return -1;
}
#else
HANDLE handle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
result = WaitForSingleObject(handle, INFINITE) == WAIT_OBJECT_0 ? 0 : -1;
#endif

return result;
}
Expand Down Expand Up @@ -135,8 +198,12 @@ mrb_f_sleep(mrb_state *mrb, mrb_value klass)
tv.tv_usec = (mrb_float(argv[0]) - tv.tv_sec) * 1000000.0;
}


#ifdef _WIN32
n = tv.tv_sec * 1000 + tv.tv_usec / 1000;
Sleep(n);
#else
n = select(0, 0, 0, 0, &tv);
#endif
if (n < 0)
mrb_sys_fail(mrb, "mrb_f_sleep failed");
} else {
Expand All @@ -157,7 +224,9 @@ mrb_f_system(mrb_state *mrb, mrb_value klass)
mrb_value *argv, pname;
const char *path;
int argc;
#ifdef SIGCHLD
RETSIGTYPE (*chfunc)(int);
#endif

fflush(stdout);
fflush(stderr);
Expand All @@ -174,9 +243,14 @@ mrb_f_system(mrb_state *mrb, mrb_value klass)
path = mrb_string_value_cstr(mrb, &pname);
ret = system(path);

#ifndef _WIN32
if (WIFEXITED(ret) && WEXITSTATUS(ret) == 0) {
return mrb_true_value();
}
#else
if (ret != -1)
return mrb_true_value();
#endif

return mrb_false_value();
}
Expand Down Expand Up @@ -210,11 +284,16 @@ mrb_f_pid(mrb_state *mrb, mrb_value klass)
mrb_value
mrb_f_ppid(mrb_state *mrb, mrb_value klass)
{
#ifndef _WIN32
return mrb_fixnum_value((mrb_int)getppid());
#else
mrb_raise(mrb, E_RUNTIME_ERROR, emsg(ERROR_CALL_NOT_IMPLEMENTED));
return mrb_nil_value();
#endif
}

void
mrb_mruby_process_gem_init(mrb_state *mrb)
mrb_mruby_process_win32_gem_init(mrb_state *mrb)
{
struct RClass *p;

Expand All @@ -233,6 +312,6 @@ mrb_mruby_process_gem_init(mrb_state *mrb)
}

void
mrb_mruby_process_gem_final(mrb_state *mrb)
mrb_mruby_process_win32_gem_final(mrb_state *mrb)
{
}