Filehandles, αρχεία, κατάλογοι

sysopen#

Ανοίγει ένα αρχείο με χαμηλού επιπέδου τρόπο, περνώντας μια ακέραιη μάσκα bits MODE απευθείας στην υποκείμενη κλήση συστήματος open(2).

Η sysopen είναι η διέξοδος για όταν το DWIM της λειτουργίας συμβολοσειράς της open σας εμποδίζει - όταν χρειάζεστε O_EXCL για ατομικό create-if-not-exist, O_NOFOLLOW για άρνηση συμβολικών λινκ, O_NONBLOCK σε FIFO, ή οποιαδήποτε άλλη σημαία που δεν έχει αντίστοιχη συμβολοσειρά "<" / ">" / ">>". Οι σταθερές σημαιών βρίσκονται στο Fcntl και συνδυάζονται με |.

Σύνοψη#

sysopen FILEHANDLE, FILENAME, MODE
sysopen FILEHANDLE, FILENAME, MODE, PERMS

Τι επιστρέφεται#

1 σε επιτυχία, undef σε αποτυχία (με το $! ορισμένο στο errno από την αποτυχημένη κλήση συστήματος). Σε αντίθεση με την open, δεν υπάρχει μαγεία - το FILENAME λαμβάνεται κυριολεκτικά, δεν ερμηνεύεται κανένα προπορευόμενο >, <, |, ή -, δεν αναλύεται καμία συμβολοσειρά λειτουργίας με στρώματα.

Αν το FILEHANDLE είναι μη ορισμένο βαθμωτό, αυτο-δημιουργείται σε νέο handle:

sysopen my $fh, $path, O_RDONLY
    or die "sysopen $path: $!";

MODE - η μάσκα bits του Fcntl#

Το MODE είναι ακέραιος κατασκευασμένος με OR σταθερών από το Fcntl. Η λειτουργία πρόσβασης είναι υποχρεωτική και αμοιβαία αποκλειόμενη· οι σημαίες τροποποιητών είναι προαιρετικές και συνδυάζονται ελεύθερα:

Σημαία

Σημασία

O_RDONLY

Άνοιγμα μόνο για ανάγνωση.

O_WRONLY

Άνοιγμα μόνο για εγγραφή.

O_RDWR

Άνοιγμα για ανάγνωση και εγγραφή.

O_CREAT

Δημιουργία του αρχείου αν δεν υπάρχει.

O_EXCL

Μαζί με O_CREAT: αποτυχία αν το αρχείο υπάρχει ήδη.

O_APPEND

Κάθε εγγραφή αναζητά πρώτα το τέλος του αρχείου (ατομική προσάρτηση).

O_TRUNC

Αποκοπή του αρχείου σε μηδενικό μήκος κατά το άνοιγμα.

O_NONBLOCK

Μη μπλοκάρουσα λειτουργία για τον προκύπτοντα περιγραφέα.

O_NOFOLLOW

Αποτυχία με ELOOP αν το τελικό συστατικό της διαδρομής είναι symlink.

Εισάγετέ τες με το όνομά τους ή με ετικέτα:

use Fcntl qw(O_RDWR O_CREAT O_EXCL O_APPEND);
# or
use Fcntl ':DEFAULT';

Οι παλιές τιμές 0, 1, 2 για read-only, write-only, read-write επίσης λειτουργούν σε κάθε σύστημα που υποστηρίζει η Perl, αλλά ονοματίστε τις σταθερές - ο προκύπτων κώδικας επιβιώνει αναθεώρηση μεταξύ πλατφορμών και διαβάζεται χωρίς γλωσσάρι.

PERMS - τα bits δικαιωμάτων κατά τη δημιουργία#

Το PERMS είναι οκταδικό mode (όπως δέχεται η chmod) που εφαρμόζεται στο inode μόνο όταν το O_CREAT δημιουργεί πραγματικά το αρχείο. Αν παραλειφθεί το PERMS, η Perl περνά 0666. Η umask της διεργασίας εφαρμόζεται από τον πυρήνα από πάνω, οπότε μια προεπιλεγμένη umask 022 αποδίδει 0644 στον δίσκο.

sysopen my $fh, $path, O_WRONLY | O_CREAT | O_EXCL, 0600
    or die "create $path: $!";

