1
votes

I am working on a school project, and though it's not required, I want to implement this functionality. With that said, I can't share code, but I think it's irrelevant in this case.

When using fork(), my understanding is that the child process created inherits stdin and stdout, as the child inherits all the file streams from the parent.

My shell requires background capability, and while it technically already has that, if the "background" program runs, it still receives all the data from stdin and continues output to the screen which is just a jumbled mess. For the record, my instructor's compiled sample shell does the same thing, but I don't want that to happen!

I'm pretty certain I should be using a combination of pipe(), fork(), and dup2(), but I can't put it all together. I understand fork, but I don't understand how pipe or dup2 works and how I should implement it in the shell. I'm thinking something along these lines:

thePipe[2] = pipe();
pid = fork();
close stdin/out on child somehow if backgrounded

But I don't understand the functionality of pipe() or dup2() so I'm stuck.

Thanks!

1
If I'm understanding correctly, you will probably want to do something with the terminal (termcap or terminfo?) if possible to tell it to generate SIGTTIN and or SIGTTOU job control signals. It has been while since I looked into this, so I can't provide an actual answer unfortunately.user539810
Read Advanced Linux Programming; it explains quite well how to use pipe(7)-sBasile Starynkevitch
Shells always work this way, background processes continue to write to stdin and stdout just like foreground processes do. Inhibiting this across the board would not be desirable behavior in a shell. What you want is either (1) a program that doesn't write to any standard streams; or (2) to redirect your background program's standard streams when you run it.Crowman
Refer man 2 pipe and man 2 dup to get better understanding on unnamed pipe and dup. If you want to understand named pipe then you can also refer man 2 mknod.Adarsh

1 Answers

2
votes

You don't want pipes here. Processes run in an interactive shell should share their standard file descriptors with the shell — doing otherwise would break a lot more things (including the child processes' ability to determine they're running interactively, and to interact with the tty to handle things like window size changes). It'd also seriously complicate pipelines. Don't do it.

The missing piece here is process groups, which are described in the "General Terminal Interface" section of the Open Group UNIX specs. In brief, the kernel can be made to explicitly recognize a "foreground process group" for the terminal. If a process that isn't in this group tries to read from or write to the terminal, it is automatically stopped.

A brief walkthrough of what is necessary to make a properly functioning shell is available as part of the GNU libc manual, under "Implementing a Job Control Shell". Try following their instructions and see how that goes.