0

I am trying to implement simple shell in C language and i am having a hard time implementing job control. Everything online seems complicated enough and i think some simplicity is always good. So let me ask this ... After fork() is called can i handle Ctrl-Z signal with just 2 function and just with the pid ?

I want to call a function e.x. put_background(pid_t pid) when i hit Ctrl-Z and make process with pid = pid to run background and finally call another function e.x. put_foreground(pid_t pid) when i write fg and i want the process with pid = pid to go to foreground again.

So, is this possible? Any help is appreciated.. code more however.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
Andrew Zacharakis
  • 351
  • 1
  • 6
  • 19
  • 3
    Ctrl-Z doesn't run a program in the background, it pauses it (by sending it `SIGTSTP`). – melpomene Oct 20 '18 at 19:25
  • That's not the point, i can handle the signals as i want, however can i change between foreground and background just with the pid ? – Andrew Zacharakis Oct 20 '18 at 19:30
  • Are we to presume that you're talking about a POSIX environment? Because standard C itself doesn't have any concept of jobs, much less job control, forking, *etc*. These things work differently, if at all, in different kinds of environments. – John Bollinger Oct 20 '18 at 19:45
  • 3
    @CharlesDuffy, I'd characterize foreground vs. background completely differently: a foreground job is one that has a controlling terminal and currently has permission to read from it. Although it's likely that its parent is a shell and is `wait`ing on it, that's not the essential characteristic. – John Bollinger Oct 20 '18 at 19:53
  • I have to agree -- on which point, http://curiousthing.org/sigttin-sigttou-deep-dive-linux is probably a useful resource for the OP. – Charles Duffy Oct 20 '18 at 20:12

1 Answers1

1

I am trying to implement simple shell in C language and i am having a hard time implementing job control. Everything online seems complicated enough and i think some simplicity is always good.

So let me ask this ... After fork() is called can i handle Ctrl-Z signal with just 2 function and just with the pid ?

Note that Ctrl-Z is meaningful primarily to the terminal driver. It causes a SIGTSTP to be sent to the foreground process group of the terminal in which that character was typed -- that is, the process group that has that terminal as its controlling one, and has permission to read from it. By default, this causes the processes in that group to stop, but that's it. You don't need to do anything to achieve that.*

I want to call a function e.x. put_background(pid_t pid) when i hit Ctrl-Z and make process with pid = pid to run background and finally call another function e.x. put_foreground(pid_t pid) when i write fg and i want the process with pid = pid to go to foreground again.

By definition and design, at most one process group has control of a given terminal at any particular time. Thus, to move a foreground job to the background, all you need to do is move a different one to the foreground. That can be the shell itself or some other job under its control. The tcsetpgrp() library function accomplishes this. Unless it's the shell itself, you would also want to send a SIGCONT to that process group in case it was stopped.

You additionally need a mechanism to resume a stopped background job, but that's easy: just send that process group a SIGCONT.

So, is this possible? Any help is appreciated.. code more however.

Well sure, you could write one function for moving a job to the foreground and resuming it, and one for resuming a background job. The only information these functions need about the jobs they operate on is their process group IDs (which is the same as the process IDs of their initial processes).

But you also need to maintain some bookkeeping of the current active jobs, and you need to take some care about starting new jobs, and you need to monitor current jobs -- especially the foreground job -- so as to be able to orchestrate all of the transitions appropriately.

The GLIBC manual has an entire chapter on job control, including a substantial section specifically on implementing a job-control shell. This would probably be useful to you even if you are not writing for a GLIBC-based system. The actual code needed is not all that complicated, but getting it right requires a good understanding of a fairly wide range of concepts.


*But you do need to ensure that your shell puts commands it launches into process groups different from its own, else a Ctrl-Z will stop it, too.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157