4

I am extending the functionality of a custom unix shell which I wrote as part of my lab assignment. It currently supports all commands through execvp calls, in-built commands like pwd, cd, history, echo and export, and also redirection and pipes. Now I wanted to add support for running a command in background e.g. $ls -la& I also want to implement bg and fg job control commands.

I know this can be achieved if I execute the command by forking a new child process and not waiting for it in the parent process. But how do I again bring this command to foreground using fg? I have the idea of entering each background command in a list assigning each of them a serial number. But I don't know how do I make the processes execute in the background, then bring them back to foreground. I guess wait() and waitpid() system calls would come handy but I am not that comfortable with them. I tried reading the man pages but still am in the dark. Can someone please explain in a layman's language how to achieve this in UNIX system programming? And does it have something to do with SIGCONT and SIGSTP signals?

DeveloperDon
  • 4,958
  • 1
  • 26
  • 53
user1631009
  • 163
  • 1
  • 1
  • 3
  • 2
    glibc has a interesting docs about this: http://www.gnu.org/software/libc/manual/html_node/Job-Control.html - the search keyword you're looking for is "job control". – Mat Aug 30 '12 at 06:14
  • 1
    Nearly all popular UNIX shells are open-source. Is there a particular reason why you don't want to look at them to see how bash, zsh etc. implement the 'fg' command? – Kilian Foth Aug 30 '12 at 06:32
  • @KilianFoth, copying the implementation without understanding it as little learning experience. And I don't see why would someone who needs to ask this question starts a shell if it wasn't for the learning experience. – AProgrammer Aug 30 '12 at 09:33
  • @AProgrammer Seeing how other people have solved your problem before you is **not** avoiding learning. – Phoshi Aug 30 '12 at 11:08
  • 1
    @Phoshi, I didn't mean it would be avoiding learning, I meant I don't think it wouldn't help learning as the question hints that the OP doesn't understand the underlying concepts. Sample code would be just magic invocation. – AProgrammer Aug 30 '12 at 11:32
  • You learn more doing it from scratch. It can be illuminating to try it blind first, then looking at how other people solved it in the real implementation. You don't get as much of an appreciation for why they did things certain ways unless you've encountered the same issues directly. – Gort the Robot Sep 03 '12 at 01:13
  • Cool project btw i kinda wanna try this... – daniel gratzer Oct 02 '12 at 20:04

2 Answers2

4

Suspending a command (CTRL-Z) works by sending a SIGTSTP to the child process. The shell is then free to interact with the user via stdin/stdout.

Resuming is accomplished by sending SIGCONT to the child process and then continuing to wait for it to finish.

Backgrounding a process is accomplished by sending SIGCONT but not waiting for it to finish. In this case, both the shell and the child process can interact with stdout/stderr, but stdin is typically intercepted by the shell.

Starting a process in the background is accomplished by doing a fork/exec, but not blocking until the child process exists.

Typically (as in always) a shell will also handle SIGCHLD, which is the way the OS notifies the parent process that a child processes has finished so that the parent can collect the exit code. Otherwise you end up with "zombie" processes; ones which aren't running but which haven't yet been collected by a parent.

tylerl
  • 4,850
  • 21
  • 32
0

I'd suggest to read the relevant chapters of Advanced Programming in the Unix Environment of W. R. Stevens. There is lot of background information to know and that's the only place where I know for sure it is present in an understandable way.

AProgrammer
  • 10,404
  • 1
  • 30
  • 45