Provide full access over terminal for child, while it alive - terminal

I use fork() in order to exec some another program, for example "vim" or "man bash". But, at that moment I lost control, I can't print anything in vim or scroll or quite.
So, my question: how give child full access over terminal(input/output) and get it back for parent after child death?

So, my question: how give child full access over terminal(input/output) and get it back for parent after child death?
waitpid() and SIGCHLD are mechanisms for knowing when a child process has finished. The functions tcgetpgrp(fd) and tcsetpgrp(fd,pgrp) and ctermid() can be used to place a program in the foreground of a terminal.
Otherwise, the information in tcsetpgrp() in 'C' is probably instructive.

Related

WinAPI: who closes an inherited handle?

In windows, a child process can inherit handles of the parent process, given that the handle is created inheritable, and the child process is created with the "inherit handles" option.
How are those handles closed properly? I couldn't find any documentation on that.
Does the inherited handle in the child process become invalid when the parent process closes it (or terminates)? In that case, the child process would have to duplicate it. and only close the duplicate after use - but depending on how the handle value is passed to the child process, there would be a (miniscule) window in which the handle could become invalid before it is duplicated.
Or does the child process get its own handle, that it can (and should) close as needed?
That seems more reasonable to me, though I wonder how can we ensure that the child process knows of ll handles it became responsible for?
inherit handles this is duplicated handles. so they independent from parent process handles and not become invalid when the parent process closes self copy. and child process can (and should) close this handles when no more needed it. if not do this - handles will be closed when process exit.
how can we ensure that the child process knows of all handles it
became responsible for?
formally possible enumerate all handles in self process (via NtQuerySystemInformation(SystemExtendedHandleInformation) and for every handle call GetHandleInformation and check for HANDLE_FLAG_INHERIT. but this not have big sense and nobody do this.
need ask another question first - for what we pass handle(s) to child ? in most case we also pass information about this handles values to child. usually inside command line. child must understand format of command line and get information about handles.
how child will be use handles, close he they or it will be closed only when child exit - this already depend from child process. how it written/design

Killing all descendent processes robustly on macOS

On Linux, Pid namespaces can be used to robustly kill all descendent (including orphaned & zombie) processes – see this answer for example.
What's the closest to a "robust" way to do the same on macOS? I can't rely on process groups unfortunately as some of the descendent processes alter them.
It's a gross kludge, but it might work: The first process would open a file descriptor so that, by default, all descendant processes inherit it. When it wants to kill them all, it runs lsof to find all processes with that file open and kills them.
It won't work for processes which have detached themselves, but you could walk the child process tree using proc_listchildpids() and send signals to each PID you obtain. There are probably some timing edge cases between checking a process's children and killing it - it could spawn more processes in this time. You could perhaps suspend all processes before listing their children and killing them. Processes whose parent has died should I think be reattached to their grandparent anyway though (I may be wrong on this) so in that case, as long as you keep calling proc_listchildpids() after sending each round of signals you should eventually end up in a steady state. (Ideally with no child processes left. But if they get into a really bad state [due to a kernel bug], some processes may be completely unkillable.)
proc_listchildpids() is declared in <libproc/libproc.h>.

creating a new screen (like vi and less does) in a textual program

Programs like vi, less, screen, when executed, they fill the terminal with their data, and then, if you press c - Z (or terminate the program) the terminal return as it was before the execution of these programs.
How usually a program do that? What is the correct terminology this kind of thing?
PS: The words used in the title may be not correct since I've no even idea about the terminology of this kind of things.
EDIT:
Thank to #Atropo I now know the correct name of these is foreground process,
but, how a program do that? How the program can clear the screen, do its writing and, at the end of the execution, let the shell reappear with all the old writings?
They're called foreground processes.
Usually a foreground processes show the user an interface, through which the user can interact with the program. So the user must wait for one foreground process to complete before running another one.
While you use a foreground process the shell prompt disappears until you close the process or you put it in the background.
By default CTRL-C generates SIGINT signal and CTRL-Z SIGTSTP:
https://en.wikipedia.org/wiki/Unix_signal
To change the behavior you can:
redefine or mask signal handler
disable the key combination for stdin http://linux.die.net/man/3/termios
close stdin descriptor (like daemons do)

How are PIDs generated on Ubuntu?

I've just wrote a program that forks one process. The child process just displays "HI" 200 times. The father process just says he's the father.
I've printed out both pids.
When I run my program multiple times, I see that the parent's pid stays the same, which is normal. What I don't understand is why the child's pid keeps getting incremented by 2, and exactly 2.
My question: Is this the standard method of pid generation in Ubuntu? Incrementing by 2?
PIDs happen to be handed out monotonically increasing in Linux 2.6, but why does it matter which you get? Don't rely on any specific behavior. If there is a skip of +2 it might simply be because another process happened to spawn a child. Or because +1 would have reached a PID that is already in use.
Found a reference here saying that vfork() consumes a pid as a byproduct of its operation. As well, in some cases, if you're forking from a shell script, the fork might spawn a new shell before your actual script gets involved, which would also consume a pid.
I'd suggest suspending your program between a couple forks, and see if there's another process occupying those "missing" pids.

How to fire and forget a subprocess?

I have a long running process and I need it to launch another process (that will run for a good while too). I need to only start it, and then completely forget about it.
I managed to do what I needed by scooping some code from the Programming Ruby book, but I'd like to find the best/right way, and understand what is going on. Here's what I got initially:
exec("whatever --take-very-long") if fork.nil?
Process.detach($$)
So, is this the way, or how else should I do it?
After checking the answers below I ended up with this code, which seems to make more sense:
(pid = fork) ? Process.detach(pid) : exec("foo")
I'd appreciate some explanation on how fork works. [got that already]
Was detaching $$ right? I don't know why this works, and I'd really love to have a better grasp of the situation.
Alnitak is right. Here's a more explicit way to write it, without $$
pid = Process.fork
if pid.nil? then
# In child
exec "whatever --take-very-long"
else
# In parent
Process.detach(pid)
end
The purpose of detach is just to say, "I don't care when the child terminates" to avoid zombie processes.
The fork function separates your process in two.
Both processes then receive the result of the function. The child receives a value of zero/nil (and hence knows that it's the child) and the parent receives the PID of the child.
Hence:
exec("something") if fork.nil?
will make the child process start "something", and the parent process will carry on with where it was.
Note that exec() replaces the current process with "something", so the child process will never execute any subsequent Ruby code.
The call to Process.detach() looks like it might be incorrect. I would have expected it to have the child's PID in it, but if I read your code right it's actually detaching the parent process.
Detaching $$ wasn't right. From p. 348 of the Pickaxe (2nd Ed):
$$ Fixnum The process number of the program being executed. [r/o]
This section, "Variables and Constants" in the "Ruby Language" chapter, is very handy for decoding various ruby short $ constants - however the online edition (the first
So what you were actually doing was detaching the program from itself, not from its child.
Like others have said, the proper way to detach from the child is to use the child's pid returned from fork().
The other answers are good if you're sure you want to detach the child process. However, if you either don't mind, or would prefer to keep the child process attached (e.g. you are launching sub-servers/services for a web app), then you can take advantage of the following shorthand
fork do
exec('whatever --option-flag')
end
Providing a block tells fork to execute that block (and only that block) in the child process, while continuing on in the parent.
i found the answers above broke my terminal and messed up the output. this is the solution i found.
system("nohup ./test.sh &")
just in case anyone has the same issue, my goal was to log into a ssh server and then keep that process running indefinitely. so test.sh is this
#!/usr/bin/expect -f
spawn ssh host -l admin -i cloudkey
expect "pass"
send "superpass\r"
sleep 1000000

Resources