[solved] How to start a new process/program?

Hi @ all!

I wrote a small program “Zeichnen” with qt and ported it to QNX neutrino 6.5.0 SP1 (for BeagleBoard xM).
It is working just fine :slight_smile:
Now I want to start this program from my C Code. I want the new program to run separately, like if I start in Linux a program with “&”. For this I tried the following:
(I borrowed some code from a tutorial)

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>


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

pid_t kind1;

while(1)
 {
  switch(kind1=fork())
   {
     case -1 : printf("Fehler bei fork()..........\n");  exit(0);
     case  0 : printf("Kindprozess: Mein PID ist %d\n",getpid());
               printf("Kindprozess: Meine Eltern haben die PID %d\n",getppid());
               execl ("/Zeichnen/Zeichnen", "zeichnen", "-qws", "&");
               printf("Überschreibe prozess");
               exit(1);
     default : printf("Elternprozess: Ich habe folgendes Kind PID : %d\n",kind1);
               printf("Elternprozess: Meine PID lautet %d\n",getpid());
               printf("Elternprozess: Die PID meiner Eltern lautet %d\n",getppid());
               exit(2);
   }
 }

	return EXIT_SUCCESS;
}

This is the output:

Elternprozess: Ich habe folgendes Kind PID : 442402
Elternprozess: Meine PID lautet 442390
Elternprozess: Die PID meiner Eltern lautet 151579
Kindprozess: Mein PID ist 442402
Kindprozess: Meine Eltern haben die PID 442390
Ü

I cannot understand what is happening… the childprocess is started, but the execl-command and the print-command are ignored (print command only the first letter), what is the problem?
Is this not the correct way? What else could I do?

What is my goal:
starting different programs on the Board via the serial interface from another program on my pc (and stopping of course… with kill() :slight_smile: )

Edit:
I tried only

execl ("/Zeichnen/Zeichnen", "zeichnen", "-qws", "&", NULL);

with a NULL argument and it is starting now BUT:
I overwrite the actual process (correct?), so I still have the problem with fork()-process and that it runs seperate from its parent process

‘&’ is a signal to the shell to run a program in the background. It is not usually an argument to a program the way you are doing this. I would take a look at spawn() and it’s variants, eg. spawnl().

Yeah, I know that “&” is normaly used in the shell only.
… You could say that was a try out of frustration + not so much knowledge about unix systems (but I am learning) :slight_smile:

Thx 4 answer, I will check the suggested spawn()-function.

Hi again :slight_smile:

The spawn() function is working just fine!

Now I want to stop/kill this new process → what command can I use in my code for this?
I find a lot about wait() and such, but that is only if the child is stopping and the parent is reacting to it.

I want the parent to stop a process (in my case a process which is running simultaneously with the parent process).
I know that this is not a good way, but it is only for testing :slight_smile:

Edit:

I found the function

int SignalKill( uint32_t nd, pid_t pid, int tid, int signo, int code, int value );

and I tihink this could help me, but can someone explain me what “code” and “value” would be?
Maybe I am just blind, but I cannot find an example or an explanation in the documents about what value I should enter here.

I tried with

SignalKill( 0, pid, 0, SIGKILL,0, 0 );

→ Now the process seems to stop, but i doesn´t vanish from the list. Instead there stands “unavailable” and it only vanishs if I stop the parent.
Could it be a Zombie? → How can I get rid of this? (waitpid() also stops my parent after the kill signal)

Noir,

Yes it’s a zombie.

If you are just testing and want fast ways to spawn and kill your program you can instead use to following code:

// Start my program
system(“fullpath/Zeichnen youArgsHere &”);

// Stop my program
system (“slay Zeichnen”);

Tim

You are getting the Zombie because the child process dies and it trying to notify the parent of it’s final error code.
The Zombie is what is left of the process. No memory, but just an error code. It does take up a space in the process list which could eventually fill up if you get enough zombies. To fix this you have three choices.

  1. Let the parent die.
  2. Do a wait() or waitpid() in the parent. This will return the error code and the Zombie will go away.
  3. Use the SPAWN_NOZOMBIE flag if you are using spawn(). If instead you are using spawnl() you can use the P_NOWAITO flag instead of P_NOWAIT.

Thx for the answer :slight_smile: this helps a lot!

@Tim:
I have also seen the system()-command, but for this I need the shell “sh” (as far as I know).
But this sh-process is disrupting my serial interface connection with my Pc, so I kill this process after booting.
→ I am using a demoOS from QNX with the librarys that I need already implemented, because I have problems in understanding how to build the binary from commandline with Qt.
It would be nice if someone can explain me this, but I think I will start a new thread for this (with better explanation)

