[ruby-dev:13761] Re: mswin32/ming32 system patch (experimental)
From:
"U.Nakamura" <usa@...>
Date:
2001-07-06 18:49:39 UTC
List:
ruby-dev #13761
こんにちは、なかむら(う)です。
At Sat, 16 Jun 2001 23:13:49 +0900, nobu.nakada@nifty.ne.jp wrote in
'[ruby-dev:13604] Re: mswin32/ming32 system patch (experimental)'
> 一案としてこういうのは。[ruby-dev:13510]からの差分ですが、
> win32/win32.c だけです。process.c は #ifndef NT を抜いた以外は
> CVS HEAD と同じなので省略、win32/win32.h は CVS HEAD そのままで
> す。
だいぶ遅くなりましたが(すみません)、まとめ。
これをそのまま採用して、末尾のパッチのようになりました。
この先の拡張は、別途fork+execなメソッドの議論の後ですね。
# あるいは、fork(のように動くもの)を実装するか :-P
これでcommitしようと思ってますが、どうでしょう?
Index: process.c
===================================================================
RCS file: /src/ruby/process.c,v
retrieving revision 1.36
diff -u -2 -p -r1.36 process.c
--- process.c 2001/05/21 04:22:54 1.36
+++ process.c 2001/07/06 18:40:25
@@ -1328,5 +1328,4 @@ Init_process()
rb_define_singleton_method(rb_mProcess, "exit!", rb_f_exit_bang, -1);
rb_define_module_function(rb_mProcess, "kill", rb_f_kill, -1);
-#ifndef NT
rb_define_module_function(rb_mProcess, "wait", proc_wait, 0);
rb_define_module_function(rb_mProcess, "wait2", proc_wait2, 0);
@@ -1356,5 +1355,4 @@ Init_process()
rb_define_module_function(rb_mProcess, "pid", get_pid, 0);
rb_define_module_function(rb_mProcess, "ppid", get_ppid, 0);
-#endif /* ifndef NT */
rb_define_module_function(rb_mProcess, "getpgrp", proc_getpgrp, -1);
Index: win32/win32.c
===================================================================
RCS file: /src/ruby/win32/win32.c,v
retrieving revision 1.45
diff -u -2 -p -r1.45 win32.c
--- win32/win32.c 2001/05/12 06:47:24 1.45
+++ win32/win32.c 2001/07/06 18:40:25
@@ -73,4 +73,5 @@ extern char **environ;
#endif
+static struct ChildRecord *CreateChild(char *, SECURITY_ATTRIBUTES *, HANDLE, HANDLE, HANDLE);
static bool NtHasRedirection (char *);
static int valid_filename(char *s);
@@ -295,23 +296,73 @@ char *getlogin()
#if 1
-// popen stuff
+#define MAXCHILDNUM 256 /* max num of child processes */
-//
-// use these so I can remember which index is which
-//
+struct ChildRecord {
+ HANDLE hProcess; /* process handle */
+ pid_t pid; /* process id */
+ FILE* pipe; /* pipe */
+} ChildRecord[MAXCHILDNUM];
-#define NtPipeRead 0 // index of pipe read descriptor
-#define NtPipeWrite 1 // index of pipe write descriptor
+#define FOREACH_CHILD(v) do { \
+ struct ChildRecord* v; \
+ for (v = ChildRecord; v < ChildRecord + sizeof(ChildRecord) / sizeof(ChildRecord[0]); ++v)
+#define END_FOREACH_CHILD } while (0)
-#define NtPipeSize 1024 // size of pipe buffer
+static struct ChildRecord *
+FindFirstChildSlot(void)
+{
+ FOREACH_CHILD(child) {
+ if (child->pid) return child;
+ } END_FOREACH_CHILD;
+ return NULL;
+}
-#define MYPOPENSIZE 256 // size of book keeping structure
+static struct ChildRecord *
+FindChildSlot(pid_t pid)
+{
-struct {
- int inuse;
- int pid;
- FILE *pipe;
-} MyPopenRecord[MYPOPENSIZE];
+ FOREACH_CHILD(child) {
+ if (child->pid == pid) {
+ return child;
+ }
+ } END_FOREACH_CHILD;
+ return NULL;
+}
+static struct ChildRecord *
+FindPipedChildSlot(FILE *fp)
+{
+ FOREACH_CHILD(child) {
+ if (child->pid && child->pipe == fp) {
+ return child;
+ }
+ } END_FOREACH_CHILD;
+ return NULL;
+}
+
+static void
+CloseChildHandle(struct ChildRecord *child)
+{
+ HANDLE h = child->hProcess;
+ child->hProcess = NULL;
+ child->pid = 0;
+ CloseHandle(h);
+}
+
+static struct ChildRecord *
+FindFreeChildSlot(void)
+{
+ FOREACH_CHILD(child) {
+ if (!child->pid) {
+ child->pid = -1; /* lock the slot */
+ child->hProcess = NULL;
+ child->pipe = NULL;
+ return child;
+ }
+ } END_FOREACH_CHILD;
+ return NULL;
+}
+
+
int SafeFree(char **vec, int vecc)
{
@@ -397,32 +448,11 @@ mypopen (char *cmd, char *mode)
{
FILE *fp;
- int saved, reading;
+ int reading;
int pipemode;
- int pipes[2];
- int pid;
- int slot;
- static initialized = 0;
-
- //
- // if first time through, intialize our book keeping structure
- //
-
- if (!initialized++) {
- for (slot = 0; slot < MYPOPENSIZE; slot++)
- MyPopenRecord[slot].inuse = FALSE;
- }
-
- //printf("mypopen %s\n", cmd);
-
- //
- // find a free popen slot
- //
-
- for (slot = 0; slot < MYPOPENSIZE && MyPopenRecord[slot].inuse; slot++)
- ;
-
- if (slot > MYPOPENSIZE) {
- return NULL;
- }
+ struct ChildRecord* child;
+ BOOL fRet;
+ HANDLE hInFile, hOutFile;
+ SECURITY_ATTRIBUTES sa;
+ int fd;
//
@@ -436,297 +466,76 @@ mypopen (char *cmd, char *mode)
// Now get a pipe
//
-
-#if 0
- if (_pipe(pipes, NtPipeSize, pipemode) == -1) {
- return NULL;
+ sa.nLength = sizeof (SECURITY_ATTRIBUTES);
+ sa.lpSecurityDescriptor = NULL;
+ sa.bInheritHandle = TRUE;
+
+ fRet = CreatePipe(&hInFile, &hOutFile, &sa, 2048L);
+ if (!fRet) {
+ errno = GetLastError();
+ rb_sys_fail("mypopen: CreatePipe");
}
if (reading) {
-
- //
- // we\'re reading from the pipe, so we must hook up the
- // write end of the pipe to the new processes stdout.
- // To do this we must save our file handle from stdout
- // by _dup\'ing it, then setting our stdout to be the pipe\'s
- // write descriptor. We must also make the write handle
- // inheritable so the new process can use it.
-
- if ((saved = _dup(fileno(stdout))) == -1) {
- _close(pipes[NtPipeRead]);
- _close(pipes[NtPipeWrite]);
- return NULL;
- }
- if (_dup2 (pipes[NtPipeWrite], fileno(stdout)) == -1) {
- _close(pipes[NtPipeRead]);
- _close(pipes[NtPipeWrite]);
- return NULL;
- }
+ child = CreateChild(cmd, &sa, NULL, hOutFile, NULL);
}
else {
- //
- // must be writing to the new process. Do the opposite of
- // the above, i.e. hook up the processes stdin to the read
- // end of the pipe.
- //
-
- if ((saved = _dup(fileno(stdin))) == -1) {
- _close(pipes[NtPipeRead]);
- _close(pipes[NtPipeWrite]);
- return NULL;
- }
- if (_dup2(pipes[NtPipeRead], fileno(stdin)) == -1) {
- _close(pipes[NtPipeRead]);
- _close(pipes[NtPipeWrite]);
- return NULL;
- }
- }
-
- //
- // Start the new process. Must set _fileinfo to non-zero value
- // for file descriptors to be inherited. Reset after the process
- // is started.
- //
-
- if (NtHasRedirection(cmd)) {
- docmd:
- pid = spawnlpe(_P_NOWAIT, "cmd.exe", "/c", cmd, 0, environ);
- if (pid == -1) {
- _close(pipes[NtPipeRead]);
- _close(pipes[NtPipeWrite]);
- return NULL;
- }
+ child = CreateChild(cmd, &sa, hInFile, NULL, NULL);
}
- else {
- char **vec;
- int vecc = NtMakeCmdVector(cmd, &vec, FALSE);
- //pid = spawnvpe (_P_NOWAIT, vec[0], vec, environ);
- pid = spawnvpe (_P_WAIT, vec[0], vec, environ);
- if (pid == -1) {
- goto docmd;
- }
- Safefree (vec, vecc);
+ if (!child) {
+ CloseHandle(hInFile);
+ CloseHandle(hOutFile);
+ rb_sys_fail("mypopen: CreateChild");
}
if (reading) {
-
- //
- // We need to close our instance of the inherited pipe write
- // handle now that it's been inherited so that it will actually close
- // when the child process ends.
- //
-
- if (_close(pipes[NtPipeWrite]) == -1) {
- _close(pipes[NtPipeRead]);
- return NULL;
- }
- if (_dup2 (saved, fileno(stdout)) == -1) {
- _close(pipes[NtPipeRead]);
- return NULL;
- }
- _close(saved);
-
- //
- // Now get a stream pointer to return to the calling program.
- //
-
- if ((fp = (FILE *) fdopen(pipes[NtPipeRead], mode)) == NULL) {
- return NULL;
- }
+ fd = _open_osfhandle((long)hInFile, (_O_RDONLY | pipemode));
+ CloseHandle(hOutFile);
}
else {
-
- //
- // need to close our read end of the pipe so that it will go
- // away when the write end is closed.
- //
-
- if (_close(pipes[NtPipeRead]) == -1) {
- _close(pipes[NtPipeWrite]);
- return NULL;
- }
- if (_dup2 (saved, fileno(stdin)) == -1) {
- _close(pipes[NtPipeWrite]);
- return NULL;
- }
- _close(saved);
-
- //
- // Now get a stream pointer to return to the calling program.
- //
+ fd = _open_osfhandle((long)hOutFile, (_O_WRONLY | pipemode));
+ CloseHandle(hInFile);
+ }
- if ((fp = (FILE *) fdopen(pipes[NtPipeWrite], mode)) == NULL) {
- _close(pipes[NtPipeWrite]);
- return NULL;
- }
+ if (fd == -1) {
+ CloseHandle(reading ? hInFile : hOutFile);
+ CloseChildHandle(child);
+ rb_sys_fail("mypopen: _open_osfhandle");
}
- //
- // do the book keeping
- //
+ if ((fp = (FILE *) fdopen(fd, mode)) == NULL) {
+ _close(fd);
+ CloseChildHandle(child);
+ rb_sys_fail("mypopen: fdopen");
+ }
- MyPopenRecord[slot].inuse = TRUE;
- MyPopenRecord[slot].pipe = fp;
- MyPopenRecord[slot].pid = pid;
+ child->pipe = fp;
return fp;
-#else
- {
- int p[2];
-
- BOOL fRet;
- HANDLE hInFile, hOutFile;
- LPCSTR lpApplicationName = NULL;
- LPTSTR lpCommandLine;
- LPTSTR lpCmd2 = NULL;
- DWORD dwCreationFlags;
- STARTUPINFO aStartupInfo;
- PROCESS_INFORMATION aProcessInformation;
- SECURITY_ATTRIBUTES sa;
- int fd;
-
- sa.nLength = sizeof (SECURITY_ATTRIBUTES);
- sa.lpSecurityDescriptor = NULL;
- sa.bInheritHandle = TRUE;
-
- fRet = CreatePipe(&hInFile, &hOutFile, &sa, 2048L);
- if (!fRet) {
- errno = GetLastError();
- rb_sys_fail("mypopen: CreatePipe");
- }
-
- memset(&aStartupInfo, 0, sizeof (STARTUPINFO));
- memset(&aProcessInformation, 0, sizeof (PROCESS_INFORMATION));
- aStartupInfo.cb = sizeof (STARTUPINFO);
- aStartupInfo.dwFlags = STARTF_USESTDHANDLES;
-
- if (reading) {
- aStartupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
- aStartupInfo.hStdOutput = hOutFile;
- }
- else {
- aStartupInfo.hStdInput = hInFile;
- aStartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
- }
- aStartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
-
- dwCreationFlags = (NORMAL_PRIORITY_CLASS);
-
- lpCommandLine = cmd;
- if (NtHasRedirection(cmd) || isInternalCmd(cmd)) {
- lpApplicationName = getenv("COMSPEC");
- lpCmd2 = xmalloc(strlen(lpApplicationName) + 1 + strlen(cmd) + sizeof (" /c "));
- sprintf(lpCmd2, "%s %s%s", lpApplicationName, " /c ", cmd);
- lpCommandLine = lpCmd2;
- }
-
- fRet = CreateProcess(lpApplicationName, lpCommandLine, &sa, &sa,
- sa.bInheritHandle, dwCreationFlags, NULL, NULL, &aStartupInfo, &aProcessInformation);
- errno = GetLastError();
-
- if (lpCmd2)
- free(lpCmd2);
-
- if (!fRet) {
- CloseHandle(hInFile);
- CloseHandle(hOutFile);
- return NULL;
- }
-
- CloseHandle(aProcessInformation.hThread);
-
- if (reading) {
- fd = _open_osfhandle((long)hInFile, (_O_RDONLY | pipemode));
- CloseHandle(hOutFile);
- }
- else {
- fd = _open_osfhandle((long)hOutFile, (_O_WRONLY | pipemode));
- CloseHandle(hInFile);
- }
-
- if (fd == -1) {
- CloseHandle(reading ? hInFile : hOutFile);
- CloseHandle(aProcessInformation.hProcess);
- rb_sys_fail("mypopen: _open_osfhandle");
- }
-
- if ((fp = (FILE *) fdopen(fd, mode)) == NULL) {
- _close(fd);
- CloseHandle(aProcessInformation.hProcess);
- rb_sys_fail("mypopen: fdopen");
- }
-
- MyPopenRecord[slot].inuse = TRUE;
- MyPopenRecord[slot].pipe = fp;
- MyPopenRecord[slot].pid = (int)aProcessInformation.hProcess;
- return fp;
- }
-#endif
}
+extern VALUE rb_last_status;
+
int
mypclose(FILE *fp)
{
- int i;
- DWORD exitcode;
+ struct ChildRecord *child = FindPipedChildSlot(fp);
- Sleep(100);
- for (i = 0; i < MYPOPENSIZE; i++) {
- if (MyPopenRecord[i].inuse && MyPopenRecord[i].pipe == fp)
- break;
+ if (!child) {
+ rb_fatal("Invalid file pointer passed to mypclose!\n");
}
- if (i >= MYPOPENSIZE) {
- rb_fatal("Invalid file pointer passed to mypclose!\n");
- }
//
- // get the return status of the process
- //
-
-#if 0
- if (_cwait(&exitcode, MyPopenRecord[i].pid, WAIT_CHILD) == -1) {
- if (errno == ECHILD) {
- fprintf(stderr, "mypclose: nosuch child as pid %x\n",
- MyPopenRecord[i].pid);
- }
- }
-#else
- for (;;) {
- if (GetExitCodeProcess((HANDLE)MyPopenRecord[i].pid, &exitcode)) {
- if (exitcode == STILL_ACTIVE) {
- //printf("Process is Active.\n");
- Sleep(100);
- TerminateProcess((HANDLE)MyPopenRecord[i].pid, 0); // ugly...
- continue;
- }
- else if (exitcode == 0) {
- //printf("done.\n");
- break;
- }
- else {
- //printf("never.\n");
- break;
- }
- }
- }
- CloseHandle((HANDLE)MyPopenRecord[i].pid);
-#endif
-
- //
// close the pipe
//
-
+ child->pipe = NULL;
fflush(fp);
fclose(fp);
//
- // free this slot
+ // get the return status of the process
//
-
- MyPopenRecord[i].inuse = FALSE;
- MyPopenRecord[i].pipe = NULL;
- MyPopenRecord[i].pid = 0;
-
- return (int)((exitcode & 0xff) << 8);
+ rb_syswait(child->pid);
+ return NUM2INT(rb_last_status);
}
#endif
@@ -735,109 +544,103 @@ mypclose(FILE *fp)
-typedef char* CHARP;
-/*
- * The following code is based on the do_exec and do_aexec functions
- * in file doio.c
- */
-
int
do_spawn(cmd)
char *cmd;
{
- register char **a;
- register char *s;
- char **argv;
- int status = -1;
- char *shell, *cmd2;
- int mode = NtSyncProcess ? P_WAIT : P_NOWAIT;
- char quote;
- char *exec;
+ struct ChildRecord *child = CreateChild(cmd, NULL, NULL, NULL, NULL);
+ if (!child) {
+ rb_sys_fail("do_spawn: CreateChild");
+ }
+ rb_syswait(child->pid);
+ return NUM2INT(rb_last_status);
+}
+
+static struct ChildRecord *
+CreateChild(char *cmd, SECURITY_ATTRIBUTES *psa, HANDLE hInput, HANDLE hOutput, HANDLE hError)
+{
+ BOOL fRet;
+ DWORD dwCreationFlags;
+ STARTUPINFO aStartupInfo;
+ PROCESS_INFORMATION aProcessInformation;
+ SECURITY_ATTRIBUTES sa;
+ char *shell;
+ struct ChildRecord *child;
+
+ child = FindFreeChildSlot();
+ if (!child) {
+ errno = EAGAIN;
+ return NULL;
+ }
- /* save an extra exec if possible */
- if ((shell = getenv("RUBYSHELL")) != 0) {
- if (NtHasRedirection(cmd)) {
- int i;
- char *p;
- char *argv[4];
- char *cmdline = ALLOC_N(char, (strlen(cmd) * 2 + 1));
+ if (!psa) {
+ sa.nLength = sizeof (SECURITY_ATTRIBUTES);
+ sa.lpSecurityDescriptor = NULL;
+ sa.bInheritHandle = TRUE;
+ psa = &sa;
+ }
- p=cmdline;
- *p++ = '"';
- for (s=cmd; *s;) {
- if (*s == '"')
- *p++ = '\\'; /* Escape d-quote */
- *p++ = *s++;
- }
- *p++ = '"';
- *p = '\0';
+ memset(&aStartupInfo, 0, sizeof (STARTUPINFO));
+ memset(&aProcessInformation, 0, sizeof (PROCESS_INFORMATION));
+ aStartupInfo.cb = sizeof (STARTUPINFO);
+ aStartupInfo.dwFlags = STARTF_USESTDHANDLES;
+ if (hInput) {
+ aStartupInfo.hStdInput = hInput;
+ }
+ else {
+ aStartupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+ }
+ if (hOutput) {
+ aStartupInfo.hStdOutput = hOutput;
+ }
+ else {
+ aStartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+ }
+ if (hError) {
+ aStartupInfo.hStdError = hError;
+ }
+ else {
+ aStartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+ }
- /* fprintf(stderr, "do_spawn: %s %s\n", shell, cmdline); */
- argv[0] = shell;
- argv[1] = "-c";
- argv[2] = cmdline;
- argv[4] = NULL;
- status = spawnvpe(mode, argv[0], argv, environ);
- /* return spawnle(mode, shell, shell, "-c", cmd, (char*)0, environ); */
- free(cmdline);
- return (int)((status & 0xff) << 8);
- }
- }
- else if ((shell = getenv("COMSPEC")) != 0) {
- if (NtHasRedirection(cmd) /* || isInternalCmd(cmd) */) {
- status = spawnle(mode, shell, shell, "/c", cmd, (char*)0, environ);
- return (int)((status & 0xff) << 8);
- }
+ dwCreationFlags = (NORMAL_PRIORITY_CLASS);
+
+ if ((shell = getenv("RUBYSHELL")) && NtHasRedirection(cmd)) {
+ char *tmp = ALLOCA_N(char, strlen(shell) + strlen(cmd) + sizeof (" -c "));
+ sprintf(tmp, "%s -c %s", shell, cmd);
+ cmd = tmp;
+ }
+ else if ((shell = getenv("COMSPEC")) &&
+ (NtHasRedirection(cmd) || isInternalCmd(cmd))) {
+ char *tmp = ALLOCA_N(char, strlen(shell) + strlen(cmd) + sizeof (" /c "));
+ sprintf(tmp, "%s /c %s", shell, cmd);
+ cmd = tmp;
+ }
+ else {
+ shell = NULL;
}
- argv = ALLOC_N(CHARP, (strlen(cmd) / 2 + 2));
- cmd2 = ALLOC_N(char, (strlen(cmd) + 1));
- strcpy(cmd2, cmd);
- a = argv;
- for (s = cmd2; *s;) {
- while (*s && ISSPACE(*s)) s++;
- if (*s == '"') {
- quote = *s;
- *(a++) = s++;
- while (*s) {
- if (*s == '\\' && *(s + 1) == quote) {
- memmove(s, s + 1, strlen(s) + 1);
- s++;
- }
- else if (*s == quote) {
- s++;
- break;
- }
- s++;
- }
- }
- else if (*s) {
- *(a++) = s;
- while (*s && !ISSPACE(*s)) s++;
- }
- if (*s)
- *s++ = '\0';
- }
- *a = NULL;
- exec = NULL;
- if (argv[0]) {
- exec = ALLOC_N(char, (strlen(argv[0]) + 1));
- if (argv[0][0] == '"' && argv[0][strlen(argv[0]) - 1] == '"') {
- strcpy(exec, &argv[0][1]);
- exec[strlen(exec) - 1] = '\0';
- }
- else {
- strcpy(exec, argv[0]);
- }
- if ((status = spawnvpe(mode, exec, argv, environ)) == -1) {
- free(exec);
- free(argv);
- free(cmd2);
- return -1;
- }
+ RUBY_CRITICAL({
+ fRet = CreateProcess(shell, cmd, psa, psa,
+ psa->bInheritHandle, dwCreationFlags, NULL, NULL,
+ &aStartupInfo, &aProcessInformation);
+ errno = GetLastError();
+ });
+
+ if (!fRet) {
+ child->pid = 0; /* release the slot */
+ return NULL;
}
- free(exec);
- free(cmd2);
- free(argv);
- return (int)((status & 0xff) << 8);
+
+ CloseHandle(aProcessInformation.hThread);
+
+ child->hProcess = aProcessInformation.hProcess;
+ child->pid = (pid_t)aProcessInformation.dwProcessId;
+
+ if (!IsWinNT()) {
+ /* On Win9x, make pid positive similarly to cygwin and perl */
+ child->pid = -child->pid;
+ }
+
+ return child;
}
@@ -1061,4 +864,5 @@ NtHasRedirection (char *cmd)
case '>':
case '<':
+ case '|':
if (!inquote)
@@ -2467,5 +2271,19 @@ waitpid (pid_t pid, int *stat_loc, int o
{
DWORD timeout;
+ DWORD exitcode;
+ int ret;
+ struct ChildRecord* child;
+ if (pid == -1) {
+ child = FindFirstChildSlot();
+ }
+ else {
+ child = FindChildSlot(pid);
+ }
+ if (!child) {
+ errno = ECHILD;
+ return -1;
+ }
+
if (options == WNOHANG) {
timeout = 0;
@@ -2473,15 +2291,32 @@ waitpid (pid_t pid, int *stat_loc, int o
timeout = INFINITE;
}
- RUBY_CRITICAL({
- if (wait_events((HANDLE)pid, timeout) == WAIT_OBJECT_0) {
- pid = _cwait(stat_loc, pid, 0);
+
+ for (;;) {
+ if (!GetExitCodeProcess(child->hProcess, &exitcode)) {
+ /* If an error occured, return immediatly. */
+ errno = GetLastError();
+ if (errno == ERROR_INVALID_PARAMETER) {
+ errno = ECHILD;
+ }
+ CloseChildHandle(child);
+ pid = -1;
+ break;
}
- else {
+ else if (exitcode != STILL_ACTIVE) {
+ /* If already died, return immediatly. */
+ pid = child->pid;
+ CloseChildHandle(child);
+ if (stat_loc) *stat_loc = exitcode << 8;
+ break;
+ }
+
+ /* wait... */
+ if (wait_events(child->hProcess, timeout) != WAIT_OBJECT_0) {
+ /* still active */
pid = 0;
+ break;
}
- });
-#if !defined __BORLANDC__
- if (pid) *stat_loc <<= 8;
-#endif
+ }
+
return pid;
}
@@ -2491,5 +2326,5 @@ waitpid (pid_t pid, int *stat_loc, int o
int _cdecl
gettimeofday(struct timeval *tv, struct timezone *tz)
-{
+{
SYSTEMTIME st;
time_t t;
@@ -2557,30 +2392,48 @@ chown(const char *path, int owner, int g
#include <signal.h>
+#ifndef SIGINT
+#define SIGINT 2
+#endif
+#ifndef SIGKILL
+#define SIGKILL 9
+#endif
int
kill(int pid, int sig)
{
- if ((unsigned int)pid == GetCurrentProcessId())
+ if ((unsigned int)pid == GetCurrentProcessId() && sig != SIGKILL)
return raise(sig);
- if (sig == 2 && pid > 0) {
- if (!GenerateConsoleCtrlEvent(CTRL_C_EVENT, (DWORD)pid)) {
- errno = GetLastError();
- return -1;
- }
+ if (sig == SIGINT && pid > 0) {
+ RUBY_CRITICAL({
+ if (!GenerateConsoleCtrlEvent(CTRL_C_EVENT, (DWORD)pid)) {
+ errno = GetLastError();
+ return -1;
+ }
+ });
}
- else if (sig == 9 && pid > 0) {
+ else if (sig == SIGKILL && pid > 0) {
HANDLE hProc;
+ int ret = 0;
- hProc = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
- if (hProc == NULL || hProc == INVALID_HANDLE_VALUE) {
- errno = GetLastError();
- return -1;
- }
- if (!TerminateProcess(hProc, 0)) {
- errno = GetLastError();
+ RUBY_CRITICAL({
+ hProc = OpenProcess(PROCESS_TERMINATE, FALSE,
+ IsWin95() ? -pid : pid);
+ if (hProc == NULL || hProc == INVALID_HANDLE_VALUE) {
+ if (GetLastError() == ERROR_INVALID_PARAMETER) {
+ errno = ESRCH;
+ }
+ else {
+ errno = EPERM;
+ }
+ return -1;
+ }
+
+ if (!TerminateProcess(hProc, 0)) {
+ errno = EPERM;
+ ret = -1;
+ }
CloseHandle(hProc);
- return -1;
- }
- CloseHandle(hProc);
+ });
+ return ret;
}
else {
それでは。
--
U.Nakamura <usa@osb.att.ne.jp>