PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : exec in C und Inhalte an stdin?


Aqualon
2005-04-28, 20:10:02
H!

Ich habe eine Frage zu C. Ist es moeglich aus einem C-Programm ein anderes C-Programm aufzurufen und diesem per stdin Inhalte zu uebergeben? Also wie wenn ich in der Shell ./prog < datei aufrufen wuerde (nur soll natuerlich vorher keine Datei erstellt werden).

Aqua

Demirug
2005-04-28, 20:20:49
Mit reinem C wird das nichts.

Dafür musst du auf Funktionen des Betriebssystem zurückgreifen.

Aqualon
2005-04-28, 20:51:29
Ok, weisst du wie ich das unter Linux bewerkstelligen kann? Falls nicht ist es auch nicht so wild, muss ich mir halt was anderes einfallen lassen.

Aqua

Gast
2005-04-28, 21:09:00
ja, das ist möglich. Du musst nur in deinem Programm pipes einrichten. Google mal nach "pipes" und "linux".

Gast
2005-04-29, 08:07:23
Die Funktion, mit der man das machen kann hieß iirc popen. (Pipe open)

Googlen sollte einige Treffer ausspucken.

Coda
2005-04-29, 10:18:19
Öh, tut's nicht auch ne Shell Pipe (prog | prog2 etc.)?

Aqualon
2005-04-29, 10:50:53
Danke fuer eure Tips, werd mich da mal genauer einlesen.

Es geht naemlich darum, dass wir eine kleine Shell programmieren sollen und ich wuerde der gerne die Moeglichkeit verpassen Programme mit < Operator zu starten. Welches Programm gestartet werden soll, kann ich ja leicht auslesen und ich seh auch die Datei, die an das Programm gepiped werden soll. Nur ist mir bisher noch keine Moeglichkeit eingefallen, wie ich den Inhalt der Datei an den stdin des aufzurufenden Programms schicken kann (gehen muss das ja irgendwie, die bash kann es schliesslich).

Werd mir mal die Sache mit den pipes genauer anschauen, vielleicht komm ich auf eine Loesung.

Aqua

stabilo_boss13
2005-04-29, 11:25:01
prog1:

#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
cout << "test";
}

prog2:

#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
cout << "von prog1: ";
for(char c = cin.get(); cin.good(); c = cin.get())
cout << c;
}


Befehlszeile: prog1 | prog2

Läuft unter Linux und Windows.

beos
2005-04-30, 13:16:51
H!

Ich habe eine Frage zu C. Ist es moeglich aus einem C-Programm ein anderes C-Programm aufzurufen und diesem per stdin Inhalte zu uebergeben? Also wie wenn ich in der Shell ./prog < datei aufrufen wuerde (nur soll natuerlich vorher keine Datei erstellt werden).

Aqua

Du kannst Programm A forken und dann mit exec Programm B starten
Einfach mal nach fork() googlen

del_4901
2005-04-30, 14:35:58
Danke fuer eure Tips, werd mich da mal genauer einlesen.

Es geht naemlich darum, dass wir eine kleine Shell programmieren sollen und ich wuerde der gerne die Moeglichkeit verpassen Programme mit < Operator zu starten. Welches Programm gestartet werden soll, kann ich ja leicht auslesen und ich seh auch die Datei, die an das Programm gepiped werden soll. Nur ist mir bisher noch keine Moeglichkeit eingefallen, wie ich den Inhalt der Datei an den stdin des aufzurufenden Programms schicken kann (gehen muss das ja irgendwie, die bash kann es schliesslich).

Werd mir mal die Sache mit den pipes genauer anschauen, vielleicht komm ich auf eine Loesung.

Aqua

Tu-Cottbus, BS III ?

Aqualon
2005-05-01, 23:34:18
[...]

Befehlszeile: prog1 | prog2

Läuft unter Linux und Windows.Ok, so könnte es gehen, aber damit wird die Problematik ja an die bash ausgelagert. Es müsste aber doch auch gehen dies ohne Verwendung der zugrundeliegenden Shell hinzukriegen.

