1 / 45

Shells, System Calls, and Signals

Learn about shells, system calls, and signals in Unix systems. Explore different shells like Bourne Shell, C Shell, tcsh, BASH, and Korne Shell. Understand processes, the current working directory, process attributes, creating processes, and switching programs. Discover the importance of shells in managing operating systems efficiently.

jswank
Download Presentation

Shells, System Calls, and Signals

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Shells, System Calls, and Signals

  2. What is a Shell? • A shell is a command line interface to the operating system • Fetch a command from the user and execute the command • Sometimes the commands are built-in to the shell • Other times the commands are external system programs or user programs • There are lots of different shells available in UNIX

  3. Bourne Shell • Historically the sh language was the first to be created and goes under the name of The Bourne Shell • It has a very compact syntax which makes it obtuse for novice users but very efficient when used by experts • It also contains some powerful constructs built in

  4. Bourne Shell • On UNIX systems, most of the scripts used to start and configure the operating system are written in the Bourne shell • It has been around for so long that is virtually bug free

  5. C Shell • The C Shell (csh) • Similar syntactical structures to the C language • The UNIX man pages contain almost twice as much information for the C Shell as the pages for the Bourne Shell, leading most users to believe that it is twice as good

  6. C Shell • Actually, there are several compromises within the C Shell which makes using the language for serious work difficult • (Check the list of bugs at the end of the man pages!).

  7. C Shell • The real reason why the C Shell is so popular is that it is usually selected as the default login shell for most users • The features that guarantee its continued use in this arena are aliases and history lists

  8. tcsh – An Enhanced C Shell • An enhanced but completely compatible version of the Berkeley UNIX C Shell, csh • It is a command language interpreter usable both as an interactive login shell and a shell script command processor • Uses a C-like syntax

  9. tcsh – An Enhanced C Shell • It includes: • Command-line editor • Programmable word completion • Spelling correction • History mechanism • Job control

  10. BASH • GNU Bourne Again Shell • A complete implementation of the IEEE POSIX.2 and Open Group Shell specificaiton with… • Interactive command line editing • Job control on architectures that support it • Csh-like features such as history substitution and brace expansion • …and a slew of other features

  11. Korne Shell • The ksh was made famous by IBM’s AIX version of UNIX • The Korne Shell can be thought of as a superset of the Borne Shell as it contains the whole of the Borne Shell world within its own syntax rules

  12. Processes and the CWD • Every process runs in a directory • The attribute is called the “current working directory” (cwd) • Finding the CWD char *getcwd( char *buf, size_t size ); • Returns a string that contains the absolute pathname of the current working directory • There are functions that can be used to change the current working directory (chdir)

  13. Other Process Attributes • Getting the process id number #include <unistd.h> pid_t getpid( void ); • Getting the group id number gid_t getgid( void ); • Getting the real user ID of a process uid_t getuid( void );

  14. Creating a Process • The only way to create a new process is to issue the fork() system call • Fork() splits the current process into 2 processes, one is called the parent and the other is called the child

  15. Parent and Child Processes • The child process is a copy of the parent process • Same program • Same place in the program • Almost…. • The child process get a new process ID

  16. Process Inheritance • The child process inherits many attributes from the parent including… • Current working directory • User id • Group id

  17. The fork() system call #include <unistd.h> Pid_t fork( void ); • fork() returns a process id (small unsigned integer) • fork() returns twice!!!!!!! • In the parent process, fork returns the id of the child process • In the child, fork returns a 0

  18. Example • #include <unistd.h> • #include <iostream> • using namespace std; • int main( int argc, char *argv[] ) • { • if( fork() ) • cout << "I am the parent" << endl; • else • cout << "I am the child" << endl; • return( 0 ); • }

  19. Bad Example (don’t do this) • #include <unistd.h> // This is called a • #include <iostream> // fork bomb!!!!! • using namespace std; // please don’t do this • int main( int argc, char *argv[] ) • { • while( fork() ) • cout << "I am the parent" << endl; • cout << "I am the child" << endl; • return( 0 ); • }

  20. Switching Programs • fork() is the only way to create a new process • This would be almost useless if there was not a way to switch what program is associated with a process • The exec() system call is used to start a new program

  21. exec() • There are actually a number of exec functions • execlp, execl, execle, execvp, execv, execve • The difference between these functions is the parameters • How the new program is identified and some attributes that should be set

  22. The exec Family • When you call a member of the exec family, you give it the pathname of the executable file that you want to run • If all goes well, exec will never return!!! • The process becomes the new program!!!

  23. Execl() • int execl( char *path, char *arg0, char *arg1, …, char *argN, (char *) 0); execl( “/home/bin/foobar”, “alpha”, “beta”, NULL );

  24. A Complete execl Example • #include <unistd.h> • #include <iostream> • using namespace std; • int main( int argc, char *argv[] ) • { • char buf[ 1000 ]; • cout << "Here are the files in " << getcwd( buf, 1000 ) << endl; • execl( "/bin/ls", "ls", "-al", NULL ); • cout << "If all goes well, this line will not be printed!!!" << endl; • return( 0 ); • }

  25. fork() and exec() Together • The following program does the following: • fork() – results in 2 processes • Parent prints out it’s PID and waits for child process to finish (to exit) • Child process prints out it’s PID and then exec() “ls” and then exits

  26. execandfork.cpp (1) • #include <unistd.h> // exec, fork, getpid • #include <iostream> // cout • #include <sys/types.h> // needed for wait • #include <sys/wait.h> // wait() • using namespace std;

  27. execandfork.cpp (2) • void child( void ) • { • int pid = getpid(); • cout << "CHILD: Child process PID is " << pid << endl; • cout << "CHILD: Child process now ready to exec ls" << endl; • execl( "/bin/ls", "ls", NULL ); • }

  28. execandfork.cpp (3) • void parent( void ) • { • int pid = getpid(); • int stat; • cout << "PARENT: Parent process PID is " << pid << endl; • cout << "PARENT: Parent waiting for child" << endl; • wait( &stat ); • cout << "PARENT: Child is done. Parent returning" << endl; • }

  29. execandfork.cpp (4) • int main( int argc, char *argv[] ) • { • cout << "MAIN: Starting fork system call" << endl; • if( fork() ) • parent(); • else • child(); • cout << "MAIN: Done" << endl; • return( 0 ); • }

  30. execandfork.cpp (output) neptune.cs.kent.edu] {58}% a.out MAIN: Starting fork system call CHILD: Child process PID is 32557 CHILD: Child process now ready to exec ls PARENT: Parent process PID is 32556 PARENT: Parent waiting for child a.out lowcost_DB_NOW.pdf Project 1.pdf asc mail public_html Backup MASC Software bin MPISpawn2 ZephyrDemo hybrid_parallel_system.pdf Parallaxis icp_fall2004_prj4.txt Pictures PARENT: Child is done. Parent returning MAIN: Done neptune.cs.kent.edu] {59}%

  31. A More Concise Example int main() { pid_t pid; /* fork another process */ pid = fork(); if (pid < 0) { /* error occurred */ fprintf(stderr, "Fork Failed"); exit(-1); } else if (pid == 0) { /* child process */ execlp("/bin/ls", "ls", NULL); } else { /* parent process */ /* parent will wait for the child to complete */ wait (NULL); printf ("Child Complete"); exit(0); } }

  32. System Calls for Files and Directories

  33. More System Calls

  34. A Simple Shell while( true ) // repeat forever { type_prompt(); // display prompt read_command( command, parameters ); // input from terminal if( fork() != 0 ) // fork off child process { // parent code waitpid( -1, &status, 0 ); // wait for child to exit } else // child code { execve( command, parameters, 0 ); // execute command } }

  35. Signaling Processes • Signal • A signal is a notification to a process that an event has occurred. Signals are sometimes called “software interrupts”. • Features of Signal • Signal usually occur asynchronously. • The process does not know ahead of time exactly when a signal will occur. • Signal can be sent by one process to another process (or to itself) or by the kernel to a process.

  36. Sources for Generating Signals • Hardware • A process attempts to access addresses outside its own address space. • Divides by zero. • Kernel • Notifying the process that an I/O device for which it has been waiting is available. • Other Processes • A child process notifying its parent process that it has terminated. • User • Pressing keyboard sequences that generate a quit, interrupt or stop signal.

  37. Three Courses of Action • Process that receives a signal can take one of three action: • Perform the system-specified default for the signal • notify the parent process that it is terminating; • generate a core file; • (a file containing the current memory image of the process) • terminate. • Ignore the signal • A process can do ignoring with all signal but two special signals: SIGSTOP and SIGKILL. • Catch the Signal (Trapping) • When a process catches a signal, except SIGSTOP and SIGKILL, it invokes a special signal handing routine.

  38. POSIX-Defined Signals (1) • SIGALRM: Alarm timer time-out. Generated by alarm( ) API. • SIGABRT: Abort process execution. Generated by abort( ) API. • SIGFPE: Illegal mathematical operation. • SIGHUP: Controlling terminal hang-up. • SIGILL: Execution of an illegal machine instruction. • SIGINT: Process interruption. • Can be generated by <Delete> or <ctrl_C> keys. • SIGKILL: Sure kill a process. Can be generated by • “kill -9 <process_id>“ command. • SIGPIPE: Illegal write to a pipe. • SIGQUIT: Process quit. Generated by <crtl_\> keys. • SIGSEGV: Segmentation fault. generated by de-referencing a NULL pointer.

  39. POSIX-Defined Signals (2) • SIGTERM: process termination. Can be generated by • “kill <process_id>” command. • SIGUSR1: Reserved to be defined by user. • SIGUSR2: Reserved to be defined by user. • SIGCHLD: Sent to a parent process when its child process has terminated. • SIGCONT: Resume execution of a stopped process. • SIGSTOP: Stop a process execution. • SIGTTIN: Stop a background process when it tries to read from its controlling terminal. • SIGTSTP: Stop a process execution by the control_Z keys. • SIGTTOUT: Stop a background process when it tries to write to its controlling terminal.

  40. Sending Signals • You may send signals to a process connected to your terminal by typing • ^C SIGINT terminate execution • ^\ SIGQUIT terminate and core dump • ^Z SIGSTOP suspend for later • The terminal driver is a program that processes I/O to the terminal can detect these special character sequences and send the appropriate signal to your interactive shell. • The shell in turn generates an appropriate signal to the foreground process.

  41. Kill • The user can use the csh built-in kill command or use regular UNIX kill command to send a specific signal to a named process. • % kill [-sig] process • If no signal is specified, then SIGTERM (15)(terminate) is assumed • In C/C++ the system call is • #include <signal.h> • int kill( int pid, int sig_id ); • Return values: Success = 0, Failure = -1, Sets errno…YES

  42. Signal Delivery and Processing • When an interrupt or event causes a signal to occur, the signal is added to a set of signals that are waiting for delivery to a process. • Signals are delivered to a process in a manner similar to hardware interrupts.

  43. Signal Delivery • If the signal is not currently blocked by the process, it is delivered to the process following these steps: • The same signal is blocked from further occurrence until delivery and processing are finished • The current process context is saved and a new one built • A handler function associated with the signal is called • If the handler function returns, then the process resumes execution from the point of interrupt, with its saved context restored. Among other things, the signal mask is restored. • Signals have the same priority • But processes can block listening to specific signals via a signal mask

  44. Signal Trapping • The system call signal() is used to trap signals • #include <signal.h> • signal( int sig_id, void * handler() ); • Example: Write a C++ program to count the number of times CTRL-C is pressed at the terminal • cc_counter.cpp

  45. Alarms • Function • The alarm API requests the kernel to send the SIGALRM signal after a certain number of real clock seconds. • #include <signal.h> • int alarm( unsigned int time_interval); • Return: • Success: the number of CPU seconds left in the process timer; Failure: -1; Sets errno: Yes • Argument • time_interval: the number of CPU seconds elapse time. After which the kernel will send the SIGALRM signal to the calling process. • Example: Write a C++ program to set an alarm for signal 5 seconds after process startup and trap the alarm signal. • alarmer.cpp

More Related