Hi,
ich stehe wieder mal auf dem Schlauch: wie finde ich in einem C-Programm den vollständigen Pfad zu argv[0], wenn dort z.B. nur "gcc" drin steht? Ich suche eine Funktion, die mir in diesem Fall "/usr/bin/gcc" zurück gibt.
Viele Grüße, Torsten
Torsten Werner mail.twerner@googlemail.com (Do 03 Apr 2008 15:08:18 CEST):
Hi,
ich stehe wieder mal auf dem Schlauch: wie finde ich in einem C-Programm den vollständigen Pfad zu argv[0], wenn dort z.B. nur "gcc" drin steht? Ich suche eine Funktion, die mir in diesem Fall "/usr/bin/gcc" zurück gibt.
Ich *glaube*, es ist nirgens definiert, daß in argv[0] etwas sinnvolles steht, es bleibt ganz dem Aufrufer überlassen, dort was relevantes reinzutun.
Daß es der Pfad zum Executable ist, ist vielleicht Konvention. Aber beispielsweise muß das Executable gar nicht mehr existieren oder kann ausgetauscht sein, wenn Du den Namen rausgefunden hast.
Aber über /proc/<PID>/exe findest Du zumindest einen Link zum Executable (wo der hinweist, wenn das File inzwischen durch ein anderes ausgetauscht wurde, weiß ich nicht. Wahrscheinlich muß man sich dann selbst kümmern (Inodes vergleichen u.ä.) Aber vielleicht brauchst Du's ja nicht so kompliziert.
Und vielleicht gibt's auch eine bessere Antwort auf die Frage und irgendwo in der glibc steckt eine passende Funktion.
Am Donnerstag 03 April 2008 15:19:04 schrieb Heiko Schlittermann:
Ich *glaube*, es ist nirgens definiert, daß in argv[0] etwas sinnvolles steht, es bleibt ganz dem Aufrufer überlassen, dort was relevantes reinzutun.
Exakt. execl("/usr/bin/schnüffelprog", "kdeinit")
Und für die Änderung zur Laufzeit: man prctl
Josef
Hallo, Josef Spillner wrote:
Am Donnerstag 03 April 2008 15:19:04 schrieb Heiko Schlittermann:
Ich *glaube*, es ist nirgens definiert, daß in argv[0] etwas sinnvolles steht, es bleibt ganz dem Aufrufer überlassen, dort was relevantes reinzutun.
Exakt. execl("/usr/bin/schnüffelprog", "kdeinit")
Und für die Änderung zur Laufzeit: man prctl
*hm* Nur mal rein interessehalber... Ich kann mich nicht recht entsinnen, aber ich dachte, irgendwann vor langer Zeit (mein Informatikstudium liegt auch schon ein paar Jahre zurück) hat das eine Zuweisung an argv[0] schon getan. Jetzt ist das aber wohl nicht mehr so:
/tmp> cat test.c #include <stdio.h> #include <unistd.h> int main(int argc, char **argv) { printf("%s\n",argv[0]); argv[0] = "hello world"; printf("%s\n",argv[0]); sleep(100); return 0; } /tmp> gcc -o test test.c /tmp> ./test ./test hello world
Aber: ps sieht trotzdem noch ein "./test". Wurde das irgendwann mal geändert im Lauf der Geschichte? Oder habe ich das was falsch in Erinnerung?
Josef
Ciao, Thomas
Hallo,
Am Freitag 04 April 2008 10:10:30 schrieb Thomas Köhler:
*hm* Nur mal rein interessehalber... Ich kann mich nicht recht entsinnen, aber ich dachte, irgendwann vor langer Zeit (mein Informatikstudium liegt auch schon ein paar Jahre zurück) hat das eine Zuweisung an argv[0] schon getan. Jetzt ist das aber wohl nicht mehr so:
Zumindest im C-Standard [0] ist Ändern von argv[] erlaubt, es steht aber nicht da ob es Auswirkungen haben soll. An dieser Stelle setzt dann auch die Betriebssystemspezifikation ein. Soweit ich weiß ist der POSIX-Standard aber nach wie vor nicht registrierungsfrei zu bekommen, da kann ich mich aber auch irren. Und da ich jetzt auch nicht in den Kernelsourcen wühlen will, denke ich mal, dass der Kernel argv[] und die sonstigen Prozessinformationen im PCB getrennt hält. Kurzum, da C es nicht definiert, ist es nicht portabel und man sollte sich darauf nicht verlassen, und prctl ist auch linuxspezifisch.
Josef
[0] http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
Hi Torsten,
On Thu, Apr 03, 2008 at 15:08:18 +0200, Torsten Werner wrote:
ich stehe wieder mal auf dem Schlauch: wie finde ich in einem C-Programm den vollstaendigen Pfad zu argv[0], wenn dort z.B. nur "gcc" drin steht? Ich suche eine Funktion, die mir in diesem Fall "/usr/bin/gcc" zurueck gibt.
readlink() auf /proc/self/exe?
Gruss, Chris
On Thu, April 3, 2008 15:08, Torsten Werner wrote:
ich stehe wieder mal auf dem Schlauch: wie finde ich in einem C-Programm den vollständigen Pfad zu argv[0], wenn dort z.B. nur "gcc" drin steht? Ich suche eine Funktion, die mir in diesem Fall "/usr/bin/gcc" zurück gibt.
Die portable aber unsichere Variante:
Schauen ob es nur ein Dateiname oder ein (relativer/absoluter) Pfad ist (enthaelt ein "/"). Falls Pfad: fertig. Falls Dateiname:
$PATH variable (getenv("PATH")) auseinandernehmen und schauen was das erste Verzeichnis mit einer Datei ist die den richtigen Namen hat.
Sichere Variante, siehe Mail von Chris.
Konrad
Danke für alle Tipps!
On Thu, Apr 3, 2008 at 4:44 PM, Konrad Rosenbaum konrad@silmor.de wrote:
$PATH variable (getenv("PATH")) auseinandernehmen und schauen was das erste Verzeichnis mit einer Datei ist die den richtigen Namen hat.
Bevor ich nach Josefs Vorbild eine Tirade gegen C im Jahr 2008 zusammenschreibe, mache ich die einfache Lösung: ich kodiere /usr/bin/argv[0] hart hinein, ich weiß ja, wo es liegt. Hauptproblem war, dass bisher immer argv[0] genommen wurde, was nur funktioniert, wenn man es über absolute Pfade aufruft.
Viele Grüße, Torsten
Hallo Torsten,
Torsten Werner wrote:
Danke für alle Tipps!
On Thu, Apr 3, 2008 at 4:44 PM, Konrad Rosenbaum konrad@silmor.de wrote:
$PATH variable (getenv("PATH")) auseinandernehmen und schauen was das erste Verzeichnis mit einer Datei ist die den richtigen Namen hat.
Bevor ich nach Josefs Vorbild eine Tirade gegen C im Jahr 2008 zusammenschreibe, mache ich die einfache Lösung: ich kodiere /usr/bin/argv[0] hart hinein, ich weiß ja, wo es liegt. Hauptproblem war, dass bisher immer argv[0] genommen wurde, was nur funktioniert, wenn man es über absolute Pfade aufruft.
Irgendwie beschleicht mich der Verdacht, du hast letzten Endes irgendwas vor, was mit fork() stressfreier geht. Oder wozu genau brauchst du den absoluten Programmnamen zur Laufzeit?
Ciao, Thomas
Hallo Thomas,
On Fri, Apr 4, 2008 at 10:19 AM, Thomas Köhler jean-luc@picard.franken.de wrote:
Irgendwie beschleicht mich der Verdacht, du hast letzten Endes irgendwas vor, was mit fork() stressfreier geht. Oder wozu genau brauchst du den absoluten Programmnamen zur Laufzeit?
ich möchte jexec.c in openjdk-6 fixen, weil man das derzeit nur mit kompletten Pfad aufrufen kann. Wenn man einen Symlink zum Binary in /usr/bin ablegt und als jexec aufruft, bricht es, weil es sich selbst nicht findet. Genau genommen findet es die Java-Installation nicht, die es mittels realpath(argv[0], ...) bestimmt.
Viele Grüße, Torsten
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Torsten Werner schrieb: | ich möchte jexec.c in openjdk-6 fixen, weil man das derzeit nur mit | kompletten Pfad aufrufen kann. Wenn man einen Symlink zum Binary in | /usr/bin ablegt und als jexec aufruft, bricht es, weil es sich selbst | nicht findet. Genau genommen findet es die Java-Installation nicht, | die es mittels realpath(argv[0], ...) bestimmt.
Falls Du abschreiben willst: Hast Du Dir mal texlive angeguckt? Die suchen auch das Verzeichnis relativ zum binary.
Keine ahnung, wie die das lösen.
Tobias
On 04.04.08 Tobias Schlemmer (keinstein_junior@gmx.net) wrote:
Moin,
Hast Du Dir mal texlive angeguckt? Die suchen auch das Verzeichnis relativ zum binary.
-vvv: wo?
H.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hi,
Hilmar Preusse schrieb: |> Hast Du Dir mal texlive angeguckt? Die suchen auch das Verzeichnis |> relativ zum binary. |> | -vvv: wo?
Bin nur mal im Zusammenhang mit tex4ht drauf gestoßen. Ich habe grade mal geguckt: Es scheint in kpathsea zu stecken. Ein guter Start könnte progname.c sein.
Tobias
Hallo Tobias,
On Fri, Apr 04, 2008 at 10:39:42 +0200, Tobias Schlemmer wrote:
Falls Du abschreiben willst: Hast Du Dir mal texlive angeguckt? Die suchen auch das Verzeichnis relativ zum binary.
Ich habe doch schon eine Loesung genannt. readlink() auf /proc/self/exe. Damit bekommt man den vollen Pfad des Binaries und kann sich daraus auch entsprechende Pfade konstruieren.
Gruss, Chris
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Christian Perle schrieb: | Hallo Tobias, | | On Fri, Apr 04, 2008 at 10:39:42 +0200, Tobias Schlemmer wrote: | |> Falls Du abschreiben willst: |> Hast Du Dir mal texlive angeguckt? Die suchen auch das Verzeichnis |> relativ zum binary. | | Ich habe doch schon eine Loesung genannt. readlink() auf | /proc/self/exe. Damit bekommt man den vollen Pfad des Binaries und kann | sich daraus auch entsprechende Pfade konstruieren.
Hatte nicht Torsten nach einer _portablen Lösung gesucht?
auf Mac OS X:
nalp17:~/Entwicklung/tonsystem-calc schlemme$ ls -l /proc/self/exe ls: /proc/self/exe: No such file or directory nalp17:~/Entwicklung/tonsystem-calc schlemme$
Tobias
Konrad Rosenbaum konrad@silmor.de (Do 03 Apr 2008 16:44:57 CEST):
On Thu, April 3, 2008 15:08, Torsten Werner wrote:
ich stehe wieder mal auf dem Schlauch: wie finde ich in einem C-Programm den vollständigen Pfad zu argv[0], wenn dort z.B. nur "gcc" drin steht? Ich suche eine Funktion, die mir in diesem Fall "/usr/bin/gcc" zurück gibt.
Die portable aber unsichere Variante:
Schauen ob es nur ein Dateiname oder ein (relativer/absoluter) Pfad ist (enthaelt ein "/"). Falls Pfad: fertig. Falls Dateiname:
Ich bin immer noch der Meinung, daß es ein Trugschluß ist, anzunehmen, daß dort *irgend* etwas drinsteht, was mit dem aufgerufenen Binary in Zusammenhang steht. (s. z.B. "-bash", bekommt die "/bin/bash" vom Login beim Start dort in argv[0] rein).
Beim inetd ebenfalls: dort gibst Du das Programm und dann argv[0]..[n] an.
$PATH variable (getenv("PATH")) auseinandernehmen und schauen was das erste Verzeichnis mit einer Datei ist die den richtigen Namen hat.
export -n PATH PATH=/x/y/z program
Was sieht das Programm dann in PATH? NICHTS. Weder portabel noch sicher. Aber eigentlich schon dort die o.a. Dinge nicht nutzber - es muß in argv[0] nichts stehen, was Du im PATH finden kannst.
On Thursday 03 April 2008, Heiko Schlittermann wrote:
Ich bin immer noch der Meinung, daß es ein Trugschluß ist, anzunehmen, daß dort *irgend* etwas drinsteht, was mit dem aufgerufenen Binary in Zusammenhang steht.
Da stimmer ich dir voll zu. Aber: Kennst Du eine andere Methode, die nicht auf Linux beschränkt ist? Ich nicht.
Also mal wieder "lieber Einbildung als gar keine Bildung"... ;-)
Konrad
Torsten Werner schrieb:
Hi,
ich stehe wieder mal auf dem Schlauch: wie finde ich in einem C-Programm den vollständigen Pfad zu argv[0], wenn dort z.B. nur "gcc" drin steht? Ich suche eine Funktion, die mir in diesem Fall "/usr/bin/gcc" zurück gibt.
Du könntest bei einem relativen Pfad bzw. Dateinamen das Arbeitsverzeichnis berücksichtigen. Du kannst es mit getcwd() bekommen. Wie Heiko schon schrieb ist es aber nur eine Konvention, das argv[0] den Pfad zur Executable enthält (s. a. man execl).
Grüße,
Lars
lug-dd@mailman.schlittermann.de