1
0

signals.c 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025
  1. /*++
  2. Copyright (c) 2013 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. signals.c
  9. Abstract:
  10. This module implements signal handling functionality for the C library.
  11. Author:
  12. Evan Green 28-Mar-2013
  13. Environment:
  14. User Mode C Library
  15. --*/
  16. //
  17. // ------------------------------------------------------------------- Includes
  18. //
  19. #include "libcp.h"
  20. #include <assert.h>
  21. #include <errno.h>
  22. #include <signal.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <sys/wait.h>
  26. #include <unistd.h>
  27. //
  28. // --------------------------------------------------------------------- Macros
  29. //
  30. //
  31. // This macro asserts that the C library wait flags are equivalent to the
  32. // kernel wait flags.
  33. //
  34. #define ASSERT_WAIT_FLAGS_EQUIVALENT() \
  35. ASSERT((WNOHANG == SYSTEM_CALL_WAIT_FLAG_RETURN_IMMEDIATELY) && \
  36. (WUNTRACED == SYSTEM_CALL_WAIT_FLAG_STOPPED_CHILDREN) && \
  37. (WCONTINUED == SYSTEM_CALL_WAIT_FLAG_CONTINUED_CHILDREN) && \
  38. (WEXITED == SYSTEM_CALL_WAIT_FLAG_EXITED_CHILDREN) && \
  39. (WNOWAIT == SYSTEM_CALL_WAIT_FLAG_DONT_DISCARD_CHILD))
  40. //
  41. // ---------------------------------------------------------------- Definitions
  42. //
  43. //
  44. // Define the required size of the signal description buffer.
  45. //
  46. #define SIGNAL_DESCRIPTION_BUFFER_SIZE 64
  47. //
  48. // ------------------------------------------------------ Data Type Definitions
  49. //
  50. //
  51. // ----------------------------------------------- Internal Function Prototypes
  52. //
  53. BOOL
  54. ClpHandleSignal (
  55. PSIGNAL_PARAMETERS SignalInformation,
  56. PSIGNAL_CONTEXT Context
  57. );
  58. int
  59. ClpConvertToWaitStatus (
  60. USHORT Reason,
  61. UINTN Value
  62. );
  63. //
  64. // -------------------------------------------------------------------- Globals
  65. //
  66. //
  67. // Define an array of strings, indexed up to NSIG, that contain descriptions of
  68. // the strings.
  69. //
  70. LIBC_API const char *sys_siglist[NSIG] = {
  71. NULL,
  72. "Hangup",
  73. "Interrupt",
  74. "Quit",
  75. "Illegal instruction",
  76. "Trace/breakpoint trap",
  77. "Aborted",
  78. "Bus error",
  79. "Floating point exception",
  80. "Killed",
  81. "User defined signal 1",
  82. "Segmentation fault",
  83. "User defined signal 2",
  84. "Broken pipe",
  85. "Alarm clock",
  86. "Terminated",
  87. "Child exited",
  88. "Continued",
  89. "Stopped (signal)",
  90. "Stopped",
  91. "Stopped (tty input)",
  92. "Stopped (tty output)",
  93. "Urgent I/O condition",
  94. "CPU time limit exceeded",
  95. "File size limit exceeded",
  96. "Virtual timer expired",
  97. "Profiling timer expired",
  98. "Window changed",
  99. "I/O possible",
  100. "Bad system call",
  101. };
  102. //
  103. // Define the process-wide array of signal handlers.
  104. //
  105. struct sigaction ClSignalHandlers[SIGNAL_COUNT];
  106. //
  107. // Store a pointer to the signal description buffer, allocated on demand.
  108. //
  109. char *ClSignalDescriptionBuffer = NULL;
  110. //
  111. // ------------------------------------------------------------------ Functions
  112. //
  113. LIBC_API
  114. int
  115. siginterrupt (
  116. int Signal,
  117. int Flag
  118. )
  119. /*++
  120. Routine Description:
  121. This routine modifies the behavior of system calls interrupted by a given
  122. signal.
  123. Arguments:
  124. Signal - Supplies the signal number to change restart behavior of.
  125. Flag - Supplies a boolean that if zero, will mean that system calls
  126. interrupted by this signal will be restarted if no data is transferred.
  127. This is the default. If non-zero, system calls interrupted by the given
  128. signal that have not transferred any data yet will return with EINTR.
  129. Return Value:
  130. 0 on success.
  131. -1 on error, and the errno variable will contain more information.
  132. --*/
  133. {
  134. struct sigaction Action;
  135. int Result;
  136. Result = sigaction(Signal, NULL, &Action);
  137. if (Result != 0) {
  138. return Result;
  139. }
  140. if (Flag != 0) {
  141. Action.sa_flags &= ~SA_RESTART;
  142. } else {
  143. Action.sa_flags |= SA_RESTART;
  144. }
  145. return Result;
  146. }
  147. LIBC_API
  148. int
  149. sigaction (
  150. int SignalNumber,
  151. struct sigaction *NewAction,
  152. struct sigaction *OriginalAction
  153. )
  154. /*++
  155. Routine Description:
  156. This routine sets a new signal action for the given signal number.
  157. Arguments:
  158. SignalNumber - Supplies the signal number that will be affected.
  159. NewAction - Supplies an optional pointer to the new signal action to
  160. perform upon receiving that signal. If this pointer is NULL, then no
  161. change will be made to the signal's action.
  162. OriginalAction - Supplies a pointer where the original signal action will
  163. be returned.
  164. Return Value:
  165. 0 on success.
  166. -1 on error, and the errno variable will contain more information.
  167. --*/
  168. {
  169. //
  170. // Just pretend everything is fine, but ignore changes to the signals
  171. // needed by the C library.
  172. //
  173. if ((SignalNumber == SIGNAL_PTHREAD) || (SignalNumber == SIGNAL_SETID)) {
  174. return 0;
  175. }
  176. return ClpSetSignalAction(SignalNumber, NewAction, OriginalAction);
  177. }
  178. LIBC_API
  179. int
  180. sigaddset (
  181. sigset_t *SignalSet,
  182. int SignalNumber
  183. )
  184. /*++
  185. Routine Description:
  186. This routine adds the specified individual signal into the given signal set.
  187. Arguments:
  188. SignalSet - Supplies a pointer to the signal set to add the signal to.
  189. SignalNumber - Supplies the signal number to add.
  190. Return Value:
  191. 0 on success.
  192. -1 on error, and the errno variable will contain more information. The only
  193. error returned an invalid parameter error returned when an invalid signal
  194. number is passed in.
  195. --*/
  196. {
  197. ASSERT(sizeof(sigset_t) == sizeof(SIGNAL_SET));
  198. if (SignalNumber > SIGNAL_COUNT) {
  199. errno = EINVAL;
  200. return -1;
  201. }
  202. ADD_SIGNAL(*SignalSet, SignalNumber);
  203. return 0;
  204. }
  205. LIBC_API
  206. int
  207. sigemptyset (
  208. sigset_t *SignalSet
  209. )
  210. /*++
  211. Routine Description:
  212. This routine initializes the given signal set to contain no signals, the
  213. empty set.
  214. Arguments:
  215. SignalSet - Supplies a pointer to the signal set to initialize.
  216. Return Value:
  217. 0 always to indicate success.
  218. --*/
  219. {
  220. ASSERT(sizeof(sigset_t) == sizeof(SIGNAL_SET));
  221. INITIALIZE_SIGNAL_SET(*SignalSet);
  222. return 0;
  223. }
  224. LIBC_API
  225. int
  226. sigdelset (
  227. sigset_t *SignalSet,
  228. int SignalNumber
  229. )
  230. /*++
  231. Routine Description:
  232. This routine removes the specified signal number from the given signal set.
  233. Arguments:
  234. SignalSet - Supplies a pointer to the signal set to remove the signal from.
  235. SignalNumber - Supplies the signal number to remove.
  236. Return Value:
  237. 0 on success.
  238. -1 on error, and the errno variable will contain more information. The only
  239. error returned an invalid parameter error returned when an invalid signal
  240. number is passed in.
  241. --*/
  242. {
  243. ASSERT(sizeof(sigset_t) == sizeof(SIGNAL_SET));
  244. if (SignalNumber > SIGNAL_COUNT) {
  245. errno = EINVAL;
  246. return -1;
  247. }
  248. REMOVE_SIGNAL(*SignalSet, SignalNumber);
  249. return 0;
  250. }
  251. LIBC_API
  252. int
  253. sigfillset (
  254. sigset_t *SignalSet
  255. )
  256. /*++
  257. Routine Description:
  258. This routine initializes the given signal set to contain all signals set.
  259. Arguments:
  260. SignalSet - Supplies a pointer to the signal set to initialize.
  261. Return Value:
  262. 0 always to indicate success.
  263. --*/
  264. {
  265. ASSERT(sizeof(sigset_t) == sizeof(SIGNAL_SET));
  266. FILL_SIGNAL_SET(*SignalSet);
  267. return 0;
  268. }
  269. LIBC_API
  270. void (
  271. *signal (
  272. int Signal,
  273. void (*SignalFunction)(int)
  274. ))(int)
  275. /*++
  276. Routine Description:
  277. This routine changes a signal's disposition and handler. This method is
  278. deprecated in favor of sigaction because this function's implementation
  279. behavior is to reset the signal handler to the default value after the
  280. signal handler is called, causing nasty race conditions.
  281. Arguments:
  282. Signal - Supplies the signal to change.
  283. SignalFunction - Supplies a pointer to the signal function.
  284. Return Value:
  285. Returns a pointer to the original function wired up for this signal.
  286. --*/
  287. {
  288. struct sigaction Action;
  289. struct sigaction OriginalAction;
  290. int Result;
  291. Action.sa_handler = SignalFunction;
  292. Action.sa_flags = SA_RESETHAND | SA_NODEFER;
  293. sigemptyset(&(Action.sa_mask));
  294. Result = sigaction(Signal, &Action, &OriginalAction);
  295. if (Result == -1) {
  296. return SIG_ERR;
  297. }
  298. return OriginalAction.sa_handler;
  299. }
  300. LIBC_API
  301. int
  302. sigismember (
  303. const sigset_t *SignalSet,
  304. int SignalNumber
  305. )
  306. /*++
  307. Routine Description:
  308. This routine tests whether the specified signal is in the given signal set.
  309. Arguments:
  310. SignalSet - Supplies a pointer to the signal set to test.
  311. SignalNumber - Supplies the signal number to check.
  312. Return Value:
  313. 0 if the signal is not set in the given signal set.
  314. 1 if the signal is set in the given signal set.
  315. -1 on error, and the errno variable will contain more information. The only
  316. error returned an invalid parameter error returned when an invalid signal
  317. number is passed in.
  318. --*/
  319. {
  320. ASSERT(sizeof(sigset_t) == sizeof(SIGNAL_SET));
  321. if (SignalNumber > SIGNAL_COUNT) {
  322. errno = EINVAL;
  323. return -1;
  324. }
  325. if (IS_SIGNAL_SET(*SignalSet, SignalNumber) != FALSE) {
  326. return 1;
  327. }
  328. return 0;
  329. }
  330. LIBC_API
  331. int
  332. sigprocmask (
  333. int LogicalOperation,
  334. const sigset_t *SignalSet,
  335. sigset_t *OriginalSignalSet
  336. )
  337. /*++
  338. Routine Description:
  339. This routine sets the process' blocked signal mask, assuming there's only
  340. one thread in the process.
  341. Arguments:
  342. LogicalOperation - Supplies the operation to use when combining the new
  343. signal set with the existing. Valid values are:
  344. SIG_BLOCK - Add the given signals to the mask of blocked signals.
  345. SIG_SETMASK - Replace the mask of blocked signals wholesale with the
  346. given mask.
  347. SIG_UNBLOCK - Remove the set of signals given from the mask of blocked
  348. signals.
  349. SignalSet - Supplies an optional pointer to the signal set parameter that
  350. will in some way become the new signal mask (the effect it has depends
  351. on the operation parameter).
  352. OriginalSignalSet - Supplies an optional pointer that will receieve the
  353. signal set that was in effect before this call.
  354. Return Value:
  355. 0 if a signal mask was sucessfully sent.
  356. -1 on error, and the errno variable will contain more information about the
  357. error.
  358. --*/
  359. {
  360. SIGNAL_SET NewSet;
  361. SIGNAL_MASK_OPERATION Operation;
  362. SIGNAL_SET PreviousSet;
  363. //
  364. // Don't allow the internal signals used by the C library to become blocked.
  365. //
  366. INITIALIZE_SIGNAL_SET(NewSet);
  367. if (SignalSet != NULL) {
  368. NewSet = *SignalSet;
  369. REMOVE_SIGNAL(NewSet, SIGNAL_PTHREAD);
  370. REMOVE_SIGNAL(NewSet, SIGNAL_SETID);
  371. }
  372. if (SignalSet == NULL) {
  373. Operation = SignalMaskOperationNone;
  374. } else if (LogicalOperation == SIG_BLOCK) {
  375. Operation = SignalMaskOperationSet;
  376. } else if (LogicalOperation == SIG_SETMASK) {
  377. Operation = SignalMaskOperationOverwrite;
  378. } else if (LogicalOperation == SIG_UNBLOCK) {
  379. Operation = SignalMaskOperationClear;
  380. } else {
  381. errno = EINVAL;
  382. return -1;
  383. }
  384. ASSERT(sizeof(SIGNAL_SET) == sizeof(sigset_t));
  385. PreviousSet = OsSetSignalBehavior(SignalMaskBlocked,
  386. Operation,
  387. &NewSet);
  388. if (OriginalSignalSet != NULL) {
  389. *OriginalSignalSet = PreviousSet;
  390. }
  391. return 0;
  392. }
  393. LIBC_API
  394. int
  395. pthread_sigmask (
  396. int LogicalOperation,
  397. const sigset_t *SignalSet,
  398. sigset_t *OriginalSignalSet
  399. )
  400. /*++
  401. Routine Description:
  402. This routine sets the current thread's blocked signal mask.
  403. Arguments:
  404. LogicalOperation - Supplies the operation to use when combining the new
  405. signal set with the existing set. Valid values are:
  406. SIG_BLOCK - Add the given signals to the mask of blocked signals.
  407. SIG_SETMASK - Replace the mask of blocked signals wholesale with the
  408. given mask.
  409. SIG_UNBLOCK - Remove the set of signals given from the mask of blocked
  410. signals.
  411. SignalSet - Supplies an optional pointer to the signal set parameter that
  412. will in some way become the new signal mask (the effect it has depends
  413. on the operation parameter).
  414. OriginalSignalSet - Supplies an optional pointer that will receieve the
  415. signal set that was in effect before this call.
  416. Return Value:
  417. 0 if a signal mask was sucessfully sent.
  418. -1 on error, and the errno variable will contain more information about the
  419. error.
  420. --*/
  421. {
  422. //
  423. // The specification says that the original mask function must only be used
  424. // in a single threaded environment, and that using that routine with
  425. // multiple threads is undefined. In this system's implementation, the
  426. // original function sets the current thread's mask, so just call that.
  427. //
  428. return sigprocmask(LogicalOperation, SignalSet, OriginalSignalSet);
  429. }
  430. LIBC_API
  431. int
  432. kill (
  433. pid_t ProcessId,
  434. int SignalNumber
  435. )
  436. /*++
  437. Routine Description:
  438. This routine sends a signal to a process or group of processes.
  439. Arguments:
  440. ProcessId - Supplies the process ID of the process to send the signal to.
  441. If zero is supplied, then the signal will be sent to all processes in
  442. the process group. If the process ID is -1, the signal will be sent to
  443. all processes the signal can reach. If the process ID is negative but
  444. not negative 1, then the signal will be sent to all processes whose
  445. process group ID is equal to the absolute value of the process ID (and
  446. for which the process has permission to send the signal to).
  447. SignalNumber - Supplies the signal number to send. This value is expected
  448. to be one of the standard signal numbers (i.e. not a real time signal
  449. number).
  450. Return Value:
  451. 0 if a signal was actually sent to any processes.
  452. -1 on error, and the errno variable will contain more information about the
  453. error.
  454. --*/
  455. {
  456. KSTATUS Status;
  457. SIGNAL_TARGET_TYPE TargetType;
  458. if (ProcessId == 0) {
  459. TargetType = SignalTargetCurrentProcessGroup;
  460. } else if (ProcessId == -1) {
  461. TargetType = SignalTargetAllProcesses;
  462. } else if (ProcessId < 0) {
  463. TargetType = SignalTargetProcessGroup;
  464. ProcessId = -ProcessId;
  465. } else {
  466. TargetType = SignalTargetProcess;
  467. }
  468. Status = OsSendSignal(TargetType,
  469. ProcessId,
  470. SignalNumber,
  471. SIGNAL_CODE_USER,
  472. 0);
  473. if (!KSUCCESS(Status)) {
  474. errno = ClConvertKstatusToErrorNumber(Status);
  475. return -1;
  476. }
  477. return 0;
  478. }
  479. LIBC_API
  480. int
  481. killpg (
  482. pid_t ProcessGroupId,
  483. int SignalNumber
  484. )
  485. /*++
  486. Routine Description:
  487. This routine sends a signal to a group of processes.
  488. Arguments:
  489. ProcessGroupId - Supplies the process group ID of the process group to
  490. signal. If zero is supplied, then the signal is sent to all processes
  491. in the current process group. If the process group ID is 1, then the
  492. signal will be sent to all processs the signal can reach.
  493. SignalNumber - Supplies the signal number to send. This value is expected
  494. to be one of the standard signal numbers (i.e. not a real time signal
  495. number).
  496. Return Value:
  497. 0 if a signal was actually sent to any processes.
  498. -1 on error, and the errno variable will contain more information about the
  499. error.
  500. --*/
  501. {
  502. if (ProcessGroupId < 0) {
  503. errno = EINVAL;
  504. return -1;
  505. }
  506. return kill(-ProcessGroupId, SignalNumber);
  507. }
  508. LIBC_API
  509. int
  510. raise (
  511. int SignalNumber
  512. )
  513. /*++
  514. Routine Description:
  515. This routine sends a signal to the current process.
  516. Arguments:
  517. SignalNumber - Supplies the signal number to send. This value is expected
  518. to be one of the standard signal numbers (ie not a real time signal
  519. number).
  520. Return Value:
  521. 0 if a signal was actually sent to any processes.
  522. -1 on error, and the errno variable will contain more information about the
  523. error.
  524. --*/
  525. {
  526. KSTATUS Status;
  527. Status = OsSendSignal(SignalTargetCurrentProcess,
  528. 0,
  529. SignalNumber,
  530. SIGNAL_CODE_USER,
  531. 0);
  532. if (!KSUCCESS(Status)) {
  533. errno = ClConvertKstatusToErrorNumber(Status);
  534. return -1;
  535. }
  536. return 0;
  537. }
  538. LIBC_API
  539. int
  540. sigqueue (
  541. pid_t ProcessId,
  542. int SignalNumber,
  543. union sigval Value
  544. )
  545. /*++
  546. Routine Description:
  547. This routine sends a real time signal to the given process.
  548. Arguments:
  549. ProcessId - Supplies the process ID to send the signal to.
  550. SignalNumber - Supplies the signal number to send. This is expected to be
  551. in the real time range, not one of the standard lower signal numbers.
  552. Value - Supplies the value to send off with the signal.
  553. Return Value:
  554. 0 if a signal was actually sent to any processes.
  555. -1 on error, and the errno variable will contain more information about the
  556. error.
  557. --*/
  558. {
  559. KSTATUS Status;
  560. ASSERT(sizeof(void *) >= sizeof(int));
  561. Status = OsSendSignal(SignalTargetProcess,
  562. ProcessId,
  563. SignalNumber,
  564. SIGNAL_CODE_QUEUE,
  565. (UINTN)(Value.sival_ptr));
  566. if (KSUCCESS(Status)) {
  567. return 0;
  568. } else {
  569. errno = ClConvertKstatusToErrorNumber(Status);
  570. }
  571. return -1;
  572. }
  573. LIBC_API
  574. int
  575. pause (
  576. void
  577. )
  578. /*++
  579. Routine Description:
  580. This routine suspends execution until a signal is caught and handled by the
  581. application. This routine is known to be frought with timing problems, as
  582. the most common use for it involves checking if a signal has occurred, and
  583. calling pause if not. Unfortunately that doesn't work as a signal can come
  584. in after the check but before the call to pause. Pause is really only
  585. useful if the entirety of the application functionality is implemented
  586. inside signal handlers.
  587. Arguments:
  588. None.
  589. Return Value:
  590. -1 always. A return rather negatively is thought of as a failure of the
  591. function. The errno variable will be set to indicate the "error".
  592. --*/
  593. {
  594. OsSuspendExecution(SignalMaskOperationNone,
  595. NULL,
  596. NULL,
  597. SYS_WAIT_TIME_INDEFINITE);
  598. errno = EINTR;
  599. return -1;
  600. }
  601. LIBC_API
  602. int
  603. sigpending (
  604. sigset_t *SignalSet
  605. )
  606. /*++
  607. Routine Description:
  608. This routine returns the current set of signals that are blocked from
  609. delivery to the current calling thread and that are pending on the process
  610. or calling thread.
  611. Arguments:
  612. SignalSet - Supplies a pointer where the mask of pending signals will be
  613. returned.
  614. Return Value:
  615. 0 on success.
  616. -1 on failure, and errno will be set to contain more information.
  617. --*/
  618. {
  619. INITIALIZE_SIGNAL_SET(*SignalSet);
  620. *SignalSet = OsSetSignalBehavior(SignalMaskPending,
  621. SignalMaskOperationNone,
  622. (PSIGNAL_SET)SignalSet);
  623. return 0;
  624. }
  625. LIBC_API
  626. int
  627. sigsuspend (
  628. const sigset_t *SignalMask
  629. )
  630. /*++
  631. Routine Description:
  632. This routine temporarily replaces the current thread's signal mask with
  633. the given signal mask, then suspends the thread's execution until an
  634. unblocked signal comes in.
  635. Arguments:
  636. SignalMask - Supplies a pointer to the mask of signals to block during the
  637. suspend.
  638. Return Value:
  639. -1 always. A return rather negatively is thought of as a failure of the
  640. function. The errno variable will be set to indicate the "error".
  641. --*/
  642. {
  643. OsSuspendExecution(SignalMaskOperationOverwrite,
  644. (PSIGNAL_SET)SignalMask,
  645. NULL,
  646. SYS_WAIT_TIME_INDEFINITE);
  647. //
  648. // Obviously if execution is back, a signal must have occurred that was
  649. // caught by the application.
  650. //
  651. errno = EINTR;
  652. return -1;
  653. }
  654. LIBC_API
  655. int
  656. sigwait (
  657. const sigset_t *SignalSet,
  658. int *SignalNumber
  659. )
  660. /*++
  661. Routine Description:
  662. This routine waits for a signal from the given set and returns the number
  663. of the received signal.
  664. Arguments:
  665. SignalSet - Supplies a pointer to a set of signals on which to wait. This
  666. set of signals shall have been blocked prior to calling this routine.
  667. SignalNumber - Supplies a pointer that receives the signal number of the
  668. received signal.
  669. Return Value:
  670. 0 on success.
  671. Returns an error number on failure.
  672. --*/
  673. {
  674. KSTATUS KernelStatus;
  675. SIGNAL_PARAMETERS SignalParameters;
  676. if (SignalNumber == NULL) {
  677. return EINVAL;
  678. }
  679. do {
  680. KernelStatus = OsSuspendExecution(SignalMaskOperationClear,
  681. (PSIGNAL_SET)SignalSet,
  682. &SignalParameters,
  683. SYS_WAIT_TIME_INDEFINITE);
  684. } while (KernelStatus == STATUS_INTERRUPTED);
  685. if (KSUCCESS(KernelStatus)) {
  686. *SignalNumber = SignalParameters.SignalNumber;
  687. }
  688. return ClConvertKstatusToErrorNumber(KernelStatus);
  689. }
  690. LIBC_API
  691. int
  692. sigwaitinfo (
  693. const sigset_t *SignalSet,
  694. siginfo_t *SignalInformation
  695. )
  696. /*++
  697. Routine Description:
  698. This routine waits for a signal from the given set and returns the signal
  699. information for the received signal. If an unblocked signal outside the
  700. given set arrives, this routine will return EINTR.
  701. Arguments:
  702. SignalSet - Supplies a pointer to a set of signals on which to wait. This
  703. set of signals shall have been blocked prior to calling this routine.
  704. SignalInformation - Supplies an optional pointer that receives the signal
  705. information for the selected singal.
  706. Return Value:
  707. The selected signal number on success.
  708. -1 on failure, and errno will be set to contain more information.
  709. --*/
  710. {
  711. return sigtimedwait(SignalSet, SignalInformation, NULL);
  712. }
  713. LIBC_API
  714. int
  715. sigtimedwait (
  716. const sigset_t *SignalSet,
  717. siginfo_t *SignalInformation,
  718. const struct timespec *Timeout
  719. )
  720. /*++
  721. Routine Description:
  722. This routine waits for a signal from the given set and returns the signal
  723. information for the received signal. If the timeout is reached without a
  724. signal, then the routine will fail with EAGAIN set in errno. If an
  725. unblocked signal outside the given set arrives, this routine will return
  726. EINTR.
  727. Arguments:
  728. SignalSet - Supplies a pointer to a set of signals on which to wait. This
  729. set of signals shall have been blocked prior to calling this routine.
  730. SignalInformation - Supplies an optional pointer that receives the signal
  731. information for the selected singal.
  732. Timeout - Supplies an optional timeout interval to wait for one of the set
  733. of signals to become pending. If no signal becomes set within the
  734. timeout interval EAGAIN will be returned. If NULL is supplied, the
  735. routine will wait indefinitely for a signal to arrive.
  736. Return Value:
  737. The selected signal number on success.
  738. -1 on failure, and errno will be set to contain more information.
  739. --*/
  740. {
  741. KSTATUS KernelStatus;
  742. INT Result;
  743. INT SignalNumber;
  744. SIGNAL_PARAMETERS SignalParameters;
  745. ULONG TimeoutInMilliseconds;
  746. Result = ClpConvertSpecificTimeoutToSystemTimeout(Timeout,
  747. &TimeoutInMilliseconds);
  748. if (Result != 0) {
  749. errno = Result;
  750. return -1;
  751. }
  752. KernelStatus = OsSuspendExecution(SignalMaskOperationClear,
  753. (PSIGNAL_SET)SignalSet,
  754. &SignalParameters,
  755. TimeoutInMilliseconds);
  756. if (KSUCCESS(KernelStatus)) {
  757. SignalNumber = SignalParameters.SignalNumber;
  758. if (SignalInformation != NULL) {
  759. RtlZeroMemory(SignalInformation, sizeof(siginfo_t));
  760. SignalInformation->si_signo = SignalNumber;
  761. SignalInformation->si_code = SignalParameters.SignalCode;
  762. SignalInformation->si_errno = SignalParameters.ErrorNumber;
  763. SignalInformation->si_pid = SignalParameters.FromU.SendingProcess;
  764. SignalInformation->si_uid = SignalParameters.SendingUserId;
  765. SignalInformation->si_addr = SignalParameters.FromU.FaultingAddress;
  766. SignalInformation->si_status = SignalParameters.Parameter;
  767. SignalInformation->si_band = SignalParameters.FromU.Poll.BandEvent;
  768. SignalInformation->si_value.sival_int = SignalParameters.Parameter;
  769. SignalInformation->si_fd =
  770. (int)(UINTN)SignalParameters.FromU.Poll.Descriptor;
  771. }
  772. } else {
  773. SignalNumber = -1;
  774. if (KernelStatus == STATUS_TIMEOUT) {
  775. errno = EAGAIN;
  776. } else {
  777. errno = ClConvertKstatusToErrorNumber(KernelStatus);
  778. }
  779. }
  780. return SignalNumber;
  781. }
  782. LIBC_API
  783. pid_t
  784. wait (
  785. int *Status
  786. )
  787. /*++
  788. Routine Description:
  789. This routine obtains status information about one of the caller's
  790. terminated child processes. This routine blocks until such status
  791. information becomes available or until the calling process receives a
  792. terminating signal.
  793. Arguments:
  794. Status - Supplies an optional pointer where the child process' exit status
  795. information will be returned.
  796. Return Value:
  797. Returns the process ID of the child process that just experienced a state
  798. change.
  799. -1 on failure, and the errno variable will contain more information.
  800. --*/
  801. {
  802. UINTN ChildExitValue;
  803. PROCESS_ID ChildPid;
  804. KSTATUS KernelStatus;
  805. ULONG Reason;
  806. ChildPid = -1;
  807. Reason = 0;
  808. KernelStatus = OsWaitForChildProcess(SYSTEM_CALL_WAIT_FLAG_EXITED_CHILDREN,
  809. &ChildPid,
  810. &Reason,
  811. &ChildExitValue,
  812. NULL);
  813. if (!KSUCCESS(KernelStatus)) {
  814. errno = ClConvertKstatusToErrorNumber(KernelStatus);
  815. return -1;
  816. }
  817. if (Status != NULL) {
  818. *Status = ClpConvertToWaitStatus(Reason, ChildExitValue);
  819. }
  820. return ChildPid;
  821. }
  822. LIBC_API
  823. pid_t
  824. waitpid (
  825. pid_t ProcessId,
  826. int *Status,
  827. int Options
  828. )
  829. /*++
  830. Routine Description:
  831. This routine obtains status information about one of the caller's child
  832. processes. This routine can block waiting for any child process to change,
  833. or can wait for a specific process.
  834. Arguments:
  835. ProcessId - Supplies the process ID of the process to wait for. The
  836. various valid values are as follows:
  837. If equal to -1, then this routine will be equivalent to the original
  838. routine, it will return when any process has status information.
  839. If greater than 0, then the specific process ID will be waited for.
  840. If 0, then any child whose process process group ID is equal to that of
  841. the calling process will satisfy the wait.
  842. If less than negative one, then any child process whose process group ID
  843. is equal to the absolute value of this parameter will satisfy the
  844. wait.
  845. Status - Supplies an optional pointer where the child process' exit status
  846. information will be returned.
  847. Options - Supplies a bitfield of options. This field may contain one or
  848. more of the following options:
  849. WCONTINUED - Wait for a process that just continued.
  850. WNOHANG - Return immediately if no child process information is
  851. currently available.
  852. WUNTRACED - Wait for a process that just stopped.
  853. Return Value:
  854. Returns the process ID of the child process that just experienced a state
  855. change.
  856. -1 on failure, and the errno variable will contain more information.
  857. --*/
  858. {
  859. UINTN ChildExitValue;
  860. PROCESS_ID ChildPid;
  861. ULONG Flags;
  862. KSTATUS KernelStatus;
  863. ULONG Reason;
  864. ULONG ValidOptions;
  865. ChildPid = ProcessId;
  866. Reason = 0;
  867. //
  868. // Only accept valid options.
  869. //
  870. ValidOptions = WCONTINUED | WUNTRACED | WNOHANG;
  871. if ((Options & ~ValidOptions) != 0) {
  872. errno = EINVAL;
  873. return -1;
  874. }
  875. ASSERT_WAIT_FLAGS_EQUIVALENT();
  876. Flags = Options | SYSTEM_CALL_WAIT_FLAG_EXITED_CHILDREN;
  877. KernelStatus = OsWaitForChildProcess(Flags,
  878. &ChildPid,
  879. &Reason,
  880. &ChildExitValue,
  881. NULL);
  882. if (KernelStatus == STATUS_NO_DATA_AVAILABLE) {
  883. assert((Options & WNOHANG) != 0);
  884. return 0;
  885. }
  886. if (!KSUCCESS(KernelStatus)) {
  887. errno = ClConvertKstatusToErrorNumber(KernelStatus);
  888. return -1;
  889. }
  890. if (Status != NULL) {
  891. *Status = ClpConvertToWaitStatus(Reason, ChildExitValue);
  892. }
  893. return ChildPid;
  894. }
  895. LIBC_API
  896. int
  897. waitid (
  898. idtype_t IdentifierType,
  899. id_t ProcessOrGroupIdentifier,
  900. siginfo_t *SignalInformation,
  901. int Options
  902. )
  903. /*++
  904. Routine Description:
  905. This routine suspends execution until a child process of this process
  906. changes state.
  907. Arguments:
  908. IdentifierType - Supplies a value indicating whether the process or group
  909. identifier identifies a process, group, or nothing. If nothing, then
  910. any child process changing state will satisfy the wait.
  911. ProcessOrGroupIdentifier - Supplies a process or process group identifier
  912. to wait for. If the identifier type indicates neither, then this
  913. parameter is ignored.
  914. SignalInformation - Supplies a pointer where the child signal information
  915. will be returned.
  916. Options - Supplies a bitfield of options. Valid values are WEXITED,
  917. WSTOPPED, WCONTINUED, WNOHANG, and WNOWAIT. One or more of WEXITED,
  918. WSTOPPED or WCONTINUED must be supplied.
  919. Return Value:
  920. 0 if WNOHANG was specified and no child was waiting to report status
  921. information.
  922. 0 on success (child information was returned).
  923. -1 on failure, and the errno variable will be set to indicate the error.
  924. --*/
  925. {
  926. UINTN ChildExitValue;
  927. PROCESS_ID ChildPid;
  928. ULONG Flags;
  929. ULONG Reason;
  930. KSTATUS Status;
  931. RtlZeroMemory(SignalInformation, sizeof(siginfo_t));
  932. if (IdentifierType == P_PID) {
  933. ChildPid = ProcessOrGroupIdentifier;
  934. } else if (IdentifierType == P_PGID) {
  935. ChildPid = -ProcessOrGroupIdentifier;
  936. } else if (IdentifierType == P_ALL) {
  937. ChildPid = -1;
  938. } else {
  939. errno = EINVAL;
  940. return -1;
  941. }
  942. //
  943. // Gather the required options.
  944. //
  945. ASSERT_WAIT_FLAGS_EQUIVALENT();
  946. Flags = Options;
  947. //
  948. // There must be one or more of WEXITED, WCONTINUED, and WUNTRACED
  949. // specified.
  950. //
  951. if ((Options & (WEXITED | WCONTINUED | WUNTRACED)) == 0) {
  952. errno = EINVAL;
  953. return -1;
  954. }
  955. Status = OsWaitForChildProcess(Flags,
  956. &ChildPid,
  957. &Reason,
  958. &ChildExitValue,
  959. NULL);
  960. if (Status == STATUS_NO_DATA_AVAILABLE) {
  961. assert((Options & WNOHANG) != 0);
  962. return 0;
  963. }
  964. if (!KSUCCESS(Status)) {
  965. errno = ClConvertKstatusToErrorNumber(Status);
  966. return -1;
  967. }
  968. SignalInformation->si_signo = SIGCHLD;
  969. SignalInformation->si_code = Reason;
  970. SignalInformation->si_pid = ChildPid;
  971. SignalInformation->si_status = ChildExitValue;
  972. SignalInformation->si_uid = 0;
  973. return ChildPid;
  974. }
  975. LIBC_API
  976. pid_t
  977. wait3 (
  978. int *Status,
  979. int Options,
  980. struct rusage *ResourceUsage
  981. )
  982. /*++
  983. Routine Description:
  984. This routine is equivalent to the wait function, except it can obtain
  985. resource usage about the reaped child. This function is provided for
  986. compatibility with existing applications. New applications should use the
  987. waitpid function.
  988. Arguments:
  989. Status - Supplies an optional pointer where the child process' exit status
  990. information will be returned.
  991. Options - Supplies a bitfield of options. See the waitpid function for
  992. more details.
  993. ResourceUsage - Supplies an optional pointer where the resource usage of
  994. the process will be returned on success.
  995. Return Value:
  996. Returns the process ID of the child process that just experienced a state
  997. change.
  998. -1 on failure, and the errno variable will contain more information.
  999. --*/
  1000. {
  1001. return wait4(-1, Status, Options, ResourceUsage);
  1002. }
  1003. LIBC_API
  1004. pid_t
  1005. wait4 (
  1006. pid_t ProcessId,
  1007. int *Status,
  1008. int Options,
  1009. struct rusage *ResourceUsage
  1010. )
  1011. /*++
  1012. Routine Description:
  1013. This routine is equivalent to the waitpid function, except it can obtain
  1014. resource usage about the reaped child. This function is provided for
  1015. compatibility with existing applications. New applications should use the
  1016. waitpid function.
  1017. Arguments:
  1018. ProcessId - Supplies the process ID to wait for. See waitpid for more
  1019. information.
  1020. Status - Supplies an optional pointer where the child process' exit status
  1021. information will be returned.
  1022. Options - Supplies a bitfield of options. See the waitpid function for
  1023. more details.
  1024. ResourceUsage - Supplies an optional pointer where the resource usage of
  1025. the process will be returned on success.
  1026. Return Value:
  1027. Returns the process ID of the child process that just experienced a state
  1028. change.
  1029. -1 on failure, and the errno variable will contain more information.
  1030. --*/
  1031. {
  1032. UINTN ChildExitValue;
  1033. PROCESS_ID ChildPid;
  1034. ULONG Flags;
  1035. ULONGLONG Frequency;
  1036. KSTATUS KernelStatus;
  1037. ULONG Reason;
  1038. RESOURCE_USAGE Resources;
  1039. PRESOURCE_USAGE ResourcesPointer;
  1040. ULONG ValidOptions;
  1041. ChildPid = ProcessId;
  1042. Reason = 0;
  1043. //
  1044. // Only accept valid options.
  1045. //
  1046. ValidOptions = WCONTINUED | WUNTRACED | WNOHANG;
  1047. if ((Options & ~ValidOptions) != 0) {
  1048. errno = EINVAL;
  1049. return -1;
  1050. }
  1051. ASSERT_WAIT_FLAGS_EQUIVALENT();
  1052. Flags = Options | SYSTEM_CALL_WAIT_FLAG_EXITED_CHILDREN;
  1053. ResourcesPointer = NULL;
  1054. if (ResourceUsage != NULL) {
  1055. ResourcesPointer = &Resources;
  1056. }
  1057. KernelStatus = OsWaitForChildProcess(Flags,
  1058. &ChildPid,
  1059. &Reason,
  1060. &ChildExitValue,
  1061. ResourcesPointer);
  1062. if (KernelStatus == STATUS_NO_DATA_AVAILABLE) {
  1063. assert((Options & WNOHANG) != 0);
  1064. return 0;
  1065. }
  1066. if (!KSUCCESS(KernelStatus)) {
  1067. errno = ClConvertKstatusToErrorNumber(KernelStatus);
  1068. return -1;
  1069. }
  1070. if (ResourceUsage != NULL) {
  1071. OsGetResourceUsage(ResourceUsageRequestInvalid, -1, NULL, &Frequency);
  1072. ClpConvertResourceUsage(&Resources, Frequency, ResourceUsage);
  1073. }
  1074. if (Status != NULL) {
  1075. *Status = ClpConvertToWaitStatus(Reason, ChildExitValue);
  1076. }
  1077. return ChildPid;
  1078. }
  1079. LIBC_API
  1080. void
  1081. psignal (
  1082. int Signal,
  1083. char *String
  1084. )
  1085. /*++
  1086. Routine Description:
  1087. This routine prints to stderr the given string, a colon, a space, and
  1088. a description of the given signal number.
  1089. Arguments:
  1090. Signal - Supplies the signal number to describe on standard error.
  1091. String - Supplies an optional pointer to a string. If this is NULL, then
  1092. the colon and the space will be omitted.
  1093. Return Value:
  1094. None.
  1095. --*/
  1096. {
  1097. PSTR SignalString;
  1098. if (String != NULL) {
  1099. fprintf(stderr, "%s: ", String);
  1100. }
  1101. SignalString = NULL;
  1102. if ((Signal >= 0) && (Signal < NSIG)) {
  1103. SignalString = (PSTR)(sys_siglist[Signal]);
  1104. }
  1105. if (SignalString == NULL) {
  1106. if ((Signal >= SIGRTMIN) && (Signal <= SIGRTMAX)) {
  1107. fprintf(stderr, "Real-time signal %d", Signal);
  1108. } else {
  1109. fprintf(stderr, "Unknown signal %d", Signal);
  1110. }
  1111. } else {
  1112. fprintf(stderr, "%s", SignalString);
  1113. }
  1114. return;
  1115. }
  1116. LIBC_API
  1117. char *
  1118. strsignal (
  1119. int Signal
  1120. )
  1121. /*++
  1122. Routine Description:
  1123. This routine returns a pointer to a string containing a descriptive message
  1124. for the given signal number. This routine is neither thread safe nor
  1125. reentrant.
  1126. Arguments:
  1127. Signal - Supplies the signal number to return a description for.
  1128. Return Value:
  1129. Returns a pointer to a signal description. This buffer may be used until
  1130. the next call to this routine.
  1131. --*/
  1132. {
  1133. PSTR SignalString;
  1134. SignalString = NULL;
  1135. if ((Signal >= 0) && (Signal < NSIG)) {
  1136. SignalString = (PSTR)(sys_siglist[Signal]);
  1137. }
  1138. if (SignalString != NULL) {
  1139. return SignalString;
  1140. }
  1141. if (ClSignalDescriptionBuffer == NULL) {
  1142. ClSignalDescriptionBuffer = malloc(SIGNAL_DESCRIPTION_BUFFER_SIZE);
  1143. if (ClSignalDescriptionBuffer == NULL) {
  1144. return "Unknown signal";
  1145. }
  1146. }
  1147. if ((Signal >= SIGRTMIN) && (Signal <= SIGRTMAX)) {
  1148. snprintf(ClSignalDescriptionBuffer,
  1149. SIGNAL_DESCRIPTION_BUFFER_SIZE,
  1150. "Real-time signal %d",
  1151. Signal);
  1152. } else {
  1153. snprintf(ClSignalDescriptionBuffer,
  1154. SIGNAL_DESCRIPTION_BUFFER_SIZE,
  1155. "Unknown signal %d",
  1156. Signal);
  1157. }
  1158. return ClSignalDescriptionBuffer;
  1159. }
  1160. VOID
  1161. ClpInitializeSignals (
  1162. VOID
  1163. )
  1164. /*++
  1165. Routine Description:
  1166. This routine initializes signal handling functionality for the C library.
  1167. Arguments:
  1168. None.
  1169. Return Value:
  1170. None.
  1171. --*/
  1172. {
  1173. PPROCESS_ENVIRONMENT Environment;
  1174. SIGNAL_SET IgnoredSignals;
  1175. ULONG Signal;
  1176. //
  1177. // Mark the signals that were left ignored by the parent process.
  1178. //
  1179. Environment = OsGetCurrentEnvironment();
  1180. IgnoredSignals = Environment->StartData->IgnoredSignals;
  1181. Signal = 1;
  1182. while ((!IS_SIGNAL_SET_EMPTY(IgnoredSignals)) && (Signal < SIGNAL_COUNT)) {
  1183. if (IS_SIGNAL_SET(IgnoredSignals, Signal)) {
  1184. ClSignalHandlers[Signal].sa_handler = SIG_IGN;
  1185. REMOVE_SIGNAL(IgnoredSignals, Signal);
  1186. }
  1187. Signal += 1;
  1188. }
  1189. OsSetSignalHandler(ClpHandleSignal);
  1190. return;
  1191. }
  1192. int
  1193. ClpSetSignalAction (
  1194. int SignalNumber,
  1195. struct sigaction *NewAction,
  1196. struct sigaction *OriginalAction
  1197. )
  1198. /*++
  1199. Routine Description:
  1200. This routine sets a new signal action for the given signal number.
  1201. Arguments:
  1202. SignalNumber - Supplies the signal number that will be affected.
  1203. NewAction - Supplies an optional pointer to the new signal action to
  1204. perform upon receiving that signal. If this pointer is NULL, then no
  1205. change will be made to the signal's action.
  1206. OriginalAction - Supplies a pointer where the original signal action will
  1207. be returned.
  1208. Return Value:
  1209. 0 on success.
  1210. -1 on error, and the errno variable will contain more information.
  1211. --*/
  1212. {
  1213. struct sigaction OriginalCopy;
  1214. SIGNAL_SET SignalSet;
  1215. if ((NewAction != NULL) &&
  1216. ((SignalNumber == SIGKILL) || (SignalNumber == SIGSTOP))) {
  1217. errno = EINVAL;
  1218. return -1;
  1219. }
  1220. if (SignalNumber > SIGNAL_COUNT) {
  1221. errno = EINVAL;
  1222. return -1;
  1223. }
  1224. OriginalCopy = ClSignalHandlers[SignalNumber];
  1225. if (NewAction != NULL) {
  1226. ClSignalHandlers[SignalNumber].sa_handler = SIG_DFL;
  1227. RtlMemoryBarrier();
  1228. ClSignalHandlers[SignalNumber].sa_mask = NewAction->sa_mask;
  1229. ClSignalHandlers[SignalNumber].sa_flags = NewAction->sa_flags;
  1230. RtlMemoryBarrier();
  1231. ClSignalHandlers[SignalNumber].sa_handler = NewAction->sa_handler;
  1232. RtlMemoryBarrier();
  1233. }
  1234. if (OriginalAction != NULL) {
  1235. *OriginalAction = OriginalCopy;
  1236. }
  1237. //
  1238. // Set this up in the kernel as well.
  1239. //
  1240. INITIALIZE_SIGNAL_SET(SignalSet);
  1241. ADD_SIGNAL(SignalSet, SignalNumber);
  1242. if (ClSignalHandlers[SignalNumber].sa_handler == SIG_DFL) {
  1243. OsSetSignalBehavior(SignalMaskHandled,
  1244. SignalMaskOperationClear,
  1245. &SignalSet);
  1246. } else if (ClSignalHandlers[SignalNumber].sa_handler == SIG_IGN) {
  1247. OsSetSignalBehavior(SignalMaskIgnored,
  1248. SignalMaskOperationSet,
  1249. &SignalSet);
  1250. } else {
  1251. OsSetSignalBehavior(SignalMaskHandled,
  1252. SignalMaskOperationSet,
  1253. &SignalSet);
  1254. }
  1255. return 0;
  1256. }
  1257. //
  1258. // --------------------------------------------------------- Internal Functions
  1259. //
  1260. BOOL
  1261. ClpHandleSignal (
  1262. PSIGNAL_PARAMETERS SignalInformation,
  1263. PSIGNAL_CONTEXT Context
  1264. )
  1265. /*++
  1266. Routine Description:
  1267. This routine is called whenever a signal occurs for the current process or
  1268. thread.
  1269. Arguments:
  1270. SignalInformation - Supplies a pointer to the signal information.
  1271. Context - Supplies a pointer to the signal context, including the machine
  1272. state before the signal was applied.
  1273. Return Value:
  1274. TRUE if an interrupted function can restart.
  1275. FALSE otherwise.
  1276. --*/
  1277. {
  1278. struct sigaction *Action;
  1279. int Flags;
  1280. siginfo_t HandlerInformation;
  1281. struct sigaction OriginalAction;
  1282. struct sigaction ResetAction;
  1283. ULONG Signal;
  1284. SIGNAL_SET SignalMask;
  1285. Signal = SignalInformation->SignalNumber;
  1286. Action = &(ClSignalHandlers[Signal]);
  1287. Flags = Action->sa_flags;
  1288. //
  1289. // Add to the signal mask if desired. SA_RESETHAND behaves like SA_NODEFER.
  1290. //
  1291. if ((IS_SIGNAL_SET_EMPTY(Action->sa_mask) == FALSE) ||
  1292. ((Flags & (SA_NODEFER | SA_RESETHAND)) == 0)) {
  1293. SignalMask = Action->sa_mask;
  1294. if ((Flags & (SA_NODEFER | SA_RESETHAND)) == 0) {
  1295. ADD_SIGNAL(SignalMask, Signal);
  1296. }
  1297. SignalMask = OsSetSignalBehavior(SignalMaskBlocked,
  1298. SignalMaskOperationSet,
  1299. &SignalMask);
  1300. }
  1301. //
  1302. // Reset the disposition if requested.
  1303. //
  1304. if (((Flags & SA_RESETHAND) != 0) &&
  1305. (Signal != SIGILL) && (Signal != SIGTRAP)) {
  1306. RtlZeroMemory(&ResetAction, sizeof(struct sigaction));
  1307. ClpSetSignalAction(Signal, &ResetAction, &OriginalAction);
  1308. Action = &OriginalAction;
  1309. }
  1310. //
  1311. // If no handler is installed, this handler shouldn't have been called.
  1312. // reset to the default action and reraise.
  1313. //
  1314. if (Action->sa_handler == SIG_DFL) {
  1315. signal(SignalInformation->SignalNumber, SIG_DFL);
  1316. raise(SignalInformation->SignalNumber);
  1317. //
  1318. // If the caller specified to ignore the signal, there's nothing to do.
  1319. // If it wasn't one of those two, then it's a real handler that needs to be
  1320. // called.
  1321. //
  1322. } else if (Action->sa_handler != SIG_IGN) {
  1323. if ((Flags & SA_SIGINFO) != 0) {
  1324. HandlerInformation.si_signo = Signal;
  1325. HandlerInformation.si_code = SignalInformation->SignalCode;
  1326. HandlerInformation.si_errno = SignalInformation->ErrorNumber;
  1327. HandlerInformation.si_pid = SignalInformation->FromU.SendingProcess;
  1328. HandlerInformation.si_uid = SignalInformation->SendingUserId;
  1329. HandlerInformation.si_addr =
  1330. SignalInformation->FromU.FaultingAddress;
  1331. HandlerInformation.si_status = SignalInformation->Parameter;
  1332. HandlerInformation.si_band =
  1333. SignalInformation->FromU.Poll.BandEvent;
  1334. HandlerInformation.si_value.sival_int =
  1335. SignalInformation->Parameter;
  1336. HandlerInformation.si_fd =
  1337. (int)(UINTN)SignalInformation->FromU.Poll.Descriptor;
  1338. Action->sa_sigaction(Signal, &HandlerInformation, Context);
  1339. } else {
  1340. Action->sa_handler(Signal);
  1341. }
  1342. }
  1343. //
  1344. // Report whether or not the restart flag was set so that the system can
  1345. // restart a function if required.
  1346. //
  1347. if ((Flags & SA_RESTART) != 0) {
  1348. return TRUE;
  1349. }
  1350. return FALSE;
  1351. }
  1352. int
  1353. ClpConvertToWaitStatus (
  1354. USHORT Reason,
  1355. UINTN Value
  1356. )
  1357. /*++
  1358. Routine Description:
  1359. This routine converts a reason code and exit status into a wait status.
  1360. Arguments:
  1361. Reason - Supplies the reason for the child event.
  1362. Value - Supplies the exit status or terminating signal.
  1363. Return Value:
  1364. Returns the encoded wait status that is returned by the wait family of
  1365. functions.
  1366. --*/
  1367. {
  1368. int Status;
  1369. Status = 0;
  1370. switch (Reason) {
  1371. //
  1372. // If stopped, set the signal portion to all ones, but the status portion
  1373. // to the stop signal.
  1374. //
  1375. case CHILD_SIGNAL_REASON_STOPPED:
  1376. //
  1377. // Fall through.
  1378. //
  1379. Status |= 0x7F;
  1380. case CHILD_SIGNAL_REASON_EXITED:
  1381. //
  1382. // Add in the exit status or stop signal.
  1383. //
  1384. Status |= (Value << 8) & 0xFF00;
  1385. break;
  1386. case CHILD_SIGNAL_REASON_DUMPED:
  1387. //
  1388. // Add the dumped flag.
  1389. //
  1390. Status |= 0x80;
  1391. //
  1392. // Fall through.
  1393. //
  1394. case CHILD_SIGNAL_REASON_KILLED:
  1395. case CHILD_SIGNAL_REASON_TRAPPED:
  1396. //
  1397. // The terminating signal goes in the low byte.
  1398. //
  1399. ASSERT(Value < 0x7F);
  1400. Status |= Value & 0x7F;
  1401. break;
  1402. case CHILD_SIGNAL_REASON_CONTINUED:
  1403. //
  1404. // Continued gets its own special value.
  1405. //
  1406. Status = 0xFFFF;
  1407. break;
  1408. }
  1409. return Status;
  1410. }