Du kannst Programm A forken und dann mit exec Programm B starten
Einfach mal nach fork() googlenDass so die Shell grundsätzlich funktioniert ist mir klar. Nur wie ich dann Programm B starte und dem über stdin etwas zuführen kann ist die Frage... Ginge es vielleicht im Vaterprozess von A abzuwarten, bis der child-Prozess durch das exec weg ist und dann einfach die Daten auf den stdin auszugeben? Sollte doch dann bei Programm B ankommen.

Tu-Cottbus, BS III ?Nein, FAU Erlangen, SOS1.

Aqua

beos
2005-05-02, 01:04:12
Bei der Excl Familie kann man doch Parameter an das auszuführende Programm
übergeben...

Coda
2005-05-02, 01:21:23
Blöde Antwort vielleicht, aber schau doch mal im bash Sourcecode nach...

stabilo_boss13
2005-05-03, 11:28:08
Du könntest auch per Parameter die Daten übergeben:
Programm1:#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
system ("./main2 test1 test2");
}
Programm2:#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
cout << "von prog1: ";
for(int x=1;x<argc;x++)
cout << argv[x] << endl;
}Unter Windows heisst die Funktion "ShellExecute".

beos
2005-05-03, 11:58:14
Das ist aber alles C++....Aqualon wollte doch in C programmieren



Das ^^ war ich. Entschuldigung. Bitte löschen.

Du könntest auch per Parameter die Daten übergeben:
Programm1:#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
system ("./main2 test1 test2");
}
Programm2:#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
cout << "von prog1: ";
for(int x=1;x<argc;x++)
cout << argv[x] << endl;
}Unter Windows heisst die Funktion "ShellExecute".

stabilo_boss13
2005-05-03, 14:18:18
Das ist aber alles C++....Aqualon wollte doch in C programmierenNaja, das einzige in C++ ist die Ausgabe. Ich denke Aqualon wird wissen, wie man cout durch printf ersetzt. ;)

beos
2005-05-04, 01:32:54
Naja, das einzige in C++ ist die Ausgabe. Ich denke Aqualon wird wissen, wie man cout durch printf ersetzt. ;)

Und

#include <iostream>
using namespace std;

aber im Grunde hast du natürlich recht :)

Coda
2005-05-04, 02:01:37
using namespace std ist böse :rolleyes:

Trap
2005-05-04, 02:17:09
Es gibt 1000 Dinge die schlimmer sind als using namespace std

Wenn using namespace std das größte Problem an einem Programm ist, ist das ein Grund zum Jubeln.

Tom Servo
2005-05-04, 07:53:23
Habe mal schnell ein einfaches Beispielprogramm geschrieben. Ist zwar jetzt kein exec(2) enthalten, aber das Prinzip bleibt dasselbe. exec() lädt nur neuen Programmcode, aber die alten Filedeskriptoren bleiben geöffnet. Man verbindet also vor dem exec() einfach den Deskriptor 0 mit einer Eingabedatei oder einer Pipe und der mit exec() geladene Code liest dann von dieser Umleitung statt von der Console.


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

char buf[1024];

void bailout()
{
perror("pipe-test: ");
exit(1);
}

int main()
{
int fids[2];
pid_t pid;

if (pipe(fids) != 0)
bailout();

pid = fork();

if (pid == -1)
bailout();

if (pid != 0) {
/* Parent process */

// redirect standard output to pipe input
if (dup2(fids[1], 1) == -1)
bailout();

// write a line to stdout
puts("Parent process: this is printed to stdout");

} else {
/* child process */

// redirect standard input to pipe output
if (dup2(fids[0], 0) == -1)
bailout();

/*(hier könnte man mit exec() ein anderes Programm laden
welches dann statt dem folgenden Code ausgeführt würde) */

// read a line from stdin
gets(buf);

// show the user the line we got from stdin
fprintf(stderr, "Child process: read from stdin: <%s>\n", buf);

}

return 0;
}

Aqualon
2005-05-05, 00:56:09
Cool, vielen Dank Tom :)

Ist ja gar nicht so schwer, wenn man mal das Prinzip verstanden hat.

Aqua