UNIX System Programming. Overview. 2. Signal Types (31 in POSIX) Signal Sources. Signals. 1. Definition

Similar documents
Signals. CSC209: Software Tools and Systems Programming. Furkan Alaca & Paul Vrbik

CSci 4061 Introduction to Operating Systems. (Advanced Control Signals)

Shell Execution of Programs. Process Groups, Session and Signals 1

Signals. Joseph Cordina

Preview. The pause() System Call. The pause() System Call. The signal() System Call 10/18/2017

Overview. Administrative. * HW 1 grades. * HW 2 Due. Topics. * 5.1 What is a Signal? * Dealing with Signals - masks, handlers

n Unconditionally kill process 8371 n Interactive interrupt key n See /usr/include/bits/signum.h (e.g., SIGKILL 9) 2 -Ken Wong, Sep 2008

Unix System Programming - Chapter 8

CS213. Exceptional Control Flow Part II. Topics Process Hierarchy Signals

CS 33. Signals Part 1. CS33 Intro to Computer Systems XXII 1 Copyright 2017 Thomas W. Doeppner. All rights reserved.

Signals and Signal Handling - Part 2

Acontecimentos assíncronos (POSIX signals) Sincronização com múltiplos acontecimentos

Lesson 3. The func procedure allows a user to choose the action upon receipt of a signal.

Chapter 5. TCP Client-Server

IMPLEMENTATION OF SIGNAL HANDLING. CS124 Operating Systems Fall , Lecture 15

Process. Signal #8. Signals are software interrupts from unexpected events. a power failure. an alarm clock. the death of a child process

CSC209H Lecture 8. Dan Zingaro. March 4, 2015

Preview. Process Termination. wait and waitpid() System Call. wait and waitpid() System Call. waitpid() System Call 10/23/2018

CSE 421: Introduction to Operating Systems

CS24: INTRODUCTION TO COMPUTING SYSTEMS. Spring 2017 Lecture 19

Signals. Goals of this Lecture. Help you learn about: Sending signals Handling signals

A read or write being atomic means that its effect is as if it happens instantaneously.

Signals are a kernel-supported mechanism for reporting events to user code and forcing a response to them. There are actually two sorts of such

Embedded Systems Programming

Exceptional Control Flow Exists at All Levels of a System. Systemprogrammering 2007 Föreläsning 3 Exceptional Control Flow Part II

系統程式 郭大維教授 / 施吉昇教授臺灣大學資訊工程系

ECF Exists at All Levels of a System Exceptional Control Flow Part II Oct. 22, 2002 Topics! Process Hierarchy! Shells! Signals!

KING FAHD UNIVERSITY OF PETROLEUM AND MINERALS Information and Computer Science Department ICS 431 Operating Systems Lab # 6

Signals. Jin-Soo Kim Computer Systems Laboratory Sungkyunkwan University

Operating Systems 2010/2011

System Programming 熊博安國立中正大學資訊工程學系

Processes. Processes (cont d)

Lecture 4. Introduction to Unix Processes. Introduction to Systems Programming: Processes and Signals

Exceptional Control Flow Part II

Advanced Unix/Linux System Program. Instructor: William W.Y. Hsu

System Programming. Signals I

CSCI 4061: Signals and Signal Handlers

Giving credit where credit is due

Goals of this Lecture

Princeton University. Computer Science 217: Introduction to Programming Systems. Signals

Exceptional Control Flow Part II Nov. 2, 2009"

CS631 - Advanced Programming in the UNIX Environment. Process Groups, Sessions, Signals

CS24: INTRODUCTION TO COMPUTING SYSTEMS. Spring 2018 Lecture 18

Signals and Session Management. Signals. Mechanism to notify processes of system events

Workshop on Inter Process Communication Solutions

Exceptions, Processes and Signals

Signals! Goals of this Lecture! Help you learn about:" Sending signals" Handling signals"

Signals! Goals of this Lecture! Help you learn about:" Sending signals" Handling signals"

Signals: Management and Implementation. Sanjiv K. Bhatia Univ. of Missouri St. Louis

Operating Systems. Threads and Signals. Amir Ghavam Winter Winter Amir Ghavam

System Calls & Signals. CS449 Spring 2016

Computer Science & Engineering Department I. I. T. Kharagpur. Operating System: CS rd Year CSE: 5th Semester (Autumn ) Lecture VII

CS240: Programming in C

Signals. POSIX defines a variety of signal types, each for a particular

