I'm presently using a Linux command in my c program to show a group of processes. When a process is stopped (suspended) though, this command does not list it. I need to list both running AND stopped jobs. Note: When I say stopped, I do NOT mean terminated jobs. The issue is with displaying suspended processes.
execvp("/bin/ps", parmList);
I have to use the ps command. Is there anyway to show both running and stopped (suspended) processes in this situation?
There are two ways to go about it:
1) Continuously monitor processes for change in state.
2) Register a handler to get notified asynchronously, when state changes.
1st case
execute a script that continously monitors process states.
You have to use ps with BSD style options ie
ps axo pid,stat
2nd case
you can only monitor the child processes.
you can monitor them by using waitpid() provided they are child processes.
So, basically you register a handler for signals and in the handler you use waitpid to get the status.
You will find the signals explained here:
[http://linux.die.net/man/2/waitpid][1]
Related
I want to write a program that uses only SIGUSR1/SIGUSR2 signals for pausing and resuming a multiple number of child processes that work on a same problem simultaneously. If I use a signal handler to send an info that a child process has paused of course when its multiples are sent they will merge into one. Since I am using sigsuspend, is there a way to know when at least the last process finished so that i don't signal a parent before the last child finishes. Also, if that is not possible is it possible to somehow find out that child process is suspended by checking some of those 3 files made when a process is created. Thanks in advance!
I'm trying to interface with a really crappy, completely opaque API that creates two subprocesses within a POSIX-like environment (OS X/Linux) in C. Basically, it starts an external program and provides rudimentary support for passing messages back and forth. The process tree looks something like this:
+ My_program
\
+ an initiation shell script (csh -f -c external_program_startup_script)
\
- the external program instance
When I press control-c in the terminal while My_program is running, the controlling terminal sends SIGINT to all processes in its process group — all three above processes. I want SIGINT to get to the program instance, but if it also hits the shell script then that middle process is terminated and the communication link is severed.
Within My_program, I can setup a signal handler to ignore SIGINTs. But I have absolutely no control over the two child processes (the API doesn't even expose their PIDs), so existing solutions such as changing their process group or attaching handlers won't work. Is there a way to prevent the controlling terminal from sending SIGINT to all processes in the foreground process group?
(The API in question is MATLAB's libeng, which allows an external C program to process commands within MATLAB. But it has absolutely no functionality for sending interrupts beyond that which the OS provides.)
You need to run sub-processes in separate control group. You can achieve that by proper usage of setpgid() function. After fork() call, in the child process run setpgid(), then exec the program you want to be run in separate group.
I am trying to emulate SIGTERM in windows using GenerateConsoleCtrlEvent(..). I read the condition should be that the new process be in a new process group and share the console of the calling process. In connection to this work, I have two questions -
Given a process id, is it possible to determine using any current windows API if the process is created with CREATE_NEW_PROCESS_GROUP flag?
GetConsoleProcessList(..) gives me all process belonging to the console of the calling process including the one created with CREATE_NEW_CONSOLE flag. This looked like a surprise, so can someone clarify the meaning of it?
In bash when I run a command like wc & or cat & that wants standard in right away, it returns immediately with
[1]+ Stopped cat
How is this accomplished? How do I stop a program that I started with exec, and how do I know to stop these programs in the first place? Is there some way to tell that these programs want stdin?
Thanks!
PS also, what is the + about? I've always wondered, but that's really hard to google...
If you want spawned programs to behave similarly to how the shell works, call setpgrp() after forking your child. This will cause the background program to run in its own process group, and therefore have a detached tty. When it tries to do I/O to the console, it will receive SIGTTIN or SIGTTOU signals. The default behaviour of SIGTTIN or SIGTTOU is to stop the process just like SIGSTOP.
As the parent, you can find out whether you have stopped child processes using waitpid() and WUNTRACED.
[Edited -- see other answers for the answer to the main question]
The + sign simply refers to the current job. Each pipeline of commands (such as foo | bar | baz) is a job, which can be referred to using a jobspec beginning with the % character. %1 is job number 1, %+ is the current job, and %- is the previous job.
For more information about jobs, see the Job Control section of the Bash manual.
The setpgid() manual page explains how this works:
A session can have a controlling terminal. At any time, one (and only
one) of the process groups in the session can be the foreground
process group for the terminal; the remaining process groups are in
the background. If a signal is generated from the terminal (e.g.,
typing the interrupt key to generate SIGINT), that signal is sent to
the foreground process group. (See termios(3) for a description of
the characters that generate signals.) Only the foreground process
group may read(2) from the terminal; if a background process group
tries to read(2) from the terminal, then the group is sent a
SIGTSTP signal, which suspends it. The tcgetpgrp(3) and
tcsetpgrp(3) functions are used to get/set the foreground process
group of the controlling terminal.
So what you want to do is this:
When you create a new pipeline, call setpgid() to put all the members of the pipeline in a new process group (with the PID of the first process in the pipeline as the PGID).
Use tcsetpgrp() to manage which process group is in the foreground - if you put a pipeline in the background with &, you should make the shell's own process group the foreground process group again.
Call waitpid() with the WNOHANG and WUNTRACED flags to check on the status of child processes - this will inform you when they are stopped by SIGTSTP, which will allow you to print a message like bash does.
You can use system("command &") in the forked child process and then manually make it exit, if there are no time and priority constraints.
I am creating a GTK application in C. I am creating a child process using fork and then replacing it with execve("crawler",arg,env); which crawls my home directory and stores all the filenames in a file.
Now, this child process takes some time (about 2-5 minutes).
In the mean time, when this child process is running, the main GTK parent program is waiting.
But when the child process is running, after some time, the GTK application hangs.
I have tried gdk_thread_enter()/leave() in my main function.
But still I am the application is hanging.
Please, point out a mistake if any or else suggest any modification.
execve does not create a child process, it replaces the current process with the child. Are you sure you used fork() first, and then execve() from within the child?
EDIT since you're already using fork/execve, perhaps the child process is still interacting with Gtk somehow. Best to use Glib/Gtk+-specific functions for invoking the crawler -- try, for instance, g_spawn_command_line_async
If what you mean by "when this child process is running, the main GTK parent program is waiting" is that your code executes a wait(), waitid(), waitpid() in its main thread, then the app will indeed suspend execution until a child terminates (unless you've selected NOHANG option).
If your Gtk app doesn't need to coordinate further with your crawler program, just use the previously-mentioned
g_spawn_command_line_async routine, and do not set G_SPAWN_DO_NOT_REAP_CHILD. If you do need to coordinate, you could set that flag, and create a GChildWatch source, or perhaps could use one of the g_spawn pipe routines.
As I interpret gdk_thread_enter()/leave(), they are locking or unlocking threading, rather than running or stopping new threads. Gtk callbacks run in the main thread, so as indicated above, a blocking waitpid() in a callback will hang the Gtk app. A non-blocking waitpid() in a timer callback (eg) is not a problem, however.