Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

438 lines
7.4 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. dllsig.c
  5. Abstract:
  6. Posix Signal Handling RTL
  7. Author:
  8. Mark Lucovsky (markl) 10-Mar-1989
  9. Revision History:
  10. --*/
  11. #include "psxdll.h"
  12. #include <excpt.h>
  13. #define _SIGNULLSET 0x0
  14. #define _SIGFULLSET 0x7ffff // ((1<<SIGTTOU) - 1)
  15. int
  16. __cdecl
  17. sigemptyset(sigset_t *set)
  18. {
  19. int r = 0;
  20. try {
  21. *set = _SIGNULLSET;
  22. } except (EXCEPTION_EXECUTE_HANDLER) {
  23. KdPrint(("PSXDLL: error in sigemptyset\n"));
  24. KdPrint(("PSXDLL: set is 0x%x\n", set));
  25. KdPrint(("PSXDLL: exception code 0x%x\n", GetExceptionCode()));
  26. }
  27. return r;
  28. }
  29. int
  30. __cdecl
  31. sigfillset(sigset_t *set)
  32. {
  33. int r = 0;
  34. try {
  35. *set = _SIGFULLSET;
  36. } except (EXCEPTION_EXECUTE_HANDLER) {
  37. errno = EFAULT;
  38. r = -1;
  39. }
  40. return r;
  41. }
  42. int __cdecl
  43. sigaddset(sigset_t *set, int signo)
  44. {
  45. sigset_t SignoAsMask;
  46. int r = 0;
  47. if (signo < 1 || signo > SIGTTOU) {
  48. errno = EINVAL;
  49. return -1;
  50. }
  51. SignoAsMask = (ULONG)(1l << (ULONG)(signo-1) );
  52. try {
  53. *set |= SignoAsMask;
  54. } except (EXCEPTION_EXECUTE_HANDLER) {
  55. errno = EFAULT;
  56. r = -1;
  57. }
  58. return r;
  59. }
  60. int __cdecl
  61. sigdelset(sigset_t *set, int signo)
  62. {
  63. sigset_t SignoAsMask;
  64. int r = 0;
  65. if (signo < 1 || signo > SIGTTOU) {
  66. errno = EINVAL;
  67. return -1;
  68. }
  69. SignoAsMask = (ULONG)(1l << (ULONG)(signo-1) );
  70. try {
  71. *set &= ~SignoAsMask;
  72. } except (EXCEPTION_EXECUTE_HANDLER) {
  73. errno = EFAULT;
  74. r = -1;
  75. }
  76. return r;
  77. }
  78. int __cdecl
  79. sigismember(const sigset_t *set, int signo)
  80. {
  81. sigset_t SignoAsMask;
  82. int r = 0;
  83. if (signo < 1 || signo > SIGTTOU) {
  84. errno = EINVAL;
  85. return -1;
  86. }
  87. SignoAsMask = (ULONG)(1L << (ULONG)(signo-1));
  88. try {
  89. if (*set & SignoAsMask) {
  90. return 1;
  91. }
  92. } except (EXCEPTION_EXECUTE_HANDLER) {
  93. errno = EFAULT;
  94. r = -1;
  95. }
  96. return r;
  97. }
  98. //
  99. // System Services
  100. //
  101. int
  102. __cdecl
  103. sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
  104. {
  105. PSX_API_MSG m;
  106. NTSTATUS st;
  107. int r = 0;
  108. PPSX_SIGACTION_MSG args;
  109. args = &m.u.SigAction;
  110. PSX_FORMAT_API_MSG(m, PsxSigActionApi, sizeof(*args));
  111. args->Sig = (ULONG)sig;
  112. args->ActSpecified = (struct sigaction *)act;
  113. if (ARGUMENT_PRESENT(act)) {
  114. try {
  115. args->Act = *act;
  116. } except (EXCEPTION_EXECUTE_HANDLER) {
  117. KdPrint(("PSXDLL: err in sigaction\n"));
  118. errno = EFAULT;
  119. r = -1;
  120. }
  121. if (r != 0) {
  122. return r;
  123. }
  124. }
  125. args->OactSpecified = oact;
  126. st = NtRequestWaitReplyPort(PsxPortHandle, (PPORT_MESSAGE)&m,
  127. (PPORT_MESSAGE)&m);
  128. if (!NT_SUCCESS(st)) {
  129. #ifdef PSX_MORE_ERRORS
  130. KdPrint(("PSXDLL: sigaction: NtRequestWaitReplyPort: 0x%x\n", st));
  131. #endif
  132. _exit(25);
  133. }
  134. if (m.Error) {
  135. errno = (int)m.Error;
  136. return -1;
  137. } else {
  138. if (ARGUMENT_PRESENT(oact)) {
  139. try {
  140. *oact = args->Oact;
  141. } except (EXCEPTION_EXECUTE_HANDLER) {
  142. errno = EFAULT;
  143. r = -1;
  144. }
  145. if (r != 0) {
  146. return r;
  147. }
  148. }
  149. return (int)m.ReturnValue;
  150. }
  151. }
  152. int
  153. __cdecl
  154. sigprocmask(int how, const sigset_t *set, sigset_t *oset)
  155. {
  156. PSX_API_MSG m;
  157. NTSTATUS st;
  158. int r = 0;
  159. PPSX_SIGPROCMASK_MSG args;
  160. args = &m.u.SigProcMask;
  161. PSX_FORMAT_API_MSG(m, PsxSigProcMaskApi, sizeof(*args));
  162. args->How = (ULONG)how;
  163. args->SetSpecified = (sigset_t *)set;
  164. if (ARGUMENT_PRESENT(set)) {
  165. try {
  166. args->Set = *set;
  167. } except (EXCEPTION_EXECUTE_HANDLER) {
  168. r = -1;
  169. errno = EFAULT;
  170. }
  171. if (0 != r) {
  172. return r;
  173. }
  174. }
  175. st = NtRequestWaitReplyPort(PsxPortHandle, (PPORT_MESSAGE)&m,
  176. (PPORT_MESSAGE)&m);
  177. #ifdef PSX_MORE_ERRORS
  178. ASSERT(NT_SUCCESS(st));
  179. #endif
  180. if (m.Error) {
  181. errno = (int)m.Error;
  182. return -1;
  183. } else {
  184. if (ARGUMENT_PRESENT(oset)) {
  185. try {
  186. *oset = args->Oset;
  187. } except (EXCEPTION_EXECUTE_HANDLER) {
  188. errno = EFAULT;
  189. r = -1;
  190. }
  191. if (0 != r) {
  192. return r;
  193. }
  194. }
  195. return (int)m.ReturnValue;
  196. }
  197. }
  198. int
  199. __cdecl
  200. sigsuspend(const sigset_t *sigmask)
  201. {
  202. PSX_API_MSG m;
  203. NTSTATUS st;
  204. PPSX_SIGSUSPEND_MSG args;
  205. args = &m.u.SigSuspend;
  206. PSX_FORMAT_API_MSG(m, PsxSigSuspendApi, sizeof(*args));
  207. args->SigMaskSpecified = (PVOID)1;
  208. st = STATUS_SUCCESS;
  209. try {
  210. args->SigMask = *sigmask;
  211. } except (EXCEPTION_EXECUTE_HANDLER) {
  212. st = STATUS_UNSUCCESSFUL;
  213. }
  214. if (!NT_SUCCESS(st)) {
  215. errno = EFAULT;
  216. return -1;
  217. }
  218. for (;;) {
  219. st = NtRequestWaitReplyPort(PsxPortHandle, (PPORT_MESSAGE)&m,
  220. (PPORT_MESSAGE)&m);
  221. if (!NT_SUCCESS(st)) {
  222. _exit(26);
  223. }
  224. if (EINTR == m.Error && SIGCONT == m.Signal) {
  225. //
  226. // We were stopped and continued. Continue
  227. // suspending.
  228. //
  229. PSX_FORMAT_API_MSG(m, PsxSigSuspendApi, sizeof(*args));
  230. continue;
  231. }
  232. if (m.Error) {
  233. errno = (int)m.Error;
  234. return -1;
  235. }
  236. return (int)m.ReturnValue;
  237. }
  238. }
  239. int
  240. __cdecl
  241. pause(void)
  242. {
  243. PSX_API_MSG m;
  244. NTSTATUS st;
  245. PPSX_SIGSUSPEND_MSG args;
  246. args = &m.u.SigSuspend;
  247. PSX_FORMAT_API_MSG(m, PsxSigSuspendApi, sizeof(*args));
  248. args->SigMaskSpecified = NULL;
  249. for (;;) {
  250. st = NtRequestWaitReplyPort(PsxPortHandle, (PPORT_MESSAGE)&m,
  251. (PPORT_MESSAGE)&m);
  252. if (!NT_SUCCESS(st)) {
  253. #ifdef PSX_MORE_ERRORS
  254. KdPrint(("PSXDLL: pause: Request: 0x%x\n", st));
  255. #endif
  256. _exit(27);
  257. }
  258. if (EINTR == m.Error && SIGCONT == m.Signal) {
  259. //
  260. // The syscall was stopped and continues. Call
  261. // again instead of returning EINTR.
  262. //
  263. PSX_FORMAT_API_MSG(m, PsxSigSuspendApi, sizeof(*args));
  264. continue;
  265. }
  266. if (m.Error) {
  267. errno = (int)m.Error;
  268. return -1;
  269. }
  270. return (int)m.ReturnValue;
  271. }
  272. }
  273. VOID
  274. PdxNullPosixApi()
  275. {
  276. PSX_API_MSG m;
  277. NTSTATUS st;
  278. PSX_FORMAT_API_MSG(m, PsxNullApi, 0);
  279. st = NtRequestWaitReplyPort(PsxPortHandle, (PPORT_MESSAGE)&m,
  280. (PPORT_MESSAGE)&m);
  281. #ifdef PSX_MORE_ERRORS
  282. if (!NT_SUCCESS(st)) {
  283. KdPrint(("PSXDLL: PdxNullPosixApi: NtRequestWaitReplyPort: 0x%x\n", st));
  284. }
  285. #endif
  286. }
  287. int
  288. __cdecl
  289. kill(pid_t pid, int sig)
  290. {
  291. PSX_API_MSG m;
  292. NTSTATUS st;
  293. PPSX_KILL_MSG args;
  294. args = &m.u.Kill;
  295. PSX_FORMAT_API_MSG(m, PsxKillApi, sizeof(*args));
  296. args->Pid = pid;
  297. args->Sig = (ULONG)sig;
  298. st = NtRequestWaitReplyPort(PsxPortHandle, (PPORT_MESSAGE)&m,
  299. (PPORT_MESSAGE)&m);
  300. if (!NT_SUCCESS(st)) {
  301. #ifdef PSX_MORE_ERRORS
  302. KdPrint(("PSXDLL: kill: NtRequestWaitReplyPort: 0x%x\n", st));
  303. #endif
  304. _exit(28);
  305. }
  306. if (m.Error) {
  307. errno = (int)m.Error;
  308. return -1;
  309. } else {
  310. return (int)m.ReturnValue;
  311. }
  312. }
  313. #ifndef SIG_ERR
  314. #define SIG_ERR 0
  315. #endif
  316. _handler __cdecl
  317. signal(int sig, _handler handler)
  318. {
  319. struct sigaction act, oact;
  320. act.sa_handler = handler;
  321. act.sa_flags = 0;
  322. sigemptyset((sigset_t *)&act.sa_mask);
  323. if (-1 == sigaction(sig, (struct sigaction *)&act,
  324. (struct sigaction *)&oact)) {
  325. return SIG_ERR;
  326. }
  327. return oact.sa_handler;
  328. }
  329. int
  330. __cdecl
  331. sigpending(sigset_t *set)
  332. {
  333. PSX_API_MSG m;
  334. PPSX_SIGPENDING_MSG args;
  335. NTSTATUS st;
  336. int r = 0;
  337. args = &m.u.SigPending;
  338. PSX_FORMAT_API_MSG(m, PsxSigPendingApi, sizeof(*args));
  339. st = NtRequestWaitReplyPort(PsxPortHandle, (PPORT_MESSAGE)&m,
  340. (PPORT_MESSAGE)&m);
  341. #ifdef PSX_MORE_ERRORS
  342. ASSERT(NT_SUCCESS(st));
  343. #endif
  344. if (m.Error) {
  345. errno = (int)m.Error;
  346. return -1;
  347. }
  348. try {
  349. *set = args->Set;
  350. } except (EXCEPTION_EXECUTE_HANDLER) {
  351. errno = EFAULT;
  352. r = -1;
  353. }
  354. return r;
  355. }