Exceptional Control Flow: Signals

So far, we know how to create processes. How do we communicate with them? Primary mechanism: signals

signals Communicating with the OS System call (last lecture) Signal (this lecture) User Process Operating System

Multitasking. Programmer s model of multitasking. fork() spawns new process. exit() terminates own process

Exceptional Control Flow: Signals and Nonlocal Jumps

Processes & Signals. System Runs Many Processes Concurrently. State consists of memory image + register values + program counter

System Calls and Signals: Communication with the OS. System Call. strace./hello. Kernel. Context Switch

Signal Example 1. Signal Example 2

Lecture 4. Introduction to make Debugging with gdb and ddd Introduction to Systems Programming: Processes and Signals

Systems Programming/ C and UNIX

Shell and Signals. Computer Organization 3/17/2015. CSC252 - Spring The World of Multiprogramming or Multitasking. Unix Process Hierarchy

Overview. POSIX signals. Generation of signals. Handling signals. Some predefined signals. Real-time Systems D0003E 3/3/2009

Programming Assignments will be.. All the PAs are continuous 3 major factors that you should consider

Interprocess Communication

Lecture 7: Signals and Events. CSC 469H1F Fall 2006 Angela Demke Brown

Introduction. Interprocess communication. Terminology. Shared Memory versus Message Passing

an infinite loop Processes and Exceptions doing nothing on a busy system timing nothing

System Programming. Signals II

CS 3733 Operating Systems

ECE 650 Systems Programming & Engineering. Spring 2018

Operating Systemss and Multicore Programming (1DT089)

Linux Signals and Daemons

Signals, Synchronization. CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Other Interprocess communication (Chapter 2.3.8, Tanenbaum)

Networks and Opera/ng Systems Chapter 14: Synchroniza/on

Signal types (some of them) Networks and Operating Systems ( ) Chapter 5: Memory Management. Where do signals come from?

CS24: INTRODUCTION TO COMPUTING SYSTEMS. Spring 2018 Lecture 20

Kernel and processes

PVPSIDDHARTHA INSTITUTE OF TECHNOLOGY

Recitation Processes, Signals,UNIX error handling

CSE410 Operating Systems Spring 2018 Project 1: Introduction to Unix/Linux Signals

Operating Systems. No. 5 ศร ณย อ นทโกส ม Sarun Intakosum

Processes, Signals, I/O, Shell Lab : Introduc>on to Computer Systems Recita>on 9: Monday, Oct. 21, 2013 Marjorie Carlson Sec>on A

Lecture 24: Multitasking and Signals

CS170 Operating Systems. Discussion Section Week 4 Project 2 - Thread

Inter-process communication (IPC)

CSE 410: Computer Systems Spring Processes. John Zahorjan Allen Center 534

UNIT III - APPLICATION DEVELOPMENT. TCP Echo Server

COMP 2400 UNIX Tools

Recitation 8 Processes, Signals, Tshlab

Signals. 5February :09

Lecture 4 Threads. (chapter 4)

Semester 2, Computer Communication 352 Module 4

Process management. What s in a process? What is a process? The OS s process namespace. A process s address space (idealized)

CSE 451: Operating Systems Winter Module 4 Processes. Mark Zbikowski Allen Center 476

Last time: Scheduling. Goals today. Recap: Hardware support for synchronization. Disabling interrupts. Disabling interrupts

Transcription:

