home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Mint / mint095b.zoo / doc / signal.doc < prev    next >
Text File  |  1992-05-17  |  21KB  |  472 lines

  1. An Introduction to Signals Under MiNT
  2.  
  3. MiNT introduces the new (to TOS) concept of a signal. If you're
  4. familiar with Unix/Posix signals, then MiNT signals will will be
  5. easy to learn; but note that there are some (not so subtle) differences
  6. between MiNT and Unix!
  7.  
  8. What is a Signal?
  9.  
  10. A signal is a small non-negative integer that represents an exceptional event;
  11. something that is very urgent. It's somewhat like an interrupt or
  12. exception to the CPU, only it's implemented in the operating system
  13. instead of in the hardware. Like many exceptions (bus errors, etc.) signals
  14. are usually fatal. Most signals can be caught by programs (so that a
  15. program-defined routine is called) or ignored; if a signal is caught or
  16. ignored, it is no longer fatal. Signals can also be blocked; a
  17. blocked signal is not acted upon until it is unblocked.
  18.  
  19. A signal is said to be sent to a process when the exceptional
  20. condition related to that signal occurs, or when another process sends
  21. the signal with the Pkill system call. The signal is said to
  22. be delivered to the process when that process wakes up and
  23. begins to take whatever actions are appropriate for the signal. Note
  24. that there may be a considerable time interval between the sending of
  25. a signal and its delivery. For example, if process A has blocked the
  26. SIGHUP signal (signal 1), then no SIGHUP will be delivered to it until
  27. it has unblocked that signal, even if process B sends it SIGHUP with
  28. the Pkill system call. Note also that a signal is not
  29. necessarily delivered the same number of times that it is sent. If both
  30. process B and process C send SIGHUP to process A, when process A
  31. unblocks SIGHUP only one SIGHUP will be delivered. This is because signals
  32. are like flags; once a flag has been set (the signal is sent) setting
  33. the flag again will have no effect until it has been cleared (the signal
  34. is delivered).
  35.  
  36. What Signals Are There?
  37.  
  38. There are 32 possible signals, 0-31. Not all of these have been assigned
  39. a meaning under MiNT. Here are the ones that have been given a meaning;
  40. we give the symbolic name for the signal, the corresponding integer,
  41. and the "traditional" meaning for the process that the signal is sent to.
  42. Any signal not listed here should be considered as "reserved" and should not
  43. be used by applications.
  44.  
  45. Unless otherwise noted, the default action for signals is to terminate
  46. the process.
  47.  
  48. #define    SIGNULL        0    [no default action, signal is never delivered]
  49. This isn't really a signal at all; it is never delivered to processes
  50. and has no effect. It exists only so that processes can test to see if
  51. a particular child process has exited, by attempting to send SIGNULL
  52. to the child. If the child exists, the attempt will succeed but nothing
  53. will be done. If the child has terminated, the caller will get an error.
  54. It is not possible to catch or block this signal, since it is never
  55. sent to processes anyway.
  56.  
  57. #define SIGHUP        1
  58. "The terminal that you're connected to is no longer valid." This signal
  59. is commonly sent by, for example, window managers when the user has
  60. closed the window. Processes should not attempt any I/O to their
  61. controlling terminal after receiving this signal, and indeed should probably
  62. exit unless the user has specifically asked them to continue.
  63.  
  64. #define SIGINT        2
  65. "Please stop what you're doing." This signal is sent when the user
  66. presses control-C. It usually means that the process should exit; interactive
  67. processes may wish to catch SIGINT so that the user can use it to
  68. break out of time-consuming tasks.
  69.  
  70. #define SIGQUIT        3
  71. "Stop what you're doing, something's gone wrong!" This signal is sent when
  72. the user presses control-\. It usually indicates a desire to immediately
  73. abort the process because of an error that the user has noticed. It is
  74. generally thought to be "stronger" than SIGINT, and exiting (perhaps after
  75. cleaning up data structures) is an appropriate response to this.
  76.  
  77. #define SIGILL        4
  78. "An illegal instruction has been encountered." This corresponds to the
  79. 680x0 illegal instruction trap, and usually indicates a very serious error;
  80. catching this signal is generally unwise.
  81.  
  82. #define SIGTRAP        5
  83. "The single-step trace trap has been encountered." This corresponds to the
  84. 680x0 trace trap, and is usually activated (and handled) by debuggers;
  85. user programs shouldn't catch this.
  86.  
  87. #define SIGABRT        6
  88. "An awful error has occured." This is commonly sent by the abort library
  89. function, and indicates that something has gone very, very wrong (for
  90. example, data structures have been unexpectedly corrupted). It is unlikely
  91. that anything useful can be done after this signal is sent; programs
  92. should not normally catch or ignore SIGABRT.
  93.  
  94. #define SIGPRIV        7
  95. "Privilege violation." An attempt has been made to execute an instruction
  96. in user mode that is normally restricted to supervisor mode; this corresponds
  97. to the 680x0 privilege violation exception, and indicates a serious error.
  98.  
  99. #define SIGFPE        8
  100. "Division by zero or a floating point error has occured." Processes may
  101. ignore or catch this signal (which corresponds to the 680x0 division by zero
  102. trap) and deal with it as they see fit.
  103.  
  104. #define SIGKILL        9        [cannot be blocked or caught]
  105. "Die!" This signal will never be seen by a process; nor can processes
  106. block it. Sending SIGKILL is a way to be sure of killing a run-away
  107. process. Use it only as a last resort, since it gives the process no
  108. chance to clean up and exit gracefully.
  109.  
  110. #define SIGBUS        10
  111. "Bus error." Corresponds to the 680x0 bus error exception, and indicates
  112. a very serious error; programs should generally not attempt to ignore
  113. or catch this signal.
  114.  
  115. #define SIGSEGV        11
  116. "Illegal memory reference." Corresponds to the 680x0 address error
  117. exception, and indicates a very serious error; catching or ignoring this
  118. signal is not recommended.
  119.  
  120. #define SIGSYS        12
  121. "Bad argument to a system call." This signal is sent when an illegal
  122. (usually, out of range) parameter is sent to a system call, and when that
  123. system call does not have any "nice" way to report errors. For example,
  124. Super(0L) when the system is already in supervisor mode causes SIGSYS to
  125. be raised. Note that the kernel does not always detect illegal/out of
  126. range arguments to system calls, only sometimes.
  127.  
  128. #define SIGPIPE        13
  129. "A pipe you were writing to has no readers." Programs may catch this signal
  130. and attempt to exit gracefully after receiving it; note that exiting is
  131. appropriate because the standard output is probably no longer connected
  132. to anything.
  133.  
  134. #define SIGALRM        14
  135. "The alarm you set earlier has happened." This signal is sent to processes
  136. when the alarm clock set by Talarm (q.v.) expires. It's very
  137. common to catch this signal and from the signal handler jump to a known
  138. point in the program; for example, to indicate a timeout while attempting
  139. to communicate over a serial line.
  140.  
  141. #define SIGTERM        15
  142. "Please die." This is a polite form of SIGKILL (#9). Programs should
  143. respect this nice request; they may want to catch the signal to perform
  144. some cleanup actions, but they should then exit (since if they don't,
  145. the user will probably get mad and send SIGKILL later anyway...). This
  146. is the signal that is sent when a process is dragged to the trashcan on
  147. the desktop.
  148.  
  149. #define SIGSTOP        17        [default action: suspend the process]
  150. "Suspend yourself." This signal is sent to a process when it should be
  151. stopped temporarily. SIGSTOP is used primarily by debuggers and similar
  152. programs; suspensions requested directly by the user usually are signalled
  153. by SIGTSTP (q.v.) This signal cannot be ignored, blocked, or caught.
  154.  
  155. #define SIGTSTP        18        [default action: suspend the process]
  156. "The user is asking you to suspend yourself." This signal is sent immediately
  157. when the user presses the control-Z key, and is sent when the process tries
  158. to read a control-Y key in cooked mode (for a delayed stop). In both cases,
  159. the process should suspend itself. Since this is the default action, no
  160. special handling is normally required, although some programs may wish to
  161. save the screen state and restore it when they are unsuspended.
  162.  
  163. #define SIGCONT        19        [default action: continue a stopped
  164.                      process]
  165. "You are being restarted after having been suspended." This signal is
  166. sent by shells to resume a suspended process. If the process is not
  167. suspended, the signal does nothing. This signal cannot be blocked, but
  168. it *is* possible to install a handler for it (this is rarely necessary,
  169. though).
  170.  
  171. #define SIGCHLD        20        [default action: no action taken]
  172. "One of your children has been suspended or has exited." This signal is
  173. sent by the kernel to the parent of any process that is terminated (either
  174. because of a signal or by a Pterm, Pterm0, or Ptermres system call) or
  175. which is suspended because of a signal. Programs that are concerned with the
  176. status of their children (for example, shells) may wish to catch this signal;
  177. after a SIGCHLD has been received, the Pwait3 system call may be
  178. used to determine exactly which child has exited or been suspended.
  179. Note that the Psigaction system call may be used to force SIGCHLD to be
  180. delivered only when a child process terminates (so that suspension of
  181. child processes, for example via job control, does not raise SIGCHLD.
  182.  
  183. #define SIGTTIN        21        [default action: suspended the process]
  184. "Attempt to read from a terminal you don't own." This signal is sent to
  185. any process that attempts to do input from a terminal with a different
  186. process group than their own. Usually, this happens if the user has started
  187. the job in the background; the process will be suspended until the user
  188. explicitly brings it to the foreground with the appropriate shell command
  189. (at which time the shell will reset the terminal's process group and
  190. send the stopped process a SIGCONT signal to tell it to continue).
  191. [NOTE: in fact, SIGTTIN and SIGTTOU are sent to all processes in the same
  192. process group as the process that attempted to do the i/o; this is for
  193. compatibility with Unix, and it simplifies the implementation of job
  194. control shells.]
  195.  
  196. #define SIGTTOU        22        [default action: suspend the process]
  197. "Attempt to write to a terminal that you don't own." Similar to SIGTTIN (q.v.).
  198. Processes should normally respect the user's job control and should
  199. override or ignore SIGTTOU only in situations where a very critical error
  200. has occured and a message must be printed immediately.
  201.  
  202. #define SIGXCPU        24
  203. "Your CPU time limit has been exhausted." Sent to processes when they have
  204. consumed more than the maximum number of milliseconds of CPU time allowed
  205. by the Psetlimit() system call. The signal will continue to be sent to
  206. the process until it exits; if a process does catch this signal, it should
  207. do whatever clean up actions are necessary and then terminate.
  208.  
  209. #define SIGWINCH    28        [default action: no action taken]
  210. "The window you were running in has changed size." This signal is sent
  211. to processes by some window managers to indicate that the user has changed
  212. the size of the window the process is running in. If the process cares
  213. about the window size, it may catch this signal and use an Fcntl call
  214. to inquire about the new window size when the signal is received.
  215. (See the documentation for Fcntl for details.)
  216.  
  217. #define SIGUSR1        29
  218. #define SIGUSR2        30
  219.  
  220. These two signals are reserved for applications, which may define whatever
  221. meaning they wish for them. Note, however, that these signals do
  222. terminate processes by default, so don't send them to a process which
  223. isn't prepared to deal with them.
  224.  
  225.  
  226. System Calls Dealing With Signals
  227.  
  228.  
  229. WORD
  230. Pkill( WORD pid, WORD sig )
  231.  
  232. If pid > 0, then the given signal (see the numbers above) is sent to the
  233. process with that pid.
  234. If pid == 0, then the given signal is sent to all members of the process
  235. group of the process making the Pkill call. This includes, of course,
  236. the process itself.
  237. If pid < 0, the signal is sent to all members of process group (-pid).
  238.  
  239. Returns:
  240. 0     for successful sending of the signal
  241.     (Note that if the current process is a recipient of the signal,
  242.     and the signal proves to be fatal, then Pkill will never return.)
  243. ERANGE    if "sig" is less than 0 or greater than 31
  244. EFILNF    if pid > 0 and the indicated process has terminated or does not
  245.     exist, or if pid < 0 and there are no processes in the given
  246.     process group
  247. EACCDN  if the sending process is not authorized to send signals to
  248.     the specified receiving process or group (for example, they
  249.     belong to different users)
  250.  
  251.  
  252. #define SIG_DFL (0L)
  253. #define SIG_IGN (1L)
  254.  
  255. LONG
  256. Psignal( WORD sig, LONG handler )
  257.  
  258. Change the handling of the indicated signal.
  259.  
  260. If "handler" is SIG_DFL, then the default action for the signal will occur when
  261. the signal is delivered to the current process.
  262.  
  263. If "handler" is SIG_IGN, then the signal will be ignored by the process, and
  264. delivery of the signal will have no noticeable effect (in particular, the
  265. signal will not interrupt the Pause system call, q.v.). If the signal
  266. is pending at the time of the Psignal call, it is discarded.
  267.  
  268. If "handler" is any other value, it is assumed to be the address of a
  269. user function that will be called when the signal is delivered to the
  270. process. The user function is called with a single LONG argument on
  271. the stack, which is the number of the signal being delivered (this is done
  272. so that processes may use the same handler for a number of different
  273. signals). While the signal is being handled, it is blocked from delivery;
  274. thus, signal handling is "reliable" (unlike Version 7 and early System V
  275. Unix implementations, in which delivery of a second signal while it
  276. was being handled could kill the process). Also note that, unlike some
  277. versions of Unix, the signal handling is *not* reset to the default action
  278. before the handler is called; it remains set to the given signal handler.
  279.  
  280. The signal handler must either return (via a normal 680x0 rts instruction)
  281. or call the Psigreturn system call to indicate when signal handling is
  282. complete; in both cases, the signal will be unblocked. Psigreturn also
  283. performs some internal clean-up of the kernel stack that is necessary if
  284. the signal handler is not planning to return (for example, if the C
  285. longjmp() function is to be used to continue execution at another point
  286. in the program).
  287.  
  288. Signal handlers may make any GEMDOS, BIOS, or XBIOS system calls freely.
  289. GEM AES and VDI calls should not be made in a signal handler.
  290.  
  291. Note that calling Psignal to change behavior of a signal has the side
  292. effect of unmasking that signal, so that delivery is possible. This is done
  293. so that processes may, while handling a signal, reset the behavior and
  294. send themselves another instance of the signal, for example in order
  295. to suspend themselves while handling a job control signal.
  296.  
  297. Signal handling is preserved across Pfork and Pvfork calls. Signals
  298. that are ignored by the parent are also ignored by the child after a Pexec
  299. call; signals that were being caught for handling in a function are reset
  300. in the child to the default behavior.
  301.  
  302. Returns:
  303. The old value of handler on success.
  304. ERANGE    if sig < 1 or sig > 31
  305. EACCDN    if sig cannot be caught by the user (i.e. SIGKILL or SIGSTOP)
  306.  
  307. Bugs:
  308. Signal handling can be nested only a small (around 3) number of times,
  309. i.e. if 4 signals are delivered to a process, and the process has established
  310. handlers for all 4, and none of the handlers has returned or called
  311. Psigreturn, then there is a very good chance of a stack overflow killing
  312. the process off. In practice, this is unlikely to happen.
  313.  
  314.  
  315. LONG
  316. Psigblock( LONG amask )
  317.  
  318. Block receipt of some signals. The "amask" argument is added to the
  319. current set of signals being masked, i.e. the new set of blocked signals
  320. is the union of the old set and the set represented by amask. Sets of
  321. blocked signals are represented by a 32 bit unsigned long quantity, with
  322. bit (1L << sig) set if signal "sig" is to be blocked, and clear if not.
  323.  
  324. Blocked signals remain blocked across Pfork and Pvfork calls. For Pexec
  325. calls, children always start out with an empty set of blocked signals,
  326. regardless of which signals are blocked in the parent.
  327.  
  328. Returns:
  329. The old set of blocked signals (i.e. the set as it was before amask
  330. was added to it).
  331.  
  332. NOTE: Certain signals (SIGKILL, SIGSTOP, SIGCONT) cannot be blocked;
  333. if the corresponding bits are set in amask, the kernel will clear them
  334. but will not report an error.
  335.  
  336.  
  337. LONG
  338. Psigsetmask( LONG mask )
  339.  
  340. Decide which signals are to be blocked from delivery. Unlike Psigblock
  341. (which adds to the set of blocked signals) Psigsetmask changes the
  342. entire set, replacing the old set of blocked signals with the one
  343. specified in "mask". As with Psigblock, signal n is blocked from
  344. delivery if bit (1L << n) is set in mask. Note that certain signals
  345. cannot be blocked, and if the corresponding bits are set in the
  346. mask the kernel will clear them.
  347.  
  348. Returns:
  349. The old set of blocked signals.
  350.  
  351. Usage:
  352. Typically, Psigblock and Psigsetmask are used together to temporarily
  353. block signals, e.g.:
  354.  
  355.     oldmask = Psigblock( (1L << SIGINT) );
  356.     ... do some things with SIGINT blocked from delivery ...
  357.     (void) Psigsetmask(oldmask);
  358.  
  359.  
  360.  
  361. LONG
  362. Psigpending()
  363.  
  364. Give an indication of what signals are pending (i.e. have been sent to
  365. the process but not yet delivered, probably because they are blocked
  366. from delivery).
  367.  
  368. Returns:
  369. A 32 bit unsigned long representing the set of signals that are pending.
  370. Signal n is pending if bit (1L << n) is set in the returned value.
  371.  
  372.  
  373. void
  374. Psigreturn()
  375.  
  376. Terminate signal handling. This call should be used by any signal
  377. handler that is not planning to return to the kernel (i.e. if the
  378. handler is going to execute a non-local jump to another point in the
  379. program). It cleans up the signal delivery stack and unblocks the
  380. signal that was being delivered. Calling Psigreturn when no signal
  381. is being delivered is harmless.
  382.  
  383. Bugs:
  384. Calling Psigreturn from a signal handler, and then actually returning
  385. from that handler, is likely to produce extremely unpleasant results.
  386. Don't do it.
  387.  
  388.  
  389. void
  390. Pause()
  391.  
  392. Wait until a signal is delivered. This call will return after any (non-fatal)
  393. signal has been delivered to the process. Note that signals that are being
  394. ignored are never delivered.
  395.  
  396.  
  397. void
  398. Psigpause( LONG mask )
  399.  
  400. Block the set of signals specified by "mask", and then wait until
  401. a signal is delivered. This call will return after any (non-fatal)
  402. signal has been delivered to the process. Before returning, the signal
  403. mask is restored to its original value.
  404.  
  405.  
  406.  
  407. struct sigaction {
  408.     LONG    sa_handler;
  409.     LONG    sa_mask;
  410.     WORD    sa_flags;
  411. #define SA_NOCLDSTOP 1;
  412. }
  413.  
  414. WORD
  415. Psigaction( WORD sig, struct sigaction *act, struct sigaction *act )
  416.  
  417. Like Psignal, this call changes the handling of the indicated signal.
  418. If "act" is non-zero, it is a pointer to a structure which describes
  419. the new signal handling behavior, as follows:
  420.  
  421. sa_handler    is the function to be called when the signal is delivered,
  422.         or SIG_DFL, or SIG_IGN. For further information about
  423.         signal handling functions, see Psignal.
  424. sa_mask        is a set of additional signals to mask while the signal
  425.         is being delivered. The signal itself is always masked,
  426.         but sometimes it might be desireable to mask some
  427.         other signals as well; this allows a "prioritization"
  428.         of signals
  429. sa_flags    extra flags which can affect the behavior of the
  430.         signal. This field should normally be set to 0.
  431.         If "sig" is SIGCHLD and "flags" is SA_NOCLDSTOP,
  432.         then the SIGCHLD signal will not be delivered to
  433.         this process when one of its children are stopped.
  434.  
  435. If "oact" is non-zero, then the old signal handling behavior is
  436. copied into "oact" and returned.
  437.  
  438. Returns:
  439. 0 on success
  440. ERANGE    if sig < 1 or sig > 31
  441. EACCDN    if sig cannot be caught by the user
  442.  
  443. Usage:
  444. If "sig" is a valid signal, the call:
  445.     foo = Psignal(sig, newfunc)
  446. is equivalent to:
  447.     struct sigaction newact, oact;
  448.     newact->sa_mask=0L;
  449.     newact->sa_flags=0;
  450.     newact->sa_handler = newfunc;
  451.     Psigaction(sig, &newact, &oact);
  452.     foo = oact->sa_handler;
  453.  
  454.  
  455. LONG
  456. Talarm( LONG s )
  457.  
  458. If s > 0, schedule a SIGALRM signal to occur in s seconds. This alarm
  459. will replace any previously scheduled alarm.
  460. If s = 0, cancel any previously scheduled alarm.
  461. If s < 0, inquire about a scheduled alarm but do not change it.
  462.  
  463. Returns:
  464. If an alarm was previously scheduled, returns the number of seconds remaining
  465. until that previously scheduled alarm. Otherwise, returns 0.
  466.  
  467. Bugs:
  468. Internal calculations are done in milliseconds, not seconds, so the returned
  469. value is not exactly accurate.
  470. For the same reason, setting an alarm more than 2 million seconds or so
  471. into the future will not work correctly.
  472.