6

What I know:

When a process is running I can press Ctrl+Z and suspend it. The with bg and fg commands I can either run it in "background" or "foreground" mode.

What I'm aksing:

Is there a way to suspend a process, send it to run in background or foreground in C?

Edit: I have the process id. I want to send that process to the background for example.

Community
  • 1
  • 1
Yasser Souri
  • 1,967
  • 2
  • 19
  • 26
  • maybe sending the SIGSTP signal, but then I don't know if you can programmatically resume it as bg or fg process with respect to the shell running the process (I think you can0t but I may be wrong). You can try `system`, but I am not sure that something like `system("bg 1")` works since the job is "local" to the running shell and afaik system can execute its own "shell interpreter" instance, or whatever – ShinTakezou Jul 04 '11 at 17:32

4 Answers4

7

You can suspend it with kill(pid, SIGSTOP), but making it foreground or background is a function of the shell that ran it, since what it actually affects is whether the shell displays a prompt (and accepts a new command) immediately or waits until the job exits. Unless the shell provides an RPC interface (like DBus), there's no clean way to change the waiting/not waiting flag.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • @geocar: Finding the flag within the memory space of the shell, then changing it through debugging APIs, does not qualify as a "**clean** way" IMO. – Ben Voigt Jul 04 '11 at 17:49
3

A Linux process can usually be suspended by sending it the SIGSTOP signal or resumed by sending it the SIGCONT signal. In C,

#include <signal.h>

kill(pid, SIGSTOP);
kill(pid, SIGCONT);

A process can suspend itself using pause().

"Foreground" and "background" modes are not properties of the process. They are properties of how the parent shell process interacts with them: In fg mode, input to the shell is passed to the child process, and the shell waits for the child process to exit. In bg mode, the shell takes input itself, and runs parallel to the child process.

aschepler
  • 70,891
  • 9
  • 107
  • 161
1

You cannot. bg and fg are shell commands, and you cannot invoke a command within an arbitrary shell from C.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
1

The usual way is to fork off a child process, and exit the parent. See this for a simple example.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>

#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1

static void daemonize(void)
{
    pid_t pid, sid;

    /* already a daemon */
    if ( getppid() == 1 ) return;

    /* Fork off the parent process */
    pid = fork();
    if (pid < 0) 
    {
        exit(EXIT_FAILURE);
    }
    /* If we got a good PID, then we can exit the parent process. */
    if (pid > 0) 
    {
        exit(EXIT_SUCCESS);
    }

    /* At this point we are executing as the child process */

    /* Change the file mode mask */
    umask(0);

    /* Create a new SID for the child process */
    sid = setsid();
    if (sid < 0) 
    {
        exit(EXIT_FAILURE);
    }


    /* Change the current working directory.  This prevents the current
       directory from being locked; hence not being able to remove it. */
    if ((chdir("/")) < 0) 
    {
        exit(EXIT_FAILURE);
    }

    /* Redirect standard files to /dev/null */
    freopen( "/dev/null", "r", stdin);
    freopen( "/dev/null", "w", stdout);
    freopen( "/dev/null", "w", stderr);
}

int main( int argc, char *argv[] ) 
{
    daemonize();

    /* Now we are a daemon -- do the work for which we were paid */

    return 0;  
}
Peter K.
  • 8,028
  • 4
  • 48
  • 73