I/O

fileno#

Επιστρέφει τον αριθμό περιγραφέα αρχείου σε επίπεδο OS που βρίσκεται πίσω από ένα filehandle.

Η fileno βλέπει πέρα από την αφαίρεση του ενταμιευμένου filehandle της Perl και σας δίνει τον ακατέργαστο ακέραιο περιγραφέα που χρησιμοποιεί ο πυρήνας. Είναι η γέφυρα μεταξύ του Perl I/O και των κλήσεων συστήματος που μιλούν απευθείας σε περιγραφείς - select, POSIX::dup2, fcntl, ή οτιδήποτε σε IO::Poll / IO::Select. Σε handle καταλόγου, υποβάλλει το ίδιο ερώτημα στο dirfd(3), το οποίο δεν παρέχουν όλες οι πλατφόρμες.

Σύνοψη#

fileno FILEHANDLE
fileno DIRHANDLE
fileno EXPR            # EXPR evaluated as an indirect handle

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

  • Έναν ακέραιο >= 0 - τον περιγραφέα αρχείου του OS - για ένα κανονικό ανοιχτό handle που υποστηρίζεται από πραγματικό αντικείμενο πυρήνα.

  • -1 όταν το handle είναι ανοιχτό αλλά δεν έχει πραγματικό περιγραφέα. Αυτό λαμβάνετε για handles στη μνήμη που δημιουργήθηκαν από την open με αναφορά σε βαθμωτό ως τρίτο όρισμα (open my $fh, ">", \$buf).

  • undef όταν το handle είναι κλειστό, ποτέ ανοιχτό, ή - σε handle καταλόγου - όταν η πλατφόρμα δεν διαθέτει dirfd(3). Στην περίπτωση του handle καταλόγου τίθεται το $!.

Οι τρεις κατηγορίες επιστροφής έχουν σημασία. Κώδικας που ελέγχει το fileno($fh) για αλήθεια συγχέει το «κανένας τέτοιος fd» με το «fd αριθμός 0» (STDIN). Συγκρίνετε πάντα ρητά:

my $fd = fileno $fh;
die "handle not open"      unless defined $fd;
die "handle has no real fd" if $fd == -1;

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

  • $! - τίθεται όταν η fileno σε handle καταλόγου αποτυγχάνει επειδή η πλατφόρμα δεν έχει αντίστοιχο του dirfd(3).

Η fileno δεν διαβάζει ούτε γράφει σε καμία άλλη καθολική μεταβλητή I/O. Δεν εκκενώνει, δεν κάνει seek, δεν αλλάζει το επιλεγμένο τη δεδομένη στιγμή handle.

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

Η συνηθισμένη περίπτωση - μετατροπή ενός filehandle της Perl στον αριθμό fd που θέλει μια κλήση συστήματος:

open my $fh, "<", "/etc/hostname" or die $!;
print fileno $fh, "\n";             # e.g. "3"

Τα τυπικά handles έχουν πάντα σταθερούς περιγραφείς 0, 1, 2:

print fileno STDIN,  "\n";          # 0
print fileno STDOUT, "\n";          # 1
print fileno STDERR, "\n";          # 2

Έλεγχος αν δύο handles είναι αντίγραφα του ίδιου υποκείμενου περιγραφέα (το ιδίωμα από το upstream POD, προσαρμοσμένο για την περίπτωση -1):

if (fileno($this) != -1 && fileno($this) == fileno($that)) {
    print "\$this and \$that are dups\n";
} elsif (fileno($this) != -1 && fileno($that) != -1) {
    print "\$this and \$that have different "
        . "underlying file descriptors\n";
} else {
    print "at least one handle has no real file descriptor\n";
}

Τα handles στη μνήμη δεν έχουν αντικείμενο πυρήνα, οπότε η fileno επιστρέφει -1:

my $buf = "";
open my $mh, ">", \$buf or die $!;
print fileno $mh, "\n";             # -1

Δημιουργία bitmap περιγραφέων για select - η σχολική χρήση της fileno:

my $rin = "";
vec($rin, fileno($sock),  1) = 1;
vec($rin, fileno(STDIN),  1) = 1;
my $n = select(my $rout = $rin, undef, undef, 5.0);

Handles καταλόγων, όπου η πλατφόρμα υποστηρίζει dirfd(3):

opendir my $dh, "." or die $!;
my $dfd = fileno $dh;
if (defined $dfd) {
    # use with fstat, openat, fchdir, ...
} else {
    warn "no dirfd on this platform: $!";
}

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

  • Κλειστό handle: επιστρέφει undef. Καμία προειδοποίηση υπό use warnings - η fileno είναι σκόπιμα σιωπηλή ώστε να μπορεί να χρησιμοποιηθεί ως ανιχνευτής.

  • Ποτέ-ανοιχτό bareword: το fileno NOSUCH επιστρέφει undef· η strict mode θα αρνηθεί το bareword κατά τη μεταγλώττιση αν δεν έχει δηλωθεί.

  • Handles βαθμωτών στη μνήμη: επιστρέφουν -1, όχι undef. Η αντιμετώπιση του -1 ως «ανοιχτό αλλά μη χρησιμοποιήσιμο για κλήσεις συστήματος» είναι το προβλεπόμενο συμβόλαιο - το ίδιο το handle εξακολουθεί να λειτουργεί με print, readline κτλ.

  • Παγίδα fileno(-1): ένα ρητό if (fileno $fh) { ... } είναι σφάλμα έτοιμο να συμβεί: ο fd 0 είναι το STDIN. Χρησιμοποιήστε defined και συγκρίνετε ρητά με το -1.

  • Έμμεσο filehandle μέσω έκφρασης: αν το FILEHANDLE είναι οποιαδήποτε έκφραση εκτός από bareword ή απλό βαθμωτό, η τιμή του λαμβάνεται ως έμμεσο όνομα handle (συμβολοσειρά), όχι ως αντικείμενο handle. Για να περάσετε ένα handle αποθηκευμένο σε δομή δεδομένων, αποαναφέρετε πρώτα:

    fileno $handles[0];                 # indirect: uses the string
    fileno ${ \$handles[0] };           # still wrong
    fileno $handles[0]->fileno;         # wrong: calling a method on ""
    my $fh = $handles[0]; fileno $fh;   # right
    
  • Handle καταλόγου σε πλατφόρμες χωρίς dirfd(3): επιστρέφει undef και θέτει το $!. Το Linux διαθέτει dirfd(3), οπότε στους υποστηριζόμενους στόχους του pperl αυτή η διαδρομή δεν ασκείται.

  • Tied handles: η fileno καλεί τη μέθοδο FILENO της κλάσης tie αν είναι ορισμένη· διαφορετικά επιστρέφει undef. Η tied κλάση είναι υπεύθυνη να επιστρέψει μια λογική τιμή (-1 για «κανένας fd» είναι η σύμβαση).

  • Dup-αρισμένα handles: δύο handles που άνοιξαν με open από τον ίδιο υποκείμενο fd (π.χ. open my $copy, ">&", $orig) επιστρέφουν τον νέο περιγραφέα, όχι τον αρχικό - η dup δημιούργησε φρέσκο fd.

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

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

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

  • open - δημιουργεί τα filehandles που επιθεωρεί η fileno· οι λειτουργίες >& και <&= δέχονται αριθμούς περιγραφέων που κάνουν πλήρη κύκλο μέσω της fileno

  • opendir - πηγή handles καταλόγων για τη μορφή dirhandle της fileno

  • close - μετά από την οποία η fileno στο ίδιο handle επιστρέφει undef

  • select - η μορφή τεσσάρων ορισμάτων καταναλώνει bitmaps κατασκευασμένα από τιμές fileno

  • binmode - λειτουργεί στο στρώμα PerlIO πάνω από το fd· η fileno φτάνει από κάτω του