System Programming Project 2 Due : 4/19...?. Foreground & Background Foreground job Foreground job Only one at moment Only one at moment Having user’s

Embed Size (px)

Text of System Programming Project 2 Due : 4/19...?. Foreground & Background Foreground job Foreground job...

  • Slide 1
  • System Programming Project 2 Due : 4/19...?
  • Slide 2
  • Foreground & Background Foreground job Foreground job Only one at moment Only one at moment Having users focus Having users focus Background job Background job Many jobs running in background Many jobs running in background They are totally inpendent They are totally inpendent No focus No focus FG BG BG BG
  • Slide 3
  • FG & BG & Stopped in Unix BG FG Stopped Ctrl+Z fgbg fg cmd& cmd
  • Slide 4
  • FG & BG & Stopped Example >parrot hi 01-hi02-hi>jobs [1] Stopped parrot hi >bg 1 >03-hi 04-hi>ls hello.c abc.txt shell >05-hi 06-hi Ctrl+Z >parrot hi & >01-hi 02-hi>jobs [1] Running parrot hi & >03-hi 04-hi >fg 1 05-hi...10-hi> Ex.1Ex.2
  • Slide 5
  • Signal Handling in shell Ex. Terminating FG job user push Ctrl+C Shell receives SIGINT signal Shell sends SIGINT to FG job FG job receives SIGINT and terminates
  • Slide 6
  • Important Unix Signals SIGINT (Ctrl+C by user) SIGINT (Ctrl+C by user) terminate process terminate process SIGTSTP (Ctrl+Z by user) SIGTSTP (Ctrl+Z by user) stop process stop process SIGCONT (from shell to child) SIGCONT (from shell to child) continue stopped process continue stopped process SIGCHLD (from child to shell) SIGCHLD (from child to shell) notify state change of child process notify state change of child process Run -> Complete Run -> Complete Run -> Terminate or Stop Run -> Terminate or Stop Stop -> Run Stop -> Run > kill l : show all signals
  • Slide 7
  • signal(), sigaction() #include #include int flag; void myHandler (int sig) { flag=1; // this can stop while loop } main() { flag=0; while (!flag); printf(1); flag=0; while (!flag); printf(2); flag=0; while (!flag); printf(3); } // After myHandler is executed // SIGINT handler changes to default signal(SIGINT, myHandler); // SIGINT handler is myHandler forever struct sigaction action, old_action; action.sa_handler = myHandler; sigemptyset(&action.sa_mask); action.sa_flags = SA_RESTART; sigaction(SIGINT, &action, &old_action; This is example of busy-waiting
  • Slide 8
  • Specification 1/2 Ctrl+C terminates FG job Ctrl+C terminates FG job Ctrl+C shouldnt terminate shell Ctrl+C shouldnt terminate shell Do nothing if there is no FG job Do nothing if there is no FG job Ctrl+Z stops FG job Ctrl+Z stops FG job Ctrl+Z shouldnt stop shell Ctrl+Z shouldnt stop shell Do nothing if there is no FG job Do nothing if there is no FG job Running in background Running in background Putting & in the end of command Putting & in the end of command Terminate all jobs when shell exit Terminate all jobs when shell exit
  • Slide 9
  • Specification 2/2 jobs command jobs command Shows list of job state Shows list of job state [job_id] state command [job_id] state command State is BG running or Stopped State is BG running or Stopped fg job_id command fg job_id command Change job_id job to FG job Change job_id job to FG job Stopped or BG FG Stopped or BG FG bg job_id command change a job to BG bg job_id command change a job to BG Change job_id job to BG job Change job_id job to BG job Stopped BG Stopped BG - Dont use exec(). - If job_id is not specified, its up to you. Make it work like bash
  • Slide 10
  • SIGINT, SIGTSTP Handler sigint_handler { search FG job if there is FG job send SIGINT to FG job to terminate } sigtstp_handler { search FG job if there is FG job change the jobs state to Stopped send SIGTSTP to FG job to stop } Use kill (pid, sig) to send signal!!
  • Slide 11
  • SIGCHLD Handler sigchld_handler { get pid whose state changed to completed / terminated / stopped / continue... if it is terminated(SIGINT) or completed delete the job from job list shell comes back else if it is stopped(SIGTSTP) shell comes back } See Hints page!!
  • Slide 12
  • Hints waitpid(pid, &status, option) waitpid(pid, &status, option) If pid=-1, wait for any child to change state If pid=-1, wait for any child to change state If option = WUNTRACED|WNOHANG If option = WUNTRACED|WNOHANG Return value is pid of process when process is terminated or stopped. 0 or -1 for other state change Return value is pid of process when process is terminated or stopped. 0 or -1 for other state change WNOHANG means doesnt wait WNOHANG means doesnt wait Status can be checked with macros. - If WIFEXITED(status) > 0, completed - If WIFSIGNALED(status) > 0, terminated - If WIFSTOPPED(status) > 0, stopped Status can be checked with macros. - If WIFEXITED(status) > 0, completed - If WIFSIGNALED(status) > 0, terminated - If WIFSTOPPED(status) > 0, stopped from http://database.sarang.net/study/glibc/24.htm http://database.sarang.net/study/glibc/24.htm and my try and error...T.T and my try and error...T.T
  • Slide 13
  • Hints Signal from group A goes to all process in group A Signal from group A goes to all process in group A Shells group and child group is same as default. Shells group and child group is same as default. But only shell should receive users signal. But only shell should receive users signal. setpgid(pid, pgid) setpgid(pid, pgid) Set process group id Set process group id If pid=0, it is same as getpid() If pid=0, it is same as getpid() If pgid=0, it is same as pid. (pid becomes a group leader) If pgid=0, it is same as pid. (pid becomes a group leader) getpgrp(), getpgid(pid) getpgrp(), getpgid(pid) get process group id get process group id
  • Slide 14
  • Hints sigprocmask(mode, set, oldset) sigprocmask(mode, set, oldset) Block signals Block signals Example code Example code sigset_t sigset, oldset; sigemptyset(&sigset); sigaddset(&sigset, SIGCHLD); sigprocmask(SIG_BLOCK, &sigset, &oldset); sigset_t sigset, oldset; sigemptyset(&sigset); sigaddset(&sigset, SIGCHLD); sigprocmask(SIG_BLOCK, &sigset, &oldset); /* run the job */ /* add job to job list */ sigprocmask(SIG_UNBLOCK, &sigset, &oldset); /* run the job */ /* add job to job list */ sigprocmask(SIG_UNBLOCK, &sigset, &oldset); Short jobs are terminated(sending SIGCHLD) before shell adds them to job list. Mask prevents this by blocking SIGCHLD.