Sicherstellen,dass eine wxPython-App nur 1x ausgeführt wird?

Plattformunabhängige GUIs mit wxWidgets.
oliver1974
User
Beiträge: 97
Registriert: Donnerstag 26. Oktober 2006, 15:01

Ich muss mal diesen alten Thread wieder nach vorne holen...

Mir ist da noch eine Sache aufgefallen, die unter Umständen für die Geschichte für Linux-Zielplattformen von Belang sein könnte... Das mit den Speichern der Sperrdatei in "/var/lock" könnte schiefgehen, da offensichtlich einige Distributionen eine etwas eigenwillige Interpretation der Rechte in diesem Verzeichnis haben... Wenn das Python-Skript mit "normalen" Benutzerrechten läuft, so hat es unter Umständen kein Schreibrecht auf "var/lock", je nachdem wie die Distri das so handhabt. Under Kubuntu (6.0.6 und 6.10) ist es kein Problem, da dort jeder schreiben darf, unter Mandriva (zumindest 2007.0, aber wenn ich einige alte LinuxUser-Artikel bezüglich anderer Applikationen mit ähnlichem Problemen richtig deute, auch schon ältere Versionen) aber zum Beispiel "von Haus aus" wieder nicht!

Entweder man passt nun die Rechte des Verzeichnisses an (kommt aber irgendwie schlecht rüber.. "ähh, für mein Programm müssten Sie mit Admin-Rechten erstmal etwas an den System-Verzeichnissen basteln) oder
man überlegt sich doch noch was anderes... Ich muss mir das mal ansehen.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Davon ist in /var/lock schreiben nicht unbedingt schlau auf Multiuser-Systemen. Wenn ein User das Programm offen hat, kann ein anderer das nicht mehr. Viele Betriebssysteme ermöglichen es, mehrere User auch grafisch einzuloggen, daher kommt dieses Problem noch erschwerend hinzu.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
oliver1974
User
Beiträge: 97
Registriert: Donnerstag 26. Oktober 2006, 15:01

Hmmm, berechtigter Einwand... Insofern müsste man sich den Code noch mal ganz neu ansehen....
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Leonidas hat geschrieben:Davon ist in /var/lock schreiben nicht unbedingt schlau auf Multiuser-Systemen. Wenn ein User das Programm offen hat, kann ein anderer das nicht mehr. Viele Betriebssysteme ermöglichen es, mehrere User auch grafisch einzuloggen, daher kommt dieses Problem noch erschwerend hinzu.
Hi!

Bei näherem Überlegen, scheint es sinnvoll, zu unterscheiden, ob ein Programm "global", also in der Betriebssystem-Instanz, oder "lokal", also nur für den Benutzer, nur einmal laufen darf.

Ein HTML-Server, der auf Port 80 horcht, sollte "global" nur einmal gestartet werden können.

Ein Programm mit GUI, das dem Benutzer ein paar Werte anzeigt, könnte auf einem System auch öfter ausgeführt werden, aber sollte (wenn gewünscht) nur einmal für den Benutzer ausgeführt werden.

Wie löst man diese Problematik? Beim Entwickeln des Programms könnte man einen Parameter setzen, der dieses Verhalten regelt.

Es ist kein Problem, eine Datei im Home-Ordner des Benutzers für solche Dinge heran zu ziehen. Die Schwierigkeit tritt auf, wenn ich ein Programm "global" sperren möchte. Wohin schreibe ich das Lockfile? Ein normaler Benutzer hat weder unter Windows noch unter Linux das Recht überall hin zu schreiben.

Gibt es einen Ort, an dem jeder Benutzer eines Systems eine Datei (exakt benannte) erstellen, bearbeiten und löschen darf?
Unter Linux könnte ich mir vorstellen, dass ``/tmp`` so ein Ort sein könnte. Aber unter Windows zeigt die Umgebungsvariable ``%TEMP%`` bei mir auf ``J:\DOKUME~1\Gerold\LOKALE~1\Temp``. Das ist garantiert kein Ordner, in den andere Benutzer schreiben dürfen.

Weiß jemand Rat? In welchen Ordnern darf jeder Benutzer schreiben und die Dateien anderer Benutzer verändern oder löschen?

Wenn wir diese Universalordner für Windows und Linux nicht finden, dann fällt mir nur XMLRPC ein. Dann müsste man beim Eruieren der Portnummer noch den Benutzernamen mit einbeziehen, um eine "lokale" Lösung zu erhalten.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

Sollte ein Programm, dass global nur einmal gestartet werden darf nicht sowiso nur als root gestartet werden...

Und Port 80 darf ich bei mir sowiso nur als root verwenden...
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

gerold hat geschrieben:Ein HTML-Server, der auf Port 80 horcht, sollte "global" nur einmal gestartet werden können.
Dies ist sowieso sichergestellt, denn beim Versuch an einen Port zu horchen der von einem anderen Prozess schon benutzt wird, gibt es einen Fehler.
gerold hat geschrieben:Unter Linux könnte ich mir vorstellen, dass ``/tmp`` so ein Ort sein könnte. Aber unter Windows zeigt die Umgebungsvariable ``%TEMP%`` bei mir auf ``J:\DOKUME~1\Gerold\LOKALE~1\Temp``. Das ist garantiert kein Ordner, in den andere Benutzer schreiben dürfen.
Also im Explorer sehe ich einen Ordner Gemeinsame Dokumente unter XP, wenn man draufklickt kommt man in ``Dokumente und EInstellungen\All Users\Dokumente`` daher würde ich sagen, dass es möglcih wäre dass User in ``All Users`` schreiben könnten (ich denke dort ist auch ein Temp-Ordner). Allerdings finde ich es recht unlogisch, dass ``All Users`` schreibbar für nicht-Administratoren wäre.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
oliver1974
User
Beiträge: 97
Registriert: Donnerstag 26. Oktober 2006, 15:01

Hallo,

Hmmm, bei mir ist zwar auch bei der Mandriva - Installation /tmp für alle schreibbar, aber keine Ahnung, ob das mal wieder bei einer anderen Distri abweicht.

Der Linux-Filesystem-Hierarchy-Standard schweigt sich zu den Zugriffsrechten zu /tmp aus, wenn ich das richtig interpretiere.

http://www.linux.com/guides/Linux-Files ... /tmp.shtml

Allerdings ist der Fall, dass ein Programm global läuft und dann auch nur einmal laufen darf, aber keine root-Rechte hat, in meinen Augen auch eher ungewöhnlich.. das sind in der Regel Dienste und die haben root-Rechte, da wäre die Lösung mit /var/lock dann wieder okay..

Zumindest aber sollten wir das Skript so abändern, dass bei "normalen" Anwendungen, die nur mit Userrechten laufen, der Lockfile im Home-Verzeichnis des Users sitzt. das wäre zumindest sinnvoll.

Ich meine mich auch erinnern zu können, dass die first_start.py Geschichte unter MacOSX nicht sauber lief.... habe ich aber nur mal aus dem Augenwinkel kurz gesehen, dazu müsste ich die Leute mit Zugriff auf MacOSX nochmal greifen und denen meine Skripte, die first_start.py benutzen, zukommen lassen.

Die Änderung mit dem Home-Directory wäre ja noch recht einfach
(Hier mal die Änderungen, wie ich sie habe.. ab Zeile 87 vom Original
her).

Code: Alles auswählen

        if appdatadir:
            lockdir = os.path.join(appdatadir, "Lockfiles")
        else:
            env_home = os.environ.get("HOME")
            appdir = os.path.join(env_home, appname)
            lockdir = os.path.join(appdir, "Lockfiles")
            
            if not (os.path.exists(lockdir) and os.path.isdir(lockdir)):
                os.makedirs(lockdir)
Man könnte sich jetzt überlegen, ob man nicht standardmäßig bei
"appname" noch den Punkt vorne hinzufügt, so hätte man dann gleich das
Verzeichnis bei den POSIX - Systemen versteckt... oder man
lässt es so und der Benutzer von first_start.py muss halt selbst
bei der Übergabe von appname daran denken...


EDIT:
-------

Ah, mist, sehe gerade, dass sich jetzt Windows und POSIX Systeme
bei meiner Variante unterschiedlich verhalten würden, natürlich
müssten dann die Windows-Systeme auch ihre Lockfiles erstmal
primär in das Home-Verzeichnis schieben... bis wir die Lösung
für unsere "Bei Bedarf sperre global" Problem haben.
Pass ich nochmal an.
Gibt es einen Ort, an dem jeder Benutzer eines Systems eine Datei (exakt benannte) erstellen, bearbeiten und löschen darf?
Unter Linux (oder umfassender, POSIX - Systemen) steht jetzt die Lösung noch aus... aber was spricht dagegen, unter Windows XP und Co.
%APPDATA% zu nehmen, also in der Regel
C:\Dokumente und Einstellungen\All Users\Anwendungsdaten
?

Wird doch eh schon in der bisherigen Version von first_start.py
verwendet... Das würde doch der Variante für das globale Sperren entsprechen? Was war daran falsch?
oliver1974
User
Beiträge: 97
Registriert: Donnerstag 26. Oktober 2006, 15:01

Also vielleicht eher so:

EDIT: Funktioniert so natürlich noch nicht, da Windows keine
"HOME" Umgebungsvariable hat... Lade die benötigten Änderungen später
hoch.... Wenn ein befreundeter MacOSX-ler das auch mal bei sich getestet hat.)