UNIX System Programming Signals Objectives Introduce signals Concentrate on sigaction() function 1730 UNIX System Programming Signals Maria Hybinette 1 Overview 1. Definition 2. Signal Types 3. Generating a Signal 4. Responding to a Signal 5. Common Uses of Signals 6. Implementing a read() Timeout 1730 UNIX System Programming Signals Maria Hybinette 2 7. POSIX Signal Functions 8. Interrupted System Calls 9. System Calls inside Handlers 10. More Information 1. Definition A signal is an asynchronous event which is delivered to a process. Asynchronous means that the event can occur at any time may be unrelated to the execution of the process e.g. user types ctrl-c,, or the modem hangs 1730 UNIX System Programming Signals Maria Hybinette 3 1730 UNIX System Programming Signals Maria Hybinette 4 2. Signal Types (31 in POSIX) Name Description SIGINT Interrupt character typed SIGQUIT Quit character typed (^\)( SIGKILL kill -9 SIGSEGV Invalid memory reference SIGPIPE Write on pipe but no reader SIGALRM alarm() clock rings SIGUSR1 user-defined signal type SIGUSR2 user-defined signal type See man 7 signal Default Action terminate process create core image terminate process create core image terminate process terminate process terminate process terminate process 1730 UNIX System Programming Signals Maria Hybinette 5 Signal Sources shell command window manager SIGKILL SIGWINCH terminal driver SIGINT a process memory management SIGHUP SIGQUIT SIGPIPE SIGALRM SIGUSR1 kernel other user processes 1730 UNIX System Programming Signals Maria Hybinette 6

3. Generating a Signal Use the UNIX command $ kill -KILL 4481 send a SIGKILL signal to pid 4481 check ps l to make sure process died kill is not a good name; send_signal might be better. 1730 UNIX System Programming Signals Maria Hybinette 7 kill() Send a signal to a process (or group of processes). #include <signal.h< signal.h> int kill( pid_t pid, int signo ); Return 0 if ok, -11 on error. 1730 UNIX System Programming Signals Maria Hybinette 8 Some pid Values pid Meaning > 0 send signal to process pid == 0 send signal to all processes whose process group ID equals the sender s pgid. e.g. parent kills all children 1730 UNIX System Programming Signals Maria Hybinette 9 4. Responding to a Signal A process can ignore/discard the signal (not possible with SIGKILL or SIGSTOP) execute a signal handler function, and then possibly resume execution or terminate carry out the default action for that signal The choice is called the process signal disposition 1730 UNIX System Programming Signals Maria Hybinette 10 signal() library call Specify a signal handler function to deal with a signal type. #include <signal.h> typedef void Sigfunc(int); /* my defn */ Sigfunc *signal( int signo, Sigfunc *handler ); signal returns a pointer to a function that returns an int (i.e. it returns a pointer to Sigfunc Returns previous signal disposition if ok, SIG_ERR on error. Actual Prototype The actual prototype, listed in the man page is a bit perplexing but is an expansion of the Sigfunc type void (*signal(int signo, void(*handler)(int)))(int); In Linux typedef void (*sighandler_t)(int); sig_handler_t signal(int signo, sighandler_t handler); Signal returns a pointer to a function that returns an int 1730 UNIX System Programming Signals Maria Hybinette 11 1730 UNIX System Programming Signals Maria Hybinette 12

The signal function itself returns Signal a pointer to Handling a function. The return type is the same as the function that is passed The signal in, to be The handler function i.e., a Use function the signal that handling takes caught library an signal.h or ignored Receives a single integer int and returns a void is given as argument Argument and returns void Then can use the signal call #include <signal.h> sig void (*signal( int sig, void (*handler)(int))) (int) ; signal returns a pointer to the PREVIOUS signal handler The function to be called Signal #include is a function <signal.h> when the specified signal typedef void Sigfunc(int); /* my defn */ that takes Sigfunc two*signal( int signo, is Sigfunc received The *handler is returned given ); as function a arguments pointer to takes the function a integer sig and handler handler parameter. 1730 UNIX System Programming Signals Maria Hybinette 13 Example signal( SIGINT, foo ); /* do usual things until SIGINT */ return 0; void foo( int signo ) /* deal with SIGINT signal */ return; /* return to program */ 1730 UNIX System Programming Signals Maria Hybinette 14 sig_examp.c #include <stdio.h> #include <unistd.h> #include <signal.h> void sig_usr( int signo ); /* handles two signals */ int i = 0; if( signal( SIGUSR1,sig_usr ) == SIG_ERR ) printf( Cannot catch SIGUSR1\n ); if( signal( SIGUSR2,sig_usr ) == SIG_ERR ) printf( Cannot catch SIGUSR2\n ); while(1) printf( %2d\n, I ); pause(); /* pause until signal handler * has processed signal */ i++; return 0; 1730 UNIX System Programming Signals Maria Hybinette 15 1730 UNIX System Programming Signals Maria Hybinette 16 void sig_usr( int signo ) /* argument is signal number */ if( signo == SIGUSR1 ) printf( Received SIGUSR1\n ); else if( signo == SIGUSR2 ) printf( Received SIGUSR2\n ); else printf( Error received signal %d\n, signo); return; 1730 UNIX System Programming Signals Maria Hybinette 17 Usage $ sig_examp & [1] 4720 0 $ kill -USR1 4720 Received SIGUSR1 1 $ kill -USR2 4720 Received SIGUSR2 2 $ kill 4720 /* send SIGTERM */ [1] + Terminated sig_examp & $ 1730 UNIX System Programming Signals Maria Hybinette 18

Special Sigfunc * Values Value SIG_IGN SIG_DFL SIG_ERR Meaning Ignore / discard the signal. Use default action to handle signal. Returned by signal() as an error. 1730 UNIX System Programming Signals Maria Hybinette 19 Multiple Signals If many signals of the same type are waiting to be handled (e.g. two SIGINTs), then most UNIXs will only deliver one of them. the others are thrown away If many signals of different types are waiting to be handled (e.g. a SIGINT, SIGSEGV, SIGUSR1), they are not delivered in any fixed order. 1730 UNIX System Programming Signals Maria Hybinette 20 pause() Suspend the calling process until a signal is caught. #include <unistd.h> int pause(void); Returns -11 with errno assigned EINTR. (Linux assigns it ERESTARTNOHAND). pause() only returns after a signal handler has returned. The Reset Problem In Linux (and many other UNIXs), the signal disposition in a process is reset to its default action immediately after the signal has been delivered. Must call signal() again to reinstall the signal handler function. 1730 UNIX System Programming Signals Maria Hybinette 21 1730 UNIX System Programming Signals Maria Hybinette 22 Reset Problem Example signal(sigint, foo); /* do usual things until SIGINT */ void foo(int signo) signal(sigint, foo); /* reinstall */ return; 1730 UNIX System Programming Signals Maria Hybinette 23 Reset Problem void ouch( int sig ) printf( "OUCH! - I got signal %d\n", sig ); (void) signal(sigint, ouch); while(1) To keep catching the signal with this function, must call the signal system call again. Problem from the time that the interrupt function starts to just before the signal handler is re-established (void) signal( SIGINT, ouch ); the signal will not be handled. printf("hello World!\n"); sleep(1); If another SIGINT signal is received during this time, default behavior will be done, 1730 UNIX System Programming Signals Maria Hybinette i.e., program will terminate. 24

Re-installation may be too slow! There is a (very) small time period in foo() when a new SIGINT signal will cause the default action to be carried out -- process termination. With signal() there is no answer to this problem. POSIX signal functions solve it (and some other later UNIXs) 1730 UNIX System Programming Signals Maria Hybinette 25 5. Common Uses of Signals 5.1. Ignore a Signal 5.2. Clean up and Terminate 5.3. Dynamic Reconfiguration 5.4. Report Status 5.5. Turn Debugging on/off 5.6. Restore Previous Handler 1730 UNIX System Programming Signals Maria Hybinette 26 5.1. Ignore a Signal signal(sigint,, SIG_IGN); signal(sigquit,, SIG_IGN); /* do work without interruptions */ Cannot ignore/handle SIGKILL or SIGSTOP Should check for SIG_ERR 1730 UNIX System Programming Signals Maria Hybinette 27 5.2. Clean up and Terminate /* global variables */ int my_children_pids; void clean_up(int signo); signal(sigint, clean_up); 1730 UNIX System Programming Signals Maria Hybinette 28 void clean_up(int signo) unlink( /tmp tmp/work-file ); kill(my_children_pids,, SIGTERM); wait((int *)0); fprintf(stderr, Program terminated\n ); n ); exit(1); Problems If a program is run in the background then the interrupt and quit signals (SIGINT( SIGINT, SIGQUIT) ) are automatically ignored. Your code should not override these changes check if the signal dispositions are SIG_IGN 1730 UNIX System Programming Signals Maria Hybinette 29 1730 UNIX System Programming Signals Maria Hybinette 30

