Warum erstellt open() meine Datei mit den falschen Berechtigungen?

Lesezeit: 7 Minuten

Benutzeravatar von Chaitanya
Chaitanya

Ich versuche, Text aus einer Datei zu lesen und in eine andere zu schreiben open(), read() und write().

Das ist mein open() für die Datei, in die geschrieben werden soll (ich möchte eine neue Datei erstellen und hineinschreiben):

fOut = open ("test-1", O_RDWR | O_CREAT | O_SYNC);

Dies setzt Dateiberechtigungen auf etwas, das ich überhaupt nicht verstehe. Dies ist die Ausgabe von ls -l:

---------T 1 chaitanya chaitanya 0 2010-02-11 09:38 test-1

Auch die Leseberechtigung ist gesperrt. Ich habe versucht danach zu suchen, konnte aber NICHTS finden. Seltsam, write() schreibt weiterhin erfolgreich Daten in die Datei.

Auch wenn ich einen ‘chmod 777 test-1’ mache, funktionieren die Dinge wieder richtig.

Könnte mir bitte jemand mitteilen, wo ich in meinem offenen Aufruf falsch liege?

Vielen Dank!

Als Referenz habe ich das vollständige Programm unten eingefügt:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

int main () {

    char buffer[512], ch;

    int fIn, fOut, i;
    ssize_t bytes;
    FILE *fp = NULL;

    //open a file
    fIn = open ("test", O_RDONLY);
    if (fIn == -1) {
        printf("\nfailed to open file.");
        return 1;
    }

    //read from file
    bytes =  read (fIn, buffer, sizeof(buffer));
    //and close it
    close (fIn);

    printf("\nSuccessfully read %d bytes.\n", bytes);

    //Create a new file
    fOut = open ("test-1", O_RDWR | O_CREAT | O_SYNC);

    printf("\nThese are the permissions for test-1\n");
    fflush(stdout);
    system("ls -l test-1");

    //write to it and close it.
    write (fOut, buffer, bytes);
    close (fOut);


    //write is somehow locking even the read permission to the file. Change it.
    system("chmod 777 test-1");

    fp = fopen ("test-1", "r");
    if (fp == NULL) {
        printf("\nCan't open test-1");
        return 1;
    }

    while (1)
    {
        ch = fgetc(fp);
        if (ch == EOF)
            break;
        printf("\n%c", ch);
    }

    fclose (fp);

    return 0;
}

  • Sie benötigen wahrscheinlich keine 777-Berechtigung; Sie benötigen wahrscheinlich höchstens 666, und normalerweise möchten Sie auch keine öffentliche Schreibberechtigung. Sie wollen nicht, dass Leute Ihre Datendateien ausführen.

    – Jonathan Leffler

    11. Februar 2010 um 15:12 Uhr

Benutzeravatar von Antti Huima
Antti Huima

open() nimmt ein drittes Argument, das der Satz von Berechtigungen ist, dh

open(filename, O_RDWR|O_CREAT, 0666)

0666 ist eine Oktalzahl, dh jeder der 6er entspricht drei Erlaubnisbits

6 = rw

7 = rwx

die ersten drei Bits für die Eigentümerberechtigung, die nächsten drei Bits für die Gruppenberechtigung und als nächstes steht für die Welt die erste Ziffer – stellt also eine Datei oder ein Verzeichnis dar. (0 – Datei, d – Verzeichnis) hier haben wir 0 verwendet, bedeutet Datei

Es ist eine typische Falle. Der Compiler erlaubt es Ihnen, das Permission-Argument wegzulassen, da die Permission-Bits beim Öffnen einer vorhandenen Datei keinen Sinn ergeben. Aber wenn Sie das Argument vergessen, wenn Sie eine Datei erstellen, erhalten Sie einen zufälligen Satz von Berechtigungen, zB 0000 in Ihrem Fall (—).

  • Der Vollständigkeit halber oktal 4 = r

    – SamPost

    11. Februar 2010 um 14:55 Uhr

  • @Adam Liss: Hex 4 = Oktal 4. Oktal ist praktisch für Berechtigungen, da jede Gruppe von 3 Bits eine Einheit von Berechtigungen und eine Oktalziffer bildet. 0644 = 0x1A4, aber es ist viel einfacher, die Berechtigungen in oktaler Schreibweise zu sehen als in hexadezimaler Schreibweise. (Teilweise Erfahrung, aber hauptsächlich die passende Gruppierung von Bits).

    – Jonathan Leffler

    11. Februar 2010 um 15:10 Uhr

  • 0666 ist normalerweise eine gute Einstellung, auch wenn Sie nicht beabsichtigen, dass “andere” darauf schreiben können. umask ist normalerweise auf 0022 gesetzt, wodurch die Schreibrechte für alle außer dem Eigentümer entfernt werden.

    – Jay Conrod

    11. Februar 2010 um 16:09 Uhr

  • Ich verstehe nicht, wie das letzte Argument erhalten wird, das ist nicht auf den Manpages?

    – PyWalker2797

    12. April 2020 um 1:16 Uhr

Benutzeravatar von ZeissS
ZeissS

Lektüre http://linux.die.net/man/2/open anscheinend hast du das verpasst mode Parameter für öffnen:

mode muss angegeben werden, wenn O_CREAT in den Flags steht, und wird ansonsten ignoriert. Das Argument mode gibt die zu verwendenden Berechtigungen an, falls eine neue Datei erstellt wird.

Billys Benutzeravatar
Billy

Diese Frage hat mir kürzlich geholfen, also wollte ich meinen Teil dazu beitragen, dem, was vor sich geht, etwas mehr Tiefe zu verleihen. Wie bereits erwähnt, fehlt Ihnen das dritte Argument open(). Die angezeigten Berechtigungen sind jedoch nicht zufällig; Sie kommen aus dem Stapel. Sehen Sie sich das folgende Code-Snippet an:

    asm("push $0");
    asm("push $0");
    asm("push $0");
    fd = open("base", O_RDWR|O_CREAT);

Beachten Sie das folgende Ergebnis:

    ----------. 1 user user 4 Feb 26 08:21 base

Lassen Sie uns den ersten Push auf 1 ändern, dh die Berechtigung ausführen:

    asm("push $1;push $0;push $0");
    fd = open("base", O_RDWR|O_CREAT);

und wir bekommen:

    ---------x. 1 user user 4 Feb 26 08:25 base

Ändern Sie den Push auf 4, dh Leseberechtigung, und spielen Sie mit den anderen beiden Werten herum:

    asm("push $4;push $5;push $6");
    fd = open("base", O_RDWR|O_CREAT);

und wir bekommen:

    -------r--. 1 user user 4 Feb 26 08:27 base

So können wir sehen, dass der dritte Wert, der vom Stack gepoppt (zuerst geschoben) wird, was wirklich zählt. Schließlich können wir zum Spaß 5 und dann 50 ausprobieren, was jeweils zu Folgendem führt:

    -------r-x. 1 user user 4 Feb 26 08:27 base
    ----rw----. 1 user user 4 Feb 26 08:28 base

Hoffe das bringt etwas Klarheit!

  • Entschuldigung, was meinst du damit, dass C diese Version von open verwendet? Aus der Manpage: „Dieses Argument muss angegeben werden, wenn O_CREAT in Flags angegeben ist; wenn O_CREAT nicht angegeben ist, wird der Modus ignoriert. Die effektiven Berechtigungen werden von der umask des Prozesses auf die übliche Weise geändert: Die Berechtigungen der erstellten Datei sind (Modus & ~umask).” Argumente werden auf dem Stack übergeben; Indem wir die Inline-Assemblierung verwenden, um den Stack manuell einzurichten, können wir demonstrieren, woher die scheinbar „zufälligen“ Berechtigungen kommen.

    – Billi

    7. Juni 2018 um 6:16 Uhr