Code: Alles auswählen

    def __init__(self, appname, global_lock = False):
        """
        Initialisiert die Klasse und legt den Lockfilenamen fest.
       
        :param appname: Eindeutiger Name der Anwendung. Anhand dieses
          Parameters wird der Name des Lockfiles oder der Serverport für den
          XMLRPC-Server generiert.
        :param global_lock: Wenn True, dann wird diese Anwendung systemweit
          nur einmal ausgeführt, auch bei Mehrbenutzer-Systemen.
        """
        self.appname = appname
        self.xmlrpcport = None
       
        # Lockfilename festlegen
        appdatadir = os.environ.get("APPDATA", None)
        # ACHTUNG: Entsprechendes Verzeichnis für 
        # POSIX - Systeme (Linux, BSD, MacOSX)
        # fehlt hier noch.
        
        if global_lock and appdatadir:
            lockdir = os.path.join(appdatadir, "Lockfiles")
        else:
            env_home = os.environ.get("HOME")
            appdir = os.path.join(env_home, appname)
            lockdir = os.path.join(appdir, "Lockfiles")
            
            if not (os.path.exists(lockdir) and os.path.isdir(lockdir)):
                os.makedirs(lockdir)

            (Hier der Rest....)

[/code]
oliver1974
User
Beiträge: 97
Registriert: Donnerstag 26. Oktober 2006, 15:01

Hmm, unter MacOSX erweist es sich schwieriger als gedacht..

Grund: MacOSX hat KEIN /proc Verzeichnis... Auch bei FreeBSD
haben die das wohl geknickt, wenn es noch da ist, dann nur als Übergangslösung für Altanwendungen.....

Wie kommen wir denn jetzt an eine Liste mit den aktuellen PIDs?

EDIT: Mir fällt jetzt nur sowas ein wie "ps" als Befehl übergeben
und dann die Ausgabe parsen... Hmmm, funktioniert wenigstens weitgehend garantiert auf allen BSDs, und wenn man es ohne weitere Optionen startet sollte da auch kein Unterschied zwischen Linux/BSD/MacOSX zu erwarten sein, in der ersten Spalte steht immer die PID... Hmmm, sollte klappen.
oliver1974
User
Beiträge: 97
Registriert: Donnerstag 26. Oktober 2006, 15:01

Okay, die neue Variante ist hier zu finden....
Antworten