Checking the Disposition new disposition old disposition if( signal(sigint,, SIG_IGN )!= SIG_IGN ) signal(sigint, clean_up); if( signal(sigquit,, SIG_IGN )!= SIG_IGN ) signal(sigquit, clean_up); Note cannot check the signal disposition without changing it (sigaction( that we will look at later, is different) 1730 UNIX System Programming Signals Maria Hybinette 31 5.3. Dynamic Reconfiguration void read_config(int signo); read_config(0); /* dummy argument */ while (1) /* work forever */ 1730 UNIX System Programming Signals Maria Hybinette 32 void read_config(int signo) int fd; signal( SIGHUP, read_config ); fd = open( config_file, O_RDONLY); /* read file and set global vars */ close(fd); return; Problems Reset problem Handler interruption what is the effect of a SIGHUP in the middle of read_config() s execution? Can only affect global variables. 1730 UNIX System Programming Signals Maria Hybinette 33 1730 UNIX System Programming Signals Maria Hybinette 34 5.4. Report Status void print_status(int signo); int count; /* global */ signal(sigusr1, print_status); for( count=0; count < BIG_NUM; count++ ) /* read block from tape */ /* write block to disk */... 1730 UNIX System Programming Signals Maria Hybinette 35 void print_status(int signo) signal(sigusr1, print_status); printf( %d blocks copied\n, count); return; Reset problem count value not always defined. Must use global variables for status information 1730 UNIX System Programming Signals Maria Hybinette 36

5.5. Turn Debugging on/off void toggle_debug(int signo); int debug = 0; /* initialize here */ signal(sigusr2, toggle_debug); /* do work */ if (debug == 1) printf(... );... 1730 UNIX System Programming Signals Maria Hybinette 37 void toggle_debug(int signo) signal(sigusr2, toggle_debug); debug = ((debug == 1)? 0 1); return; 1730 UNIX System Programming Signals Maria Hybinette 38 5.6. Restore Previous Handler Sigfunc *old_hand; /* set action for SIGTERM; save old handler */ old_hand = signal(sigterm, foobar); /* do work */ /* restore old handler */ signal(sigterm, old_hand); 1730 UNIX System Programming Signals Maria Hybinette 39 6. Implementing a read() Timeout Put an upper limit on an operation that might block forever e.g. read() 6.1. alarm() 6.2. Bad read() Timeout 6.3. setjmp() and longjmp() 6.4. Better read() Timeout 1730 UNIX System Programming Signals Maria Hybinette 40 6.1. alarm() Set an alarm timer that will ring after a specified number of seconds a SIGALRM signal is generated #include <unistd.h< unistd.h> long alarm(long secs); Returns 0 or number of seconds until previously set alarm would have rung. 1730 UNIX System Programming Signals Maria Hybinette 41 Some Tricky Aspects A process can have at most one alarm timer running at once. If alarm() is called when there is an existing alarm set then it returns the number of seconds remaining for the old alarm, and sets the timer to the new alarm value. What do we do with the old alarm value? An alarm(0) call causes the previous alarm to be cancelled. 1730 UNIX System Programming Signals Maria Hybinette 42

6.2. Bad read() Timeout #include <stdio.h> #include <unistd.h> #include <signal.h> #define MAXLINE 512 void sig_alrm( int signo ); int n; char line[maxline]; 1730 UNIX System Programming Signals Maria Hybinette 43 if( signal(sigalrm, sig_alrm) == SIG_ERR ) printf( signal(sigalrm) error\n ); exit(1); alarm(10); n = read( 0, line, MAXLINE ); alarm(0); if( n < 0 ) /* read error */ fprintf( stderr, \nread error\n ); else write( 1, line, n ); return 0; 1730 UNIX System Programming Signals Maria Hybinette 44 void sig_alrm(int signo) /* do nothing, just handle signal */ return; Problems The code assumes that the read() call terminates with an error after being interrupted ( talk about this later). Race Conditon The kernel may take longer than 10 seconds to start the read() after the alarm() call. the alarm may ring before the read() starts then the read() is not being timed; may block forever Two ways two solve this one uses setjmp and the other uses sigprocmask and sigsuspend 1730 UNIX System Programming Signals Maria Hybinette 45 1730 UNIX System Programming Signals Maria Hybinette 46 6.3. setjmp() and longjmp() In C we cannot use goto to jump to a label in another function use setjmp() and longjmp() for those long jumps Only uses which are good style error handling which requires a deeply nested function to recover to a higher level (e.g. back to main()) coding timeouts with signals Prototypes #include <setjmp.h< setjmp.h> int setjmp( jmp_buf env ); Returns 0 if called directly, non-zero if returning from a call to longjmp() (). #include <setjmp.h< setjmp.h> void longjmp( jmp_buf env, int val ); 1730 UNIX System Programming Signals Maria Hybinette 47 1730 UNIX System Programming Signals Maria Hybinette 48

Behavior In the setjmp() call, env is initialized to information about the current state of the stack. The longjmp() call causes the stack to be reset to its env value. Execution restarts after the setjmp() call, but this time setjmp() returns val. 1730 UNIX System Programming Signals Maria Hybinette 49 Example jmp_buf env; /* global */ char line[max]; int errval; if(( errval = setjmp(env) )!= 0 ) printf( error %d restart\n, errval ); while( fgets( line, MAX, stdin )!= NULL ) process_line(line); return 0; 1730 UNIX System Programming Signals Maria Hybinette 50 void process_line( char * ptr ) cmd_add() void cmd_add() int token; token = get_token(); if( token < 0 ) /* bad error */ longjmp( env, 1 ); /* normal processing */ int get_token() if( some error ) longjmp( env, 2 ); Stack Frames at setjmp() direction of stack growth top of stack main() stack frame setjmp(env) returns 0; env records stack frames info 1730 UNIX System Programming Signals Maria Hybinette 51 1730 UNIX System Programming Signals Maria Hybinette 52 Stack Frames at longjmp() direction of stack growth top of stack main() stack frame process_line() stack frame cmd_add() stack frame longjmp(env,1) causes stack frames to be reset 1730 UNIX System Programming Signals Maria Hybinette 53 sleep1() #include <signal.h> #include <unistd.h> void sig_alrm( int signo ) return; /* return to wake up pause */ unsigned int sleep1( unsigned int nsecs ) if( signal( SIGALRM, sig_alrm ) == SIG_ERR ) return (nsecs); alarm( nsecs ); /* starts timer */ pause(); /* next caugt signal wakes */ return( alarm( 0 ) ); /* turn off timer, return unslept * time */ 1730 UNIX System Programming Signals Maria Hybinette 54

sleep2() static void jmp_buf env_alrm; void sig_alrm( int signo ) longjmp( env_alrm, 1 ); unsigned int sleep2( unsigned int nsecs ) if( signal( SIGALRM, sig_alrm ) == SIG_ERR ) return (nsecs); if( setjmp( env_alrm) == 0 ) alarm( nsecs ); /* starts timer */ pause(); /* next caugt signal wakes return( alarm( 0 ) ); 1730 UNIX System Programming Signals Maria Hybinette 55 Sleep1 and Sleep2 Sleep2 fixes race condition. Even if the pause is never executed. There is one more problem (will talk about that after fixing the earlier read function ) 1730 UNIX System Programming Signals Maria Hybinette 56 Status of Variables? The POSIX standard says global and static variable values will not be changed by the longjmp() call Nothing is specified about local variables, are they rolled back to their original values (at the setjmp call) as the stack? they may be restored to their values at the first setjmp(),, but maybe not Most implementations do not roll back their values 1730 UNIX System Programming Signals Maria Hybinette 57 6.4. Better read() Timeout #include <stdio.h> #include <unistd.h> #include <setjmp.h> #include <signal.h> #define MAXLINE 512 void sig_alrm( int signo ); jmp_buf env_alrm; int n; char line[maxline]; 1730 UNIX System Programming Signals Maria Hybinette 58 if( signal(sigalrm, sig_alrm) == SIG_ERR) printf( signal(sigalrm) error\n ); exit(1); if( setjmp(env_alrm)!= 0 ) fprintf(stderr, \nread() too slow\n ); exit(2); alarm(10); n = read(0, line, MAXLINE); alarm(0); 1730 UNIX System Programming Signals Maria Hybinette 59 if( n < 0 ) /* read error */ fprintf( stderr, \nread error\n ); else write( 1, line, n ); return 0; 1730 UNIX System Programming Signals Maria Hybinette 60

Caveat Non-local Jumps void sig_alrm(int signo) /* interrupt the read() and jump to setjmp() call with value 1 */ longjmp(env_alrm, 1); From the UNIX man pages WARNINGS If longjmp() or siglongjmp() are called even though env was never primed by a call to setjmp() or sigsetjmp(), or when the last such call was in a function that has since returned, absolute chaos is guaranteed. 1730 UNIX System Programming Signals Maria Hybinette 61 1730 UNIX System Programming Signals Maria Hybinette 62 A Problem Remains! If the program has several signal handlers then execution might be inside one when an alarm rings the longjmp() call will jump to the setjmp() location, and abort the other signal handler -- might lose / corrupt data 7. POSIX Signal Functions The POSIX signal functions can control signals in more ways can block signals for a while, and deliver them later (good for coding critical sections) can switch off the resetting of the signal disposition when a handler is called (no reset problem) 1730 UNIX System Programming Signals Maria Hybinette 63 1730 UNIX System Programming Signals Maria Hybinette 64 The POSIX signal system, uses signal sets,, to deal with pending signals that might otherwise be missed while a signal is being processed 7.1. Signal Sets The signal set stores collections of signal types. Sets are used by signal functions to define which signal types are to be processed. POSIX contains several functions for creating, changing and examining signal sets. 1730 UNIX System Programming Signals Maria Hybinette 65 1730 UNIX System Programming Signals Maria Hybinette 66

Prototypes #include <signal.h> int sigemptyset( sigset_t *set ); int sigfillset( sigset_t *set ); int sigaddset( sigset_t *set, int signo ); int sigdelset( sigset_t *set, int signo ); int sigismember( const sigset_t *set, int signo ); 1730 UNIX System Programming Signals Maria Hybinette 67 7.2. sigprocmask() A process uses a signal set to create a mask which defines the signals it is blocking from delivery. good for critical sections where you want to block certain signals. #include <signal.h> int sigprocmask( int how, const sigset_t *set, sigset_t *oldset); how indicates how mask is modified 1730 UNIX System Programming Signals Maria Hybinette 68 how Meanings Value SIG_BLOCK Meaning set signals are added to mask A Critical Code Region sigset_t newmask, oldmask; sigemptyset( &newmask ); sigaddset( &newmask, SIGINT ); SIG_UNBLOCK SIG_SETMASK set signals are removed from mask set becomes new mask /* block SIGINT; save old mask */ sigprocmask( SIG_BLOCK, &newmask, &oldmask ); /* critical region of code */ 1730 UNIX System Programming Signals Maria Hybinette 69 /* reset mask which unblocks SIGINT */ sigprocmask( SIG_SETMASK, &oldmask, NULL ); 1730 UNIX System Programming Signals Maria Hybinette 70 7.3. sigaction() Supercedes (more powerful than) signal() sigaction() can be used to code a non- resetting signal() #include <signal.h> int sigaction(int signo, const struct sigaction *act, struct sigaction *oldact ); 1730 UNIX System Programming Signals Maria Hybinette 71 sigaction Structure struct sigaction void (*sa_handler)( int ); /* action to be taken or SIG_IGN, SIG_DFL */ sigset_t sa_mask; /* additional signal to be blocked */ int sa_flags; /* modifies action of the signal */ void (*sa_sigaction)( int, siginfo_t *, void * ); sa_flags SIG_DFL reset handler to default upon return SA_SIGINFO denotes extra information is passed to handler (.i.e. specifies the use of the second handler in the structure. 1730 UNIX System Programming Signals Maria Hybinette 72

sigaction() Behavior A signo signal causes the sa_handler signal handler to be called. While sa_handler executes, the signals in sa_mask are blocked. Any more signo signals are also blocked. sa_handler remains installed until it is changed by another sigaction() call. No reset problem. 1730 UNIX System Programming Signals Maria Hybinette 73 Signal Raising struct sigaction act; act.sa_handler = ouch; sigemptyset( &act.sa_mask ); act.sa_flags = 0; struct sigaction void (*) (int) sa_handler sigset_t sa_mask int sa_flags Set the signal handler to be the function ouch sigaction( SIGINT, &act, 0 No ); flags are needed here. We can manipulate Possible flags include while(1) sets of signals.. SA_NOCLDSTOP SA_RESETHAND printf("hello World!\n"); SA_RESTART sleep(1); This call sets SA_NODEFER the signal handler for the SIGINT (ctrl-c) signal 1730 UNIX System Programming Signals Maria Hybinette 74 Signal Raising This function will continually capture the ctrl-c C (SIGINT) signal. Default behavior is not restored after signal is caught. To To terminate the program, must type ctrl-\, the SIGQUIT signal. sigexpos.c /* sigexpos.c - demonstrate sigaction() */ /* include files as before */ int main(void) /* struct to deal with action on signal set */ static struct sigaction act; void catchint(int); /* user signal handler */ /* set up action to take on receipt of SIGINT */ act.sa_handler = catchint; 1730 UNIX System Programming Signals Maria Hybinette 75 1730 UNIX System Programming Signals Maria Hybinette 76 /* create full set of signals */ sigfillset(&(act.sa_mask)); /* before sigaction call, SIGINT will terminate * process */ /* now, SIGINT will cause catchint to be executed */ sigaction( SIGINT, &act, NULL ); sigaction( SIGQUIT, &act, NULL ); printf("sleep call #1\n"); sleep(1); /* rest of program as before */ Signals - Ignoring signals Other than SIGKILL and SIGSTOP, signals can be ignored Instead of in the previous program act.sa_handler = catchint /* or whatever */ We use act.sa_handler = SIG_IGN; The ^C key will be ignored 1730 UNIX System Programming Signals Maria Hybinette 77 1730 UNIX System Programming Signals Maria Hybinette 78

Restoring previous action The third parameter to sigaction, oact,, can be used /* save old action */ sigaction( ( SIGTERM, NULL, &oact ); /* set new action */ act.sa_handler = SIG_IGN; sigaction( ( SIGTERM, &act, NULL ); /* restore old action */ sigaction( ( SIGTERM, &oact,, NULL ); 1730 UNIX System Programming Signals Maria Hybinette 79 A Basic signal() #include <signal.h> Sigfunc *signal( int signo, Sigfunc *func ) struct sigaction act, oact; act.sa_handler = func; sigemptyset( &act.sa_mask ); act.sa_flags = 0; act.sa_flags = SA_INTERRUPT; if( signo!= SIGALRM ) act.sa_flags = SA_RESTART; /* any system call interrupted by a signal * other than alarm is restarted */ if( sigaction( signo, &act, &oact) < 0 ) return(sig_err); return( oact.sa_handler ); 1730 UNIX System Programming Signals Maria Hybinette 80 7.4. Other POSIX Functions sigpending() examine blocked signals sigsetjmp() siglongjmp() jump functions for use in signal handlers which handle masks correctly sigsuspend() atomically reset mask and sleep [sig]longjmp & [sig]setjmp[ NOTES (longjmp( longjmp, sigjmp) POSIX does not specify whether longjmp will restore the signal context. If you want to save and restore signal masks,, use siglongjmp. NOTES (setjmp( setjmp, sigjmp) POSIX does not specify whether setjmp will save the signal context. (In SYSV it will not. In BSD4.3 it will, and there is a function _setjmp_ that will not.) If you want to save signal masks, use sigsetjmp. 1730 UNIX System Programming Signals Maria Hybinette 81 1730 UNIX System Programming Signals Maria Hybinette 82 Example #include <stdio.h> #include <signal.h> #include <setjmp.h> sigjmp_buf buf; void handler(int sig) siglongjmp(buf, 1); main() signal(sigint, handler); if( sigsetjmp(buf, 1) == 0 ) printf("starting\n"); else while(1) sleep(5); printf( \n"); > a.out starting restarting Control-c restarting Control-c printf("restarting\n") restarting Control-c ; 1730 UNIX System Programming Signals Maria Hybinette 83 8. Interrupted System Calls When a system call (e.g. read()) ) is interrupted by a signal, a signal handler is called, returns, and then what? On many UNIXs, slow system function calls do not resume. Instead they return an error and errno is assigned EINTR. true of Linux, but can be altered with (Linux-specific) siginterrupt() 1730 UNIX System Programming Signals Maria Hybinette 84

Slow System Functions Slow system functions carry out I/O on things that can possibly block the caller forever pipes, terminal drivers, networks some IPC functions pause(),, some uses of ioctl() Non-slow System Functions Most system functions are non-slow, including ones that do disk I/O e.g. read() of a disk file read() is sometimes a slow function, sometimes not Some UNIXs resume non-slow system functions after the handler has finished. Can use signals on slow system functions to code up timeouts (e.g. did earlier ) 1730 UNIX System Programming Signals Maria Hybinette 85 Some UNIXs only call the handler after the non- slow system function call has finished. 1730 UNIX System Programming Signals Maria Hybinette 86 9. System Calls inside Handlers If a system function is called inside a signal handler then it may interact with an interrupted call to the same function in the main code. e.g. malloc() This is not a problem if the function is reentrant a process can contain multiple calls to these functions at the same time e.g. read(), write(), fork(),, many more 1730 UNIX System Programming Signals Maria Hybinette 87 Non-reentrant Functions A functions may be non-reentrant (only one call to it at once) for a number of reasons it uses a static data structure it manipulates the heap malloc() (), free(),, etc. it uses the standard I/O library e,g, scanf() (), printf() the library uses global data structures in a non-reentrant way 1730 UNIX System Programming Signals Maria Hybinette 88 errno Problem errno is usually represented by a global variable. Its value in the program can be changed suddenly by a signal handler which produces a new system function error. 1730 UNIX System Programming Signals Maria Hybinette 89