Hallo peterfido,
mal vorweg, ich kann deine Probleme und den Frust nachvollziehen, aber ich denke du machst zu Unrecht C dafür verantwortlich.
Alles was du beschreibst, hat mit C wenig zu tun, sondern resultiert aus dem Zusammenwirken oder auch Gegeneinanderwirken von eigenem Programmcode, C-Library und einem Multiuser/Multitasking Betriebssystem. Dazu kommen dann noch andere Programme, gern Kommandos genannt, die man selbst nicht unter Kontrolle hat, und deren Umfang man machmal nicht ahnt.
Ich versuche das mal an einem deiner Beispiele zu erläutern:
Um ein Programm zu starten (oder im Filesystem zu lesen und zu schreiben, etc), gibt es Systemcalls, die das Betriebssystem veranlassen das zu tun. Die Mechanismen dazu sind auf jedem System und auf jedem Prozessor andere. Eigentlich will der Programmierer das auch garnicht wissen, daher gibt es fertige Funktionen in der C-Library, die das für ihn erledigen (Das gilt natürlich nur, wenn es ein Betriebssystem und/oder ein Filesystem überhaupt gibt). Ein Programm unter Unix zu starten, geht (vereinfacht) so: zuerst wird eine identische Kopie des startenden Programms mit fork() erzeugt. Dann überlädt das erzeugte Programm seinen Code mit dem neuen Programm und setzt möglicherweise noch argv[] auf. Manchmal ist auch noch mehr zu tun. Wenn du das genauer wissen willst, schau dir die man-page von fork() an, und lies dann weiter was unter "SEE ALSO" kommt. Das ganze ist aber nicht Teil von C sondern UNIX, und wird auf einem anderen Betriebssystem anders aussehen.Ursprünglich sollte alles ein Programm erledigen. Jedoch habe ich es nicht geschafft, wie im BASH ein Programm im Hintergrund /bzw. unabhängig von meinem aufzufrufen. Im BASH wird einfach ein & am Ende des Aufrufes gehängt. Zur Not noch ein disown hinterher. Alles dies klappt per C-Programm nicht mehr. Selbst, wenn ich eine BASH aufrufe, welches dann das nächste Programm mittels "& disown" startet, wartet mein Programm solange, bis die Kette an Sripten und Programmen dazwischen beendet wurden.
Da nicht jeder ein Programm schreiben und kompilieren will, nur um den Inhalt einer Datei zu lesen oder ein Programm zu starten, hat sich im Laufe der Zeit ein ganzer Zoo von Utilities und Hilsprogrammen entwickelt. Dies geht los mit so einfachen Dingen wie echo oder cat und endet bei sed oder der Commandshell (von denen die bash nur eine von vielen ist), die dann nicht nur durch Parameter sondern auch durch Textfiles gesteuert werden können. Alles dies sind aber auch nur Anwenderprogramme, die auf der gleichen Ebene funktionieren, wie dein eigenes Programm.
Wenn in einem Steuerfile für die Shell an der richtigen Stelle ein & steht, wird also mittels der oben beschriebenen Systemcalls das Programm geforkt, ... und beide laufen nebeneiander weiter. So haben sich die Shell-Erfinder das ausgedacht. Wenn im richtigen Kontext ein | steht, werden die Programme links und rechts vom | gestartet (wie gehabt) und der Output des linken wird auf den Input des rechten geleitet. Ob ein anderes Programm als die Shell das & oder das | gleich verwendet, ist nicht gesagt.
Für C ist & der "binary and" und | der "binary or" Operator (und innerhalb eines char Arrays, auch gerne String genannt, ist es ein 38 oder 124 und damit nicht mehr als ein gültiger Wert, d.h. 0 <= 38 <= 255).
Hier wird ein Missverständniss deutlich. In C ändert man die Dateirechte durch einen Call von chmod() oder fchmod(), am besten kümmert man sich darum, wenn man die Datei mit open() oder creat() erzeugt. Du rufst dagegen via system() das externe Programm chmod auf, und läßt das die Arbeit tun. Ja, und system() startet eine Shell, die dann die Zeile "chmod 644 /tmp/webif.farben" gegebenenfalls nach Ersetzung von Wildcards ausführt.Dann sollen vom AVR ankommende Parameter in einer Datei gespeichert werden, damit der php-Code des WebIf diese auslesen kann. Konnte es natürlich nicht. Die Rechte der vom C-Programm angelegten Datei waren mal 600 und dann plötzlich mal 140 oder 104. Also nach dem Erstellen der Datei noch ein system("chmod 644 /tmp/webif.farben"); hinterher.
Für die Sprache C sind das aber nur Funktionsaufrufe: Name, rund Klammer auf, Übergabeparameter, rund Klammer zu, Semikolon. Im passenden Headerfile steht das Format der Parameter, damit der Compiler das checken kann, und der Linker muß die Adresse der Funktion auflösen können. Der Inhalt der Parameter interessiert C kein Stück. Bei deinem Beispiel mit system gilt:
int system(const char *txtptr);
so stehts im Headerfile. Was an der Stelle steht, wo txtptr hinzeigt und was das Betriebssystem dann daraus macht, ist dessen Sache.
Der Text ist ja ganz schön lang geworden, ich will mal versuchen einen Abschluß zu finden. Die Steuerung eines Systems durch direkte Library/Systemcalls kann ganz schön komplex werden. Die Beschreibung der libc umfasst einige tausend Seiten und füllt dazu noch eine ganze Bücherei. Ob du dir das antuen willst, weiß ich nicht. Ich würde eher die Hilfe der anderen verwenden, und eine Scriptsprache verwenden. Unter diesen ist aber die Shell/bash die problematischste. Die Syntax ist durch ewiges Anflicken und kryptische Kürzel von tipfaulen Programmierern alles andere als übersichtlich. Ein Syntaxcheck findet nur beim Ausführen der jeweiligen Zeile statt. Scripte, die lange gut laufen, können plötzlich Syntaxfehler bringen, weil ein if jetzt False statt True liefert. Perl oder PHP sind da die bessere Wahl.
MfG Klebwax
Lesezeichen