Subscribe for automatic updates: RSS icon RSS

Login icon Sign in for full access | Help icon Help
Advanced search

Pages: [1]
  Reply  |  Print  
Author Topic: using fork kills GDC connection  (Read 6191 times)
Jos? V.
Posts: 55

« on: March 10, 2022, 06:24:22 pm »

While mantaining a legacy app i've come accross the usage of a fork() call to run some code as another user.
The parent process waits for the child to return and then resumes normal behaviour.

The problem is that the fork() call terminates the GDC connection so when the parent resumes it throws the following error:
Can not read from GUI: Connection closed by peer.

I've attached a simple program to exemplify this behaviour, just run "compileAndRun".

Is there any way to avoid the GDC connection getting killed? or should I redo the legacy code to avoid calling fork()??

* fork.tar (10 KB - downloaded 803 times.)
Rene S.
Four Js
Posts: 111

« Reply #1 on: March 14, 2022, 04:33:52 pm »

see this fragment of your "simple program to exemplify":

  2.    pid_t pid = fork();
  3.    switch (pid) {
  4.    case -1: /* error fork unsucessful */
  5.        status = -1;
  6.        break;
  8.    case 0:
  9.        printf("child process\n");
  10.        sleep(2);
  11.        status = -1;
  12.        exit(WEXITSTATUS(status)); // *** here is the bad code ***

What is the "child process"? Teach yourself: man (2) fork: " fork() causes creation of a new process.  The new process (child process) is an exact copy of the calling process (parent process)".
This implies: "exit(WEXITSTATUS(status));" performs exactly the same as an exit() in parent process would do: this includes disconnect from the frontend.

My instinct: your code is incomplete. Typically you'll perform an call to exec() in the child, something like this:

execlp("sh", "sh", "-c", cmd, (char *) NULL);

next fragment or your example (that's the "parent" code after fork):
        while (waitpid(pid, &status_ptr, 0) != pid)
        if (WIFEXITED(status_ptr)) {
            status = (short)WEXITSTATUS(status_ptr);
        } else {
            status = 1;

Why forking (starting a new process, parent and child are running parallel)  when waiting afterwards in the parent. Your code is both invalid and makes no sense. 
Jos? V.
Posts: 55

« Reply #2 on: March 21, 2022, 06:57:10 pm »

Yes you are right.
Using execlp works fine.

The code I posted does not reflect what the aplication used to do, just the error, and therefore the code I posted actually made no sense.

The reason we had a fork() and system() was to execute a command on a new process as a different user(setuid).
The new process set itself as the user and ran a command while the parent process waited for the command to execute then checked for success and continued as the "regular" user.

This worked fine in the legacy 4gl application since no connection was broken, and works just as fine using exec since no connection is broken and the process ends just as it should.

Thank you for the explanation Rene.
Pages: [1]
  Reply  |  Print  
Jump to:  

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines