PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Harter C-(Unix)-Stoff



Deever
18-03-2004, 20:24
Hey Amigos, wie geht's?

Ich habe ein paar Fragen zu Unix/C, die ich mir trotz Google und gcc nicht endgültig klären kann!

1. Was macht eigentlich _genau_ die Startup-Routine? Gemäss ANSI-C müssen nicht explizit initialisierte, globale Variablen mit 0 vorbelegt werden, macht die z.B. das, oder werden die vom Kernel genullt?

2. Entspricht die Startup-Routine dem Entry-Point, der im ELF-Header angegeben ist?

3. Man kann ja auch Textdateien aufrufen, sofern sie auführbar sind und der Kern übergibt der Routine den Pfad zur aufgerufenen Textdatei, nicht den hinter '#!' angegebenen. Was passiert, wenn kein "Interpreter" angegeben ist? Wird /bin/sh genommen?

4. Was sind die Parameter der Routine? Sind die standardisiert?


Hoffe, das reicht. Es werden aber sicher noch mehr Fragen kommen! ;)
Vielen Dank für eure Antworten!
Gruß,
dev

cyneox
19-03-2004, 15:21
zu 3. : das "#" - zeichen ist um sh den interpreter zu übergeben...alle ausführbare dateien haben am anfang sowas wie so n magic-key: elf-dateien haben dementsprechend ELF am anfang; shell-scripts !#/bin/sh usw.

zu 1. : die startup-routine entspricht der funktion main() ...es is genau der entry-point im ELF...die nicht initialisierten variablen werden in der sektion .bss gespeichert ( die initialisierten variable in .data -->mehr dazu:besorg dir ein ELF-tutorial) .ob die nicht initialisierten variable vom kernel genullt werden,weiss ich nicht..muss du ausprobieren:


...
main()
{
int i;
printf("%d\n",i);
exit();
}

panzi
19-03-2004, 16:00
@1. "Gemäss ANSI-C müssen nicht explizit initialisierte, globale Variablen mit 0 vorbelegt werden, macht die z.B. das, oder werden die vom Kernel genullt?"

Also der Kernel wird das sicher nicht machen. Ich schätze der Compiler muss um ANSI konform zu sein halt einfach code generieren, der die Variablen nullt.


@3. "Was passiert, wenn kein "Interpreter" angegeben ist? Wird /bin/sh genommen?"

Ja ich denk dann wird die default shell genommen.

fs111
19-03-2004, 23:16
Original geschrieben von panzi

@3. "Was passiert, wenn kein "Interpreter" angegeben ist? Wird /bin/sh genommen?"

Ja ich denk dann wird die default shell genommen.

Ich habe das gerade mal getestet. Ich habe einfach eine Datei namens foo.bar angelegt, "sentenv" hinein geschrieben, also das Äquivalent zu export bei (t)csh und eine tcsh gestartet. Wenn ich nun die Datei aufrufe sagt er

[FS111@Hermes ~]$ ./foo.bar
./foo.bar: line 1: sentenv: command not found

obwohl das ja ein gültiger Befehl dieser Shell ist. Meine Standardshell ist aber die bash. Ich denke also, dass $SHELL aufgerufen wird, wenn nichts in der ersten Zeile steht.

fs111

panzi
20-03-2004, 00:20
echo $SHELL
echo "sleep 10" > testscript
chmod a+x testscript
ps
./testscript & ps


Also diese Anweisungen sagen bei mir das in $SHELL bei mir /bin/bash steht, testscript aber mit /bin/sh ausgeführt wird.

Achja, und warum "sentenv"? :confused:
Warum das n? Stimmt das tatsächlich so?


Edit: Ich denk /bin/sh ist für solche Sachen immer da, denn auch system() ruft /bin/sh auf:
man system (http://unixhelp.ed.ac.uk/CGI/man-cgi?system)

Deever
20-03-2004, 09:05
Original geschrieben von cyneox
zu 3. : das "#" - zeichen ist um sh den interpreter zu übergeben...
Hmm? Wie soll das gehen? /bin/sh (also z.B die bash) erhält also z.B. /bin/zsh in argv[0] und soll die ZShell dann exec()en?


zu 1. : die startup-routine entspricht der funktion main()
Nein, vor dem Aufruf von main() müssen z.B. noch die Environment-Variablen geschrieben werden, dafür brauchts noch Code vor main()! ;)


die nicht initialisierten variablen werden in der sektion .bss gespeichert ( die initialisierten variable in .data -->mehr dazu:besorg dir ein ELF-tutorial).
Stimmt! Von solchen Sektionen hab ich schon gehört, aber ob die zwingend mit ELF zutun haben? Schliesslich gab es C/Unix schon lange vor ELF...


ob die nicht initialisierten variable vom kernel genullt werden,weiss ich nicht..muss du ausprobieren:


...
main()
{
int i;
printf("%d\n",i);
exit();
}

Nein, ich meine globale nicht-initialisierte Variablen!
BTW! :): Dieses Programm demonstiert eindrücklich die Qualität des Speichermanagementsystems von Linux!

deever@floatkiller:~ $ for (( i=0; i<100; i++)) { ./test }
123
123
123
123
123
[...]
Der reservierte Speicherbereich wird nach dem Ende des Programms offenbar nicht sofort freigegeben!


Original geschrieben von panzi
Also diese Anweisungen sagen bei mir das in $SHELL bei mir /bin/bash steht, testscript aber mit /bin/sh ausgeführt wird.
Ja, gemäss POSIX ist aber /bin/sh ein Link auf die Shell des Systems!


Ich hab gerade in Herolds Buch "Systemprogrammierung" nachgelesesn und was sehen meine müden Augen da unter "bss segment"?

[...]Daten dieses Segments werden vom Kern beim Prozeßstart mit 0 initialisiert. [...]

So langsam versteh ich den Spruch "Auch Windows ist ein Unix-System, es wurde ja in C geschrieben"!
Danke für eure Antworten, Leute!
Gruß,
dev

fs111
20-03-2004, 12:10
Original geschrieben von panzi


echo $SHELL
echo "sleep 10" > testscript
chmod a+x testscript
ps
./testscript & ps


Also diese Anweisungen sagen bei mir das in $SHELL bei mir /bin/bash steht, testscript aber mit /bin/sh ausgeführt wird.

Achja, und warum "sentenv"? :confused:
Warum das n? Stimmt das tatsächlich so?


Nein, das 'n' war ein Tippfehler (war zu spät gestern ;-)), aber ich habe es gerade korrigiert und noch mal probiert, und das Ergebnis ist das gleiche.

fs111

panzi
20-03-2004, 12:53
Original geschrieben von Deever
[...]Daten dieses Segments werden vom Kern beim Prozeßstart mit 0 initialisiert. [...]

Tatsächlich. Aha, dachte nicht, dass das der KERNEL macht. Dachte eben eher, dass das auch Code, der noch vor main() vom Compiler eingefügt wurde, macht.
Interessant.

nobody0
22-03-2004, 13:36
Original geschrieben von panzi
Tatsächlich. Aha, dachte nicht, dass das der KERNEL macht. Dachte eben eher, dass das auch Code, der noch vor main() vom Compiler eingefügt wurde, macht.
Interessant.

Nach dem Standard (C99) wird main gestartet; wenn noch etwas davor steht, dann gehört das zum Environment und nicht zum C-Code. Aber man kann main ja auch von main aufrufen und so Parameter setzen wie man will.