简体   繁体   中英

Job control in linux with C

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.

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.

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.

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

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;  
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM