* signal handler scope ** signal handler config is at process scope ** no need to reset before exit ** may need to reset after fork * SIGWINCH handling ** display to curses won't persist after endwin / exit ** possibly block all signals and wait for a keypress or timeout ** cleanup curses first and then display msg with stdio ** set the SIGWINCH handler as a one shot handler with all other signals blocked while the handler is running, and do the display/cleanup in the signal handler ** set the SIGWINCH handler as a one shot, no SA_RESTART, set a flag, block all other signals, handle the flag in the main loop, * handling score on paddle bounce ** is ball at the position near the paddle? ** what if the ball hasn't moved away from the paddle yet, but the timer ticks? the ball might _still_ be next to the paddle? ** best to check the current direction as part of detecting a bounce * object access from a signal handler; avoiding globals ** variable must be accessible from the signal handler's function scope without being able to pass it in as an argument ** best practices: 1. declare it at file scope (static global) in the same file as the signal handler function 2. write a singleton pattern for the object static file scope variable in object.c provide getter and setter functions in object.c that allow access to the variable from other files 3. declare the variable at static function scope and hand back a pointer from the function * sigaction review ** the standards page (google "posix sigaction") has an example that shows how to replace signal() with sigaction() on Linux ** you might need to use sigaction in order to register a handler without SA_RESTART in some cases. ** sigaction also allows blocking of other signals. struct sigaction sa; sa.sa_handler = handler; sa.sa_flags = SA_RESTART; sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask, SIGWINCH); if (sigaction(SIGALRM, &sa, NULL) == -1) /* Handle error */; ** if blocking with sigaction is used, there's a greater risk of missing signals if the signal handler does a lot of work * sigprocmask review ** used to block / unblock signals ** enables a much smaller critical section; reduces missed signals ** how it's used sigset_t signal_mask, prev_mask; sigemptyset(&signal_mask); sigaddset(&signal_mask, SIGWINCH); if (sigprocmask(SIG_BLOCK, &signal_mask, &prev_mask) == -1) /* handle error */; /* execute critical section */ if (sigprocmask(SIG_UNBLOCK, &signal_mask, NULL) == -1) /* handle error */; - or - if (sigprocmask(SIG_SETMASK, &prev_mask, NULL) == -1) * randomization ** on linux srandom/random is the same as srand/rand ** according to the srand man page, srand/rand is bad on some other systems, so for portability srandom/random is better ** separate randomization of x and y is important for better game play, gives different angles of ball movement