fork(), exec oder system?
-
Hallo,
ich möchte aus einem curses programm ein systemcall starten,
während dieser läuft eine schleife ausführen, und nach dem ende des prozesses
auf dessen rückgabewert zugreifen können.ich habs schon mit fork(); probiert, das resultat war, dass wie zu erwarten das ganze programm 2mal existiert, dann mein extraprozess, aber nach seinem ablaufen das programm immernoch 2mal da ist, mit einem <defunct> dahinterbei ps.
das sah ungefähr so aus:switch(kind1=fork()) { case -1: exit(0); break; case 0: system("sleep 7");exit(0); break; default: ... break;
ja, und mit i=system("false &"); ist das problem, dass i immer 0 ergibt.
exec.. ja, das geht irgentwie garnicht:
wenn ich
execlp(sleep,"20", NULL);ausführe, dann gibt es keinen prozess "sleep"
auch bei execl(/bin/sleep,"20", NULL); nicht.hat jemand vielleicht ne ahnung wie ich das machen kann, so dass es halt am ende nur noch wieder den ersten prozess gibt, nämlich mein programm?
dankeschön schon mal,
pazz
-
Mit einem Signalhandler SIGCHLD abfanbgen und dort ein wait bzw. waitpid machen. Dann kann Dein Childprozess seinen Exitcode zurückgeben und stirbt friedlich
-
äh...
is mir immo etwas zu hoch.. ich bin schon fleissig am tuts lesen, aber vielleicht kannst du das "abfangen" nochmal spezifizierenich erstelle also eine funktion lala();
und mache dann irgendwo vor meiner fork(); aktion ein signal(SIGCHLD,lala);wenn nun mein prozess das signal bekommt, ruft er lala(); auf..
und dann steht da meine warteschleife, die was tut und immer nachschaut ob das kind noch lebt?warum das nicht gleich in den elternprozess?
und wie komme ich nun zu meinem system-return-wert?sorry wenns etwas naiv klingt, aber gibt es sonst noch howtos dazu?
ich such bei zeiten nochmal..
danke erst mal,
pazz
-
hm.
also ich wuerde es so machen:int status; pid_t pid; pid = fork(); switch( pid ) { case -1: /* das fork ist fehlgeschlagen -> fehlerbehandlung*/ break; /* kindprozess */ case 0: fuehre_sys_call_aus(); break; /* vaterprozess */ default: /* waitpid wartet auf den kindprozess mit der prozessnr. pid */ if ( waitpid( pid, &status, 0 ) == -1 ) printf( "kein kind mit dieser pid" ); } ... void fuehre_sys_call_aus() { char* programm = "sleep"; char* argv[3]; /* argv[0] sollte der programmname sein! * danach kommen die kommandozeilen-argumente * die kommandozeilenargumente mussen mit * NULL abgeschlossen sein!*/ argv[0] = programm; argv[1] = "20"; argv[2] = NULL; /* fuehre das prog aus */ execvp( programm, argv ); /* diese stelle wird nur erreicht, wenn exec fehlschlaegt */ printf( "fehler beim ausfuehren" ); }
achja, status kannst du mit folgenden makros auswerten:
(aus <sys/wait.h>)
WIFEXITED (*status) : wahr, wenn das Kind sich durch exit (_exit, return) beendet hat.
WEXITSTATUS (*status) enthält dann den Exit-Code
WIFSIGNAL (*status) : wahr, genau dann, wenn das Kind duch ein Signal beendet wurde
WTERMSIG (*status) liefert dann die Signalnummer
WIFSTOPPED (*status) : wahr, genau dann, wenn das Kind gestoppt wird.edit: siehe naechster post (danke fuer den hinweis)...
-
zwischen char und argv[3]; in fkt. void fuehre_sys_call_aus() fehlt glaub ich ein *
-
Hab das rausgekramt hier und gerade ausprobiert, ich glaube es muss WIFSIGNALED() heissen
entelechie schrieb:
hm.
WIFSIGNALED (*status) : wahr, genau dann, wenn das Kind duch ein Signal beendet