0

I wanted to start an Program in the Background and it should be could stopped from the first Program. Code vom starter C-Code:

#include<stdio.h>
#include<stdlib.h>

int main() {
    char command[50];
    int i;

    for(i=0; i<10; i++)
    {
            snprintf(command, sizeof(command), "./test %i &", i);
            system(command);
    }
    printf("FERTIG\n");
}

And here is the code that should be started in this case 10-times: (Later the code should be much bigger and it will be another code, but there will be an while(1) code. So i will need it.)

#include<stdio.h>

int main(int argc, char* argv[])
{
    int i;
    printf("argc: %i\n", argc);
    for(i=0; i < argc; i++)
    {
            printf("argv[%d]: %s\n", i, argv[i]);
    }
    printf("FERTIG\n");
    while(1)
            printf("DAUERSCHLEIFE");
}

I hope someone can help me. And no i cant use any other languages, because im using the raspberry pi, and already familiar with C. I dont want to learn any other languages.

And the Question is, is there a way to stop the while(1)-Loop from the first Program?

daniprog
  • 29
  • 3
  • 1
    yes: use `kill`. You'll have to get the pid of the child process some way. for instance: fork & exec your subprocess. the forked program has the pid and you can kill it (https://stackoverflow.com/questions/42568617/c-get-pid-of-process-launched-with-execl) – Jean-François Fabre Sep 09 '18 at 19:38
  • The [`system`](http://man7.org/linux/man-pages/man3/system.3.html) function blocks until the program is finished. Use [`fork`](http://man7.org/linux/man-pages/man2/fork.2.html), [`exec`](http://man7.org/linux/man-pages/man3/exec.3.html) to create a "background" process and execute it. Then in the parent process use [`kill`](http://man7.org/linux/man-pages/man2/kill.2.html) and [`wait`](http://man7.org/linux/man-pages/man2/waitpid.2.html). – Some programmer dude Sep 09 '18 at 19:41
  • `system(command);` does not return to the calling program until it has ended. – Weather Vane Sep 09 '18 at 19:41
  • is this a good enough duplicate? https://stackoverflow.com/questions/42568617/c-get-pid-of-process-launched-with-execl (it's mssing the kill part) – Jean-François Fabre Sep 09 '18 at 19:42
  • 2
    "I dont want to learn any other languages": you're wrong. With a python launcher, this is trivial. – Jean-François Fabre Sep 09 '18 at 19:44
  • No system() command executes. And when im using it with an & at the ending of the command it will execute in the background and makes his things in the foreground. Thanks Jean-Fraçois. I will testing it. – daniprog Sep 10 '18 at 07:11

2 Answers2

1

Caleb helped me very much. It's not really worked what i wanted, but i found another post on ubuntuforums.org (Keywords have been: c pid_t fork kill exec). And that was a really good answer. So Thanks to your help Caleb. It should be an vote up, but my rep isn't high enough. So sorry. But it said it has been recorded.

So heres the link to the post: https://ubuntuforums.org/showthread.php?t=675734

And here is the Code:

#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>

int main()
{
    pid_t childPID = fork();

    if ( childPID == -1 )
    {
        printf( "failed to fork child\n" );
        _exit( 1 );
    }
    else if ( childPID == 0 )
    {
        char *args[] = { "test", "hello", "world", 0 };

        execv( "test", args );
    }

    while ( 1 )
    {
        printf( "Enter 'q' to kill child process...\n" );
//      char c = getchar();
        sleep( 10 );
        char c = 'q';
        if ( c == 'q' )
        {
            kill( childPID, SIGKILL );
            break;
        }

        sleep( 1 );
    }

    return 0;
}

I hope any other people with also this problem, could solve it with my question and answer.

But a big thanks to Caleb.

daniprog
  • 29
  • 3
0

is there a way to stop the while(1)-Loop from the first Program?

One way is to call kill() to send the process a SIGTERM or SIGKILL signal, which should cause the program to exit. To do that, though, you also need the process ID of the process you want to kill, and calling system() doesn't give you that. You could instead start the process by fork()ing your own process and calling exec() (or one of its variants) in the child process to start the new program. So your code would look something like:

pid_t child_pid = fork();
if (child_pid == 0) {
    execl(command);
}

Then, when the parent process wants to stop the child process, it can do:

kill(child_pid, SIGTERM);    // or SIGKILL

to stop the child.

Using a signal to kill a process is a pretty blunt instrument, though. It'd be better to arrange some other inter-process communication method between the two processes and having the child process check for messages from the parent that tell it to exit gracefully.

Caleb
  • 124,013
  • 19
  • 183
  • 272