/*++ Copyright (c) 1989 Microsoft Corporation Module Name: dllsig.c Abstract: Posix Signal Handling RTL Author: Mark Lucovsky (markl) 10-Mar-1989 Revision History: --*/ #include "psxdll.h" #include #define _SIGNULLSET 0x0 #define _SIGFULLSET 0x7ffff // ((1< SIGTTOU) { errno = EINVAL; return -1; } SignoAsMask = (ULONG)(1l << (ULONG)(signo-1) ); try { *set |= SignoAsMask; } except (EXCEPTION_EXECUTE_HANDLER) { errno = EFAULT; r = -1; } return r; } int __cdecl sigdelset(sigset_t *set, int signo) { sigset_t SignoAsMask; int r = 0; if (signo < 1 || signo > SIGTTOU) { errno = EINVAL; return -1; } SignoAsMask = (ULONG)(1l << (ULONG)(signo-1) ); try { *set &= ~SignoAsMask; } except (EXCEPTION_EXECUTE_HANDLER) { errno = EFAULT; r = -1; } return r; } int __cdecl sigismember(const sigset_t *set, int signo) { sigset_t SignoAsMask; int r = 0; if (signo < 1 || signo > SIGTTOU) { errno = EINVAL; return -1; } SignoAsMask = (ULONG)(1L << (ULONG)(signo-1)); try { if (*set & SignoAsMask) { return 1; } } except (EXCEPTION_EXECUTE_HANDLER) { errno = EFAULT; r = -1; } return r; } // // System Services // int __cdecl sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { PSX_API_MSG m; NTSTATUS st; int r = 0; PPSX_SIGACTION_MSG args; args = &m.u.SigAction; PSX_FORMAT_API_MSG(m, PsxSigActionApi, sizeof(*args)); args->Sig = (ULONG)sig; args->ActSpecified = (struct sigaction *)act; if (ARGUMENT_PRESENT(act)) { try { args->Act = *act; } except (EXCEPTION_EXECUTE_HANDLER) { KdPrint(("PSXDLL: err in sigaction\n")); errno = EFAULT; r = -1; } if (r != 0) { return r; } } args->OactSpecified = oact; st = NtRequestWaitReplyPort(PsxPortHandle, (PPORT_MESSAGE)&m, (PPORT_MESSAGE)&m); if (!NT_SUCCESS(st)) { #ifdef PSX_MORE_ERRORS KdPrint(("PSXDLL: sigaction: NtRequestWaitReplyPort: 0x%x\n", st)); #endif _exit(25); } if (m.Error) { errno = (int)m.Error; return -1; } else { if (ARGUMENT_PRESENT(oact)) { try { *oact = args->Oact; } except (EXCEPTION_EXECUTE_HANDLER) { errno = EFAULT; r = -1; } if (r != 0) { return r; } } return (int)m.ReturnValue; } } int __cdecl sigprocmask(int how, const sigset_t *set, sigset_t *oset) { PSX_API_MSG m; NTSTATUS st; int r = 0; PPSX_SIGPROCMASK_MSG args; args = &m.u.SigProcMask; PSX_FORMAT_API_MSG(m, PsxSigProcMaskApi, sizeof(*args)); args->How = (ULONG)how; args->SetSpecified = (sigset_t *)set; if (ARGUMENT_PRESENT(set)) { try { args->Set = *set; } except (EXCEPTION_EXECUTE_HANDLER) { r = -1; errno = EFAULT; } if (0 != r) { return r; } } st = NtRequestWaitReplyPort(PsxPortHandle, (PPORT_MESSAGE)&m, (PPORT_MESSAGE)&m); #ifdef PSX_MORE_ERRORS ASSERT(NT_SUCCESS(st)); #endif if (m.Error) { errno = (int)m.Error; return -1; } else { if (ARGUMENT_PRESENT(oset)) { try { *oset = args->Oset; } except (EXCEPTION_EXECUTE_HANDLER) { errno = EFAULT; r = -1; } if (0 != r) { return r; } } return (int)m.ReturnValue; } } int __cdecl sigsuspend(const sigset_t *sigmask) { PSX_API_MSG m; NTSTATUS st; PPSX_SIGSUSPEND_MSG args; args = &m.u.SigSuspend; PSX_FORMAT_API_MSG(m, PsxSigSuspendApi, sizeof(*args)); args->SigMaskSpecified = (PVOID)1; st = STATUS_SUCCESS; try { args->SigMask = *sigmask; } except (EXCEPTION_EXECUTE_HANDLER) { st = STATUS_UNSUCCESSFUL; } if (!NT_SUCCESS(st)) { errno = EFAULT; return -1; } for (;;) { st = NtRequestWaitReplyPort(PsxPortHandle, (PPORT_MESSAGE)&m, (PPORT_MESSAGE)&m); if (!NT_SUCCESS(st)) { _exit(26); } if (EINTR == m.Error && SIGCONT == m.Signal) { // // We were stopped and continued. Continue // suspending. // PSX_FORMAT_API_MSG(m, PsxSigSuspendApi, sizeof(*args)); continue; } if (m.Error) { errno = (int)m.Error; return -1; } return (int)m.ReturnValue; } } int __cdecl pause(void) { PSX_API_MSG m; NTSTATUS st; PPSX_SIGSUSPEND_MSG args; args = &m.u.SigSuspend; PSX_FORMAT_API_MSG(m, PsxSigSuspendApi, sizeof(*args)); args->SigMaskSpecified = NULL; for (;;) { st = NtRequestWaitReplyPort(PsxPortHandle, (PPORT_MESSAGE)&m, (PPORT_MESSAGE)&m); if (!NT_SUCCESS(st)) { #ifdef PSX_MORE_ERRORS KdPrint(("PSXDLL: pause: Request: 0x%x\n", st)); #endif _exit(27); } if (EINTR == m.Error && SIGCONT == m.Signal) { // // The syscall was stopped and continues. Call // again instead of returning EINTR. // PSX_FORMAT_API_MSG(m, PsxSigSuspendApi, sizeof(*args)); continue; } if (m.Error) { errno = (int)m.Error; return -1; } return (int)m.ReturnValue; } } VOID PdxNullPosixApi() { PSX_API_MSG m; NTSTATUS st; PSX_FORMAT_API_MSG(m, PsxNullApi, 0); st = NtRequestWaitReplyPort(PsxPortHandle, (PPORT_MESSAGE)&m, (PPORT_MESSAGE)&m); #ifdef PSX_MORE_ERRORS if (!NT_SUCCESS(st)) { KdPrint(("PSXDLL: PdxNullPosixApi: NtRequestWaitReplyPort: 0x%x\n", st)); } #endif } int __cdecl kill(pid_t pid, int sig) { PSX_API_MSG m; NTSTATUS st; PPSX_KILL_MSG args; args = &m.u.Kill; PSX_FORMAT_API_MSG(m, PsxKillApi, sizeof(*args)); args->Pid = pid; args->Sig = (ULONG)sig; st = NtRequestWaitReplyPort(PsxPortHandle, (PPORT_MESSAGE)&m, (PPORT_MESSAGE)&m); if (!NT_SUCCESS(st)) { #ifdef PSX_MORE_ERRORS KdPrint(("PSXDLL: kill: NtRequestWaitReplyPort: 0x%x\n", st)); #endif _exit(28); } if (m.Error) { errno = (int)m.Error; return -1; } else { return (int)m.ReturnValue; } } #ifndef SIG_ERR #define SIG_ERR 0 #endif _handler __cdecl signal(int sig, _handler handler) { struct sigaction act, oact; act.sa_handler = handler; act.sa_flags = 0; sigemptyset((sigset_t *)&act.sa_mask); if (-1 == sigaction(sig, (struct sigaction *)&act, (struct sigaction *)&oact)) { return SIG_ERR; } return oact.sa_handler; } int __cdecl sigpending(sigset_t *set) { PSX_API_MSG m; PPSX_SIGPENDING_MSG args; NTSTATUS st; int r = 0; args = &m.u.SigPending; PSX_FORMAT_API_MSG(m, PsxSigPendingApi, sizeof(*args)); st = NtRequestWaitReplyPort(PsxPortHandle, (PPORT_MESSAGE)&m, (PPORT_MESSAGE)&m); #ifdef PSX_MORE_ERRORS ASSERT(NT_SUCCESS(st)); #endif if (m.Error) { errno = (int)m.Error; return -1; } try { *set = args->Set; } except (EXCEPTION_EXECUTE_HANDLER) { errno = EFAULT; r = -1; } return r; }