Μη γράφετε 0644 ως όρισμα PERMS χωρίς λόγο. Ένα σκληρά κωδικοποιημένο 0644 αφαιρεί την εγγραφή ομάδας ακόμη και από χρήστες που σκόπιμα ορίζουν ανεκτικό umask· το 0666 μαζί με το umask του χρήστη είναι η φορητή προεπιλογή και αυτό χρησιμοποιεί η sysopen όταν παραλείπετε το όρισμα εντελώς.

Καθολική κατάσταση που επηρεάζει#

  • $! - ορίζεται σε αποτυχία στο errno που επιστρέφει η open(2).

  • ${^OPEN} - η διαμόρφωση στρωμάτων της pragma open. Η sysopen εφαρμόζει την ίδια προεπιλεγμένη στοίβα PerlIO που θα εφαρμόσει η open για κλήση χωρίς στρώματα. Χρησιμοποιήστε binmode αμέσως μετά από επιτυχή sysopen όταν χρειάζεται να υπερκαλύψετε ή να αφαιρέσετε στρώματα (τυπικό για δυαδικά αρχεία, υποδοχές ως αρχεία, ή περιγραφείς O_NONBLOCK).

  • umask διεργασίας - μασκάρει το PERMS όταν το O_CREAT δημιουργεί το αρχείο.

Παραδείγματα#

Ατομικό create-if-not-exist - ο κανονικός λόγος καταφυγής στη sysopen:

use Fcntl qw(O_WRONLY O_CREAT O_EXCL);
sysopen my $fh, "lock.pid", O_WRONLY | O_CREAT | O_EXCL, 0644
    or die "another instance is already running: $!";
print $fh "$$\n";
close $fh;

Άνοιγμα-ή-δημιουργία για ανάγνωση/εγγραφή, διατηρώντας το υπάρχον περιεχόμενο:

use Fcntl qw(O_RDWR O_CREAT);
sysopen my $fh, $path, O_RDWR | O_CREAT, 0666
    or die "sysopen $path: $!";

Καταγραφή μόνο με προσάρτηση με την εγγύηση append - κάθε εγγραφή προσγειώνεται στο EOF ανεξάρτητα από την εναλλαγή με άλλους εγγραφείς:

use Fcntl qw(O_WRONLY O_CREAT O_APPEND);
sysopen my $log, "/var/log/app.log", O_WRONLY | O_CREAT | O_APPEND, 0644
    or die "open log: $!";
print $log "startup\n";

Άνοιγμα FIFO χωρίς μπλοκάρισμα στη χειραψία της πλευράς αναγνώστη:

use Fcntl qw(O_RDONLY O_NONBLOCK);
sysopen my $fifo, "/tmp/q", O_RDONLY | O_NONBLOCK
    or die "sysopen fifo: $!";

Άρνηση ακολούθησης symlink στο φύλλο - χρήσιμο σε καταλόγους εγγράψιμους από μη έμπιστους χρήστες:

use Fcntl qw(O_RDONLY O_NOFOLLOW);
sysopen my $fh, "$dir/config", O_RDONLY | O_NOFOLLOW
    or die "sysopen config: $!";

Επιβολή I/O σε επίπεδο byte μετά το άνοιγμα - αφαίρεση οποιουδήποτε στρώματος :utf8 ή :crlf που η προεπιλεγμένη στοίβα PerlIO θα εγκαθιστούσε διαφορετικά:

sysopen my $fh, $path, O_RDONLY or die $!;
binmode $fh;

