/* kill.c (rsxnt) -- Copyright (c) 1996-1997 Rainer Schnitker */

#include "rsxnt.h"

int __kill(int pid, int signo)
{
    EMXPROCESS *proc = _rsxnt_get_process_ptr();

    if (signo < 0 || signo >= NSIG)
        return _rsxnt_errno(EINVAL);

    if (!signo)
        return (proc->pid == pid) ? 0 : -1;

    if (pid < 0)
        pid = -pid;

    if (pid == proc->pid) {
        _rsxnt_send_signal(proc, signo);

#ifdef EMX_SYS_LIB
        _rsxnt_check_signals();
#endif
        return 0;
    } else if (pid == proc->debuggee.pid && signo == SIGKILL) {
        CONTEXT Context;
        FARPROC FarProc = GetProcAddress(
                GetModuleHandle("kernel32.dll"), "ExitProcess");
        int retv;

        /* set EIP to ExitProcess() */

        Context.ContextFlags = CONTEXT_CONTROL;
        GetThreadContext(proc->debuggee.hCurrentThread, &Context);
        Context.Eip = (DWORD) FarProc;
        Context.ContextFlags = CONTEXT_CONTROL;
        SetThreadContext(proc->debuggee.hCurrentThread, &Context);
        _rsxnt_do_ptrace(PTRACE_RESUME, pid, 0, 0, &retv);
        return retv;
    }
    else if (signo == SIGKILL) {
        int i;
        for (i = 0; i < MAX_CHILD; ++i)
            if (proc->childs[i].pid == pid)
                if (TerminateProcess(proc->childs[i].hProcess, 3) == FALSE)
                    return _rsxnt_errno(EACCES);
                else
                    return 0;
        return _rsxnt_errno(EINVAL);
    }
    else
        return _rsxnt_errno(EINVAL);
}
