Guten Morgen Henryk,
Nach dem Script-Start habe ich die Datei von der Konsole aus gelöscht, was ja nicht gehen dürfte, wenn es sich bei flock um eine Kernelfunktion handeln würde.
Außerdem dürfte auch kein zweiter Prozess (der das Locking Verfahren nicht beachtet) aus dem Deamon oder dem Apache auf die Datei zugreifen können, wenn sie auf Kernelebene gelockt würde. Aber eben genau das ist möglich.
QED
Unix-Systeme sind nicht so schlecht wie Windows-Systeme.
den Satz streichen wir bitte. Ich bin auch kein Microsoft(-Windows)-Fan, aber bei einer sachlichen Diskussion sollte diese Art der Polemik draußen bleiben.
Selbstverständlich verfügen die meisten netzwerk- oder mutliuser- oder multiprozessfähigen Betriebssysteme über einen Lockingmechanismus auf Systemebene. Die einfacheren über Filelocking, die etwas besseren über Pagelocking (also Clusterweise) und die guten über Recordlocking, wobei das Recordlocking in der Regel byteweise läuft. Man kann Bereiche von...bis in der Datei sperren. Wenn man vergessen hat, wo die Sperre saß, hat man Pech gehabt. Dann muss man das Handle zurückgeben. Wenn man Glück hat, werden die Sperren dan aufgehoben. Novell hatte diesen Bug bis Version < 3.x.
Du kannst _immer_ eine Datei problemlos löschen, verschieben oder umbenennen während ein Prozess sie geöffnet hat.
Das ist eine Frage der Voreinstellung des "extended Filemode". Die normalen Filemodes lauten w, w+, r, r+, a, a+ ...
Leider haben die Entwickler von C hier einen Fehler eingebaut. Es werden für die Übergabe an die Interrupt-Handler keine numerischen Konstanten übergeben, sondern echte Strings. Diese werden dann erst in den einzelnen Interrupt-Handlern von fopen() etc. interpretiert. Aus diesem Grunde kann man das Highnibble des Filemode-Bytes nicht direkt ansprechen in C. In Pascal ist das ohne weiteres möglich. Ich werde nachher mal versuchen, auf dem Linux-Host einen Pascal-Compiler zum Laufen zu bringen und dann ausprobieren, obs klappt.
Aber ich denke, bei Zugriff über C auf die API gibt es da auch eine Systemvariable, die man vor dem Aufruf der Funktion setzen kann. Ich habe sie nur noch nicht gefunden (auch unter DOS/Windows noch nicht). Und ich kenne leider keine C-Programmierer, die da so tief eingestiegen sind. Bis zum Filemode ist alles noch plattformunabhängig. Erst die API ist für die Übersetzung auf die jeweilige Maschine verantwortlich.
Wenn der Prozess nämlich die Datei öffnet, bekommt er nur einen Filehandle zurück und wenn er den erstmal hat ist der Dateiname nicht mehr nötig. Intern wird nur noch mit dem Handle gearbeitet, d.h. kannst nun ausserhalb mit dem Dateinamen anstellen was du willst.
Mit dem Namen schon. Ich darf nur nicht versuchen, ihn ein zweites Mal mit einem Handle auf die Datei zu verbinden. Wenn diese gelockt ist, nützt mir der Name gar nicht viel. Ich komme dann nur noch an den Dateideskriptor (sozusagen der "Header"), nicht jedoch an den Datenbereich der Datei.
Interessant ist nun noch der Versuch, ob die Daten im Handle kopiert werden, oder ob nur die Handlereferenz an den Prozess weitergegeben wird. Im zweiten Falle könntest Du, während eine Applikation schon ein Handle auf die Datei besitzt, von einem anderewn Prozess aus die Zugriffsrechte ändern (das ist "nur" namnesbasiert, dafür braucht man kein Handle) und es hätte Auswirkungen auf den ersten Prozess.
Es gibt (IIRC) nicht mal eine eindeutige Möglichkeit vom Handle auf den Dateinamen zu schliessen (zumindest nicht zwingend auf allen Systemen). Das kann ja auch gar nicht gehen, weil Unix-Systeme in der Regel auch Hardlinks kennen, also mehrere Dateinamen für die selbe Datei.
Vom Handle auf den Dateinamen schließen? Das muss möglich sein, zumindest auf der Systemebene. In der Handle-Tabelle wird der Name der Datei eingetragen. So wird sie nämlich mit dem Handle verbunden. Wenn man also die lage der Handle-Tabelle im Speicher kennt, kann man si natürlich auslesen. Voraussetzung, man het ein gültiges Gate auf den Speicherbereich (Local Desriptor). Sonst klopft einem das OS auf die Finger. Wir arbeiten ja schließlich im protected meode (PCs).
Wenn du die Datei 'löscht' während sie noch geöffnet ist, wird einfach nur dieser eine Dateiname entfernt und der Linkcounter um eins verringert. Wenn der Counter auf 0 steht und die Datei geschlossen wird, wird der ihr zugewiesene Speicherplatz freigegeben. Umbenennen ist völlig problemlos und Verschieben entspricht kopieren und löschen.
Was das weitere angeht: fcntl ist immer advisory locking: http://www.gnu.org/manual/glibc-2.0.6/html_chapter/libc_8.html#SEC146. Es gibt zwar auch mandatory locking (http://web.systhug.com/kernel-lock/) aber das riecht nach einer Linux-Extrawurst und ist wahrscheinlich nicht portabel.
Mit diesem Abschnitt werde ich mich noch beschäftigen. Hast Du einen Link zur Linux-API? Ich würde mich gerne mal mit den System- und Netzwerkinterrupts auseinandersetzen. Eigentlich kann man erst danach mehr sagen zum Thema Locking.
Jedenfalls hast Du bestätigt, dass es in PHP um "advisory Locking" geht. Also Quasi nur eine Verkehrsregel. man kann sie beachten oder auch nicht...
Lieb Grüße aus http://www.braunschweig.de
Tom