Οριακές περιπτώσεις#

  • Το O_EXCL χωρίς O_CREAT είναι no-op. Ο έλεγχος αποκλειστικότητας ενεργοποιείται μόνο όταν το O_CREAT ζητά από τον πυρήνα να δημιουργήσει το αρχείο. Γράφετέ τα πάντα μαζί: O_CREAT | O_EXCL.

  • Το O_EXCL δεν είναι κλείδωμα. Εμποδίζει επιτυχημένο άνοιγμα σε αρχείο που ήδη υπάρχει, τίποτε άλλο. Μόλις το αρχείο υπάρχει, κάθε επόμενη sysopen με O_CREAT | O_EXCL αποτυγχάνει. Δεν σειριοποιεί την πρόσβαση στο περιεχόμενο - χρησιμοποιήστε flock γι” αυτό.

  • Το O_EXCL σε δικτυακά συστήματα αρχείων. Οι υλοποιήσεις NFS διαφέρουν· παλαιότερες εκδόσεις NFS χάνουν σιωπηρά τη σημασιολογία αποκλειστικότητας. Μη βασίζεστε στο O_EXCL σε NFSv2.

  • O_CREAT | O_EXCL και symlinks. Με τις δύο σημαίες ορισμένες, ο πυρήνας αρνείται να ανοίξει προϋπάρχον symlink στο τελικό συστατικό διαδρομής. Δεν προστατεύει ενδιάμεσα συστατικά διαδρομής· χρησιμοποιήστε O_NOFOLLOW ή επιλύστε τον κατάλογο με opendir και σημασιολογία openat αν το χρειάζεστε.

  • O_TRUNC με O_RDONLY. Η συμπεριφορά είναι απροσδιόριστη από το POSIX. Μην τα συνδυάζετε.

  • Παραλειπόμενο PERMS. Η προεπιλογή είναι 0666, μασκαρισμένο από το umask. Δεν είναι 0644. Παραλείπετε το PERMS εκτός αν ενεργά θέλετε να υπερκαλύψετε το umask του χρήστη.

  • FILEHANDLE ως έκφραση. Αν το FILEHANDLE είναι bareword, ονομάζει μια καθολική μεταβλητή πακέτου. Αν είναι έκφραση που αξιολογείται σε glob, globref, ή IO::Handle, ανοίγει αυτό το handle. Αν είναι μη ορισμένο βαθμωτό, αυτο-δημιουργείται μέσα του ένα νέο handle - η λεξιλογική μορφή που χρησιμοποιείται σε όλα αυτά τα παραδείγματα.

  • Καμία μαγεία στο FILENAME. Ένα FILENAME "-" ανοίγει αρχείο που ονομάζεται κυριολεκτικά -, όχι το STDIN. Ένα προπορευόμενο > ανοίγει αρχείο που ονομάζεται κυριολεκτικά >filename, όχι εγγραφή στο filename. Αυτό είναι όλο το νόημα της sysopen έναντι της open.

  • Τα προεπιλεγμένα στρώματα PerlIO εξακολουθούν να εφαρμόζονται. Η sysopen είναι «χαμηλού επιπέδου» σε σχέση με τη συμβολοσειρά λειτουργίας, όχι σε σχέση με το PerlIO. Το προκύπτον handle έχει την ίδια στοίβα στρωμάτων με μια χωρίς στρώματα open· καλέστε binmode για να την αλλάξετε.

  • Κλειστή ή μη έγκυρη έκφραση FILEHANDLE. Επιστρέφει undef με ορισμένο το $! (συνήθως EBADF για κακό υπάρχοντα περιγραφέα· ENOENT, EACCES, EEXIST, ELOOP για σφάλματα σε επίπεδο διαδρομής).

Διαφορές από το upstream#

Πλήρως συμβατό με το upstream Perl 5.42.

Δείτε επίσης#

  • open - υψηλότερου επιπέδου ανοιχτήρας με ανάλυση συμβολοσειράς λειτουργίας, σωλήνες, - ως STDIN / STDOUT, και λειτουργίες με στρώματα· χρησιμοποιήστε το εκτός αν χρειάζεστε ειδικά κάποια σημαία που εκθέτει η sysopen

  • fcntl - αλλάζει σημαίες σε ήδη ανοιχτό περιγραφέα (π.χ. ορισμός O_NONBLOCK εκ των υστέρων)· μοιράζεται το λεξιλόγιο σταθερών του Fcntl

  • sysread - ανάγνωση χωρίς ενταμιευτή· λειτουργεί σε οποιοδήποτε handle, όχι μόνο σε αυτό που ελήφθη από sysopen, παρά το όνομα

  • syswrite - εγγραφή χωρίς ενταμιευτή, ίδια σημείωση

  • Fcntl - το άρθρωμα που εξάγει τις σταθερές O_* και τις ετικέτες :DEFAULT / :flock / :mode

  • binmode - ορισμός ή αφαίρεση στρωμάτων PerlIO στο handle μετά το άνοιγμα

  • umask - η μάσκα διεργασίας που αφαιρεί bits από το PERMS όταν το O_CREAT δημιουργεί το αρχείο