@maschoen:
I tried Nr.2 already with waitpid() but then the parent also stops?
P_NOWAITO is a good suggestion, I will try this later :slight_smile:

Thx again you two!

Hi again :slight_smile:

spawnl() is working the way I wanted with my testprogram. Now I tried to create processes with different programs and got an error which I don´t know how to fix it.

I made a testprogram named “QMLTest” and, as the name implies, it is a Qt QML program.
The folderstructure looks like this on my Beagleboard (the folders are outside of the OS-binary):

(/ (root) -> doesn´t stand there, but as far as I know is there :) )
   -> bin
   -> ramdisk
   -> and so on..
        .
        .
        .
   -> QMLTest
         -> QMLTest (binary)
         -> content
                -> QMLTest.qml
                -> circle.png
                -> arrow.png

In short: In the folder QMLTest are the binary from the Qt-project and a subfolder “content” with the qml-file and the used pictures.

If I use the shell to call this process

cd /QMLTest
./QMLTest -qws &

It is working fine (also if I am in the folder and only call “QMLTest -qws” ).
But if I use

exit_val = spawnl( 3, "/QMLTest/QMLTest", "QMLTest", "-qws", NULL);

Then I get the following output and error:

I start my QNX program only temporary in /ramdisk (found a paper which told me so) and therefore it cannot find the subfolder (this is my guess). Does this mean I have to use spawnl() in the folder where the other program is located?
I also have this problem with another program which is using picures! (then the error is like: “Picture is a null-image”).
I wanted to start process according to the buttons you press on a GUI.

Any idea?

chdir("/QMLTest");
spawnl(…);

Thx :slight_smile: it is working!

Edit:

For the QMLTest program it is working. But for another program “Vererbung” it is not working.
For this program I use png-pictures in a folder “Bilder”. The structure is nearly the same as “QMLTest”:

-> Vererbung
        -> Vererbung (binary)
        -> Bilder
                 -> Circle.png
                 -> arrow.png

Even if I use chdir("/Vererbung");
the failure

is still appearing. For loading the picture in Qt I use

zeiger->load(QString(QCoreApplication::applicationDirPath() + "/Bilder/Zeiger.png"));

Maybe this is the failure? But in Desktop-mode this is working fine…

Replace the Qt load with an fopen() to see if you can open the file. If you can, then the problem is with the Qt routine. If you can’t open it, either the file is corrupt or you have a permissions problem.

this program is running without problems if I use the shell to start the process.
Does this mean, if fopen can open the picture, that the shell and the spawnl() command have different permission “levels” ?
(Still haven´t the time to test fopen…)

Different users can have different permissions on files.
If fopen() can’t open the file, then you would not expect the routine to be able to either.
If fopen() can open the file, then there isn’t a file permission problem, so the problem is likely with the use of the Qt routine.

Hi again!

Finally I had time to test fopen(). For this I added

    printf("%s\n", "opening with fopen()");
    datei = fopen("/Vererbung/Bilder/Zeiger.png", "r");
    if(datei == NULL)
    {printf("%s\n", "opening with fopen() not working");}
    else
    {printf("%s\n", "opening with fopen() ok!");}

to my Qt Code. The result ist this:

So like maschoen said, there should be some problems with my Qt-routine, BUT this program is running on the same board and QNX if I don´t use spawnl(). Instead if I use the momentics suit to start the binary or the shell then it is ok and the pictures are found.

Any help with this problem?

ok, I found the problem with some help :slight_smile:

In my case I stopped the shell because it disturbs my communication.
If I now want to start a new program with the pictures, then this program doesn´t have the environment variables it needs.

Possible ways to fix this:
1.
Using systems() as it starts a new shell and don´t disturb my communication IF I add “&” AND the command doesn´t read/write stdin/stdout.
I still need the environment variables and can set it with a script started via system() → system("/directory/script");

I used spawnle() instead of spawnl() and set the environment variable with a char-array

char *env_list[] = {"QWS_DISPLAY=qnx",
			       "QWS_KEYBOARD=qnx",
			       "QWS_MOUSE_PROTO=qnx",
			        NULL
			       };

chdir("/Vererbung");
exit_val_Vererbung= spawnle( 3, "/Vererbung/Vererbung", "Vererbung", "-qws", NULL, env_list);

Now it is working :slight_smile:
Thanks again to maschoen and Dennis from another qnx-forum!


Ps.: Here is the discussion in the other forum (if linking is not allowed, then I am sorry and pls delete this link or pm me)
community.qnx.com/sf/discussion/ … .topc23954