====== std.process_ext ======
Prozess-Credentials & Systeminfo (WP-7): Liest und setzt User-/Group-IDs, ermittelt Prozessbeziehungen (PPID, PGRP) und verwaltet Sessions. Liefert außerdem Kernel- und Systeminformationen via ''uname'' (Hostname, Kernel-Version, Architektur).
→ [[lyx_-_programmiersprache:units|Standard Library]] · [[lyx_-_programmiersprache:units:process|std.process]] · [[lyx_-_programmiersprache:units:signals|std.signals]]
----
===== Konstanten =====
==== utsname-Puffer ====
^ Konstante ^ Wert ^ Beschreibung ^
| ''UTSNAME_SIZE'' | 390 | Gesamtgröße des ''utsname''-Puffers (6 × 65 Bytes) |
| ''UTSNAME_FIELD_LEN'' | 65 | Länge eines einzelnen Feldes inkl. Null-Byte |
| ''UTSNAME_SYSNAME'' | 0 | Offset: Betriebssystemname (z. B. ''„Linux"'') |
| ''UTSNAME_NODENAME'' | 65 | Offset: Hostname des Rechners |
| ''UTSNAME_RELEASE'' | 130 | Offset: Kernel-Release (z. B. ''„6.8.0-117-generic"'') |
| ''UTSNAME_VERSION'' | 195 | Offset: Kernel-Build-Info |
| ''UTSNAME_MACHINE'' | 260 | Offset: CPU-Architektur (z. B. ''„x86_64"'') |
| ''UTSNAME_DOMAIN'' | 325 | Offset: NIS-Domain-Name |
----
===== Funktionen =====
==== Credentials lesen ====
^ Signatur ^ Beschreibung ^
| ''GetUID(): int64'' | Reale User-ID des Prozesses |
| ''GetGID(): int64'' | Reale Group-ID des Prozesses |
| ''GetEUID(): int64'' | Effektive User-ID (relevant für Berechtigungsprüfungen) |
| ''GetEGID(): int64'' | Effektive Group-ID |
| ''GetPPID(): int64'' | PID des Elternprozesses |
| ''GetPGRP(): int64'' | Prozessgruppen-ID des aktuellen Prozesses |
| ''IsRoot(): bool'' | Gibt ''true'' zurück wenn die effektive UID 0 ist (Root) |
==== Credentials setzen ====
^ Signatur ^ Beschreibung ^
| ''SetUID(uid: int64): int64'' | Setzt die User-ID. Gibt 0 bei Erfolg, ''-EPERM'' wenn keine Berechtigung |
| ''SetGID(gid: int64): int64'' | Setzt die Group-ID. Gibt 0 bei Erfolg, ''-EPERM'' wenn keine Berechtigung |
==== Session & Prozessgruppe ====
^ Signatur ^ Beschreibung ^
| ''SetSID(): int64'' | Erstellt eine neue Session (Daemon-Grundlage). Gibt die neue SID zurück. Schlägt fehl wenn der Prozess bereits Prozessgruppen-Leader ist |
| ''SetPGID(pid: int64, pgid: int64): int64'' | Setzt die Prozessgruppe von ''pid'' auf ''pgid''. ''pid=0'' → aktueller Prozess; ''pgid=0'' → ''pid'' wird eigene Prozessgruppe |
==== Systeminfo (uname) ====
^ Signatur ^ Beschreibung ^
| ''GetUname(buf: int64): int64'' | Füllt ''buf'' (''alloc(UTSNAME_SIZE)'') mit dem vollständigen ''utsname''-Struct. Gibt 0 bei Erfolg |
| ''GetUnameSysname(outBuf: int64): int64'' | Kopiert das ''sysname''-Feld nach ''outBuf'' (min. ''UTSNAME_FIELD_LEN'' Bytes) |
| ''GetUnameNodename(outBuf: int64): int64'' | Kopiert den Hostnamen nach ''outBuf'' |
| ''GetUnameRelease(outBuf: int64): int64'' | Kopiert die Kernel-Version (z. B. ''„6.8.0-117-generic"'') nach ''outBuf'' |
| ''GetUnameVersion(outBuf: int64): int64'' | Kopiert die Kernel-Build-Info nach ''outBuf'' |
| ''GetUnameMachine(outBuf: int64): int64'' | Kopiert die CPU-Architektur (z. B. ''„x86_64"'') nach ''outBuf'' |
----
===== Verwendung =====
==== Credentials prüfen und wechseln (setuid-Daemon) ====
import std.process_ext;
import std.io;
fn DropPrivileges(targetUid: int64, targetGid: int64): bool {
if (!IsRoot()) {
PrintLn("Warnung: läuft nicht als Root");
return false;
}
// GID zuerst setzen (danach fehlt Root-Recht für SetGID)
if (SetGID(targetGid) < 0) { return false; }
if (SetUID(targetUid) < 0) { return false; }
PrintLn("Privileges abgegeben. EUID=" + IntToStr(GetEUID()));
return true;
}
==== Daemon erstellen (fork + setsid) ====
import std.process_ext;
import std.process;
fn Daemonize(): void {
var pid := Fork();
if (pid > 0) {
// Elternprozess beenden
Exit(0);
}
// Kindprozess: neue Session starten
SetSID();
// Zweiter fork verhindert, dass der Daemon ein Controlling Terminal bekommt
pid := Fork();
if (pid > 0) { Exit(0); }
// Ab hier: echter Daemon-Prozess ohne Terminal
}
==== Kernel-Info ausgeben ====
import std.process_ext;
import std.alloc;
import std.io;
fn PrintSystemInfo(): void {
var buf: int64 := alloc(UTSNAME_FIELD_LEN);
GetUnameNodename(buf);
PrintLn("Hostname: " + buf as pchar);
GetUnameRelease(buf);
PrintLn("Kernel-Version: " + buf as pchar);
GetUnameMachine(buf);
PrintLn("Architektur: " + buf as pchar);
free(buf, UTSNAME_FIELD_LEN);
}
==== Prozessbeziehungen ====
import std.process_ext;
import std.io;
fn PrintProcessIds(): void {
Print("UID=" + IntToStr(GetUID()));
Print(" GID=" + IntToStr(GetGID()));
Print(" EUID=" + IntToStr(GetEUID()));
Print(" PPID=" + IntToStr(GetPPID()));
PrintLn(" PGRP=" + IntToStr(GetPGRP()));
}
----
===== Hinweise =====
* ''SetUID'' und ''SetGID'' erfordern Root-Rechte oder das ''CAP_SETUID''/''CAP_SETGID''-Capability. Ohne Root kann ein Prozess seine UID nur auf seine eigene reale oder gespeicherte UID setzen.
* Bei ''SetSID'' muss der aufrufende Prozess ein Kindprozess sein (nach ''fork''), der noch kein Prozessgruppen-Leader ist.
* Alle ''GetUname*''-Funktionen rufen intern ''sys_uname'' auf und allozieren temporär 390 Bytes — für mehrere Felder ist ''GetUname'' mit einem eigenen Puffer effizienter.
* ''UTSNAME_FIELD_LEN'' = 65: Die Felder sind null-terminiert, maximal 64 Nutzzeichen.
----
===== Verwandte Units =====
* ''[[lyx_-_programmiersprache:units:process|std.process]]'' — fork, exec, waitpid, exit
* ''[[lyx_-_programmiersprache:units:signals|std.signals]]'' — Signalbehandlung (Signal-Maske gilt pro Prozess/Thread)
* ''[[lyx_-_programmiersprache:units:sched|std.sched]]'' — CPU-Affinität und Scheduling-Priorität
* ''[[lyx_-_programmiersprache:units:os|std.os]]'' — Allgemeine OS-Hilfsfunktionen
Letzte Aktualisierung: 2026-06-05