Benutzeravatar von rgt
rechts

Eigentlich umask() filtert nur Berechtigungen und legt sie nicht fest. Das typische umask() Wert ist 0002 (“Schreibrechte nicht an die Welt verschenken”) und wenn Ihr Moduswert in der open( "file", O_CREAT, 0777) gab alle Berechtigungen, die die resultierende Datei haben würde 775 als seine Berechtigungen.

Nicht unbedingt relevant für die Frage, aber die akzeptierte Antwort könnte diesen Klarstellungspunkt verwenden:

Es besteht eine Beziehung zwischen rwx und seiner numerischen Darstellung, die sichtbar wird, wenn das Vorhandensein eines Buchstabens als binäre 1 und sein Fehlen als binäre 0 behandelt wird.

z.B

rwx  <-->  111 (binary) <-->  7 (octal)

r--  <-->  100 (binary) <-->  4 (octal)

-wx  <-->  011 (binary) <-->  3 (octal) 

Als weitere Ergänzung können Sie nun den Befehl chmod betrachten:

chmod 777 Dateiname.Erweiterung –> rwxrwxrwx-Berechtigungen

777 <--> 111 111 111 <--> rwx rwx rwx

oder: chmod 654 Dateiname.Erweiterung –> rw-rxr–

654 <--> 110 101 100 <--> rw- r-x r--

Hoffe das ist informativ!

Abdos Benutzeravatar
Abdo

Du kannst anrufen umask(0); Systemaufruf vor der Verwendung open(); Systemaufruf, um Ihre Auswahlberechtigungen für die Datei korrekt festzulegen.

Benutzeravatar von Meevs
Meevs

Dies ist ein ziemlich alter Thread, aber ich denke, die Leute sollten sich der Bibliothek “sys/stat.h” bewusst sein. Dazu gehört eine Reihe symbolischer Konstanten zum Setzen von Berechtigungsbits.

Beispiel: Um eine Datei mit aktivierten Lese-/Schreibberechtigungen für den Benutzer zu öffnen

#include <fcntl.h>
#include <sys/stat.h>

open("Your/File/Path", O_RDWR | O_CREAT, S_IWUSR | S_IRUSR);

wo:

S_IWUSR // Sets the Users Write bit
S_IRUSR // Sets the Users Read bit

Diese Bibliothek enthält eine Reihe anderer, ich werde sie hier nicht alle auflisten, aber Sie können alles nachlesen hier.

Natürlich können Sie die Oktalwerte eingeben, um diese Bits zu setzen, einige mögen jedoch argumentieren, dass dies eine schlechte Codierungspraxis ist.

  • Ich denke, was Sie sagen, ist allgemeines subjektives Zeug, und die Frage ist, dass wir selbst nach dem Setzen der Berechtigung keine gesetzten Berechtigungsbits sehen können. Dies gilt sowohl für die stdlb-API als auch für die System-API.

    – Bhupesh-Hose

    26. März 2018 um 11:49 Uhr

  • @BhupeshPant Die Frage fragt, warum die Berechtigungsbits der Datei auf “———T 1 chaitanya chaitanya 0 2010-02-11 09:38 test-1” gesetzt werden. Das heißt, warum funktioniert die Datei keine Berechtigungsbits gesetzt haben. In seinem offenen Aufruf, dh.) “fOut = open (“test-1″, O_RDWR | O_CREAT | O_SYNC);” Er hat das O_CREAT-Flag, das die Datei “test-1” erstellt, wenn sie nicht existiert. Unter der Annahme, dass dies der Fall ist (dass die Datei beim Öffnen-Aufruf erstellt wird), muss er auch die der Datei zuzuordnenden Berechtigungsbits spezifizieren. Er korrigiert dies später in seinem Code mit dem Systemaufruf von chmod.

    – Meevs

    26. März 2018 um 17:20 Uhr

1416310cookie-checkWarum erstellt open() meine Datei mit den falschen Berechtigungen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy