SysV IPC

shmread#

Αντιγραφή bytes από τμήμα κοινόχρηστης μνήμης System V σε βαθμωτό της Perl.

Η shmread συνδέεται στο τμήμα κοινόχρηστης μνήμης που αναγνωρίζεται από το ID, διαβάζει SIZE bytes ξεκινώντας από το byte offset POS, τα γράφει στο VAR, και αποσυνδέεται. Στο VAR ανατίθεται ως σύνολο - ό,τι κρατούσε πριν αντικαθίσταται από ακριβώς SIZE bytes δεδομένων. Η μεταβλητή σημειώνεται ως tainted υπό -T, επειδή τα περιεχόμενά της προέρχονται από έξω από το πρόγραμμα.

Σύνοψη#

use IPC::SysV qw(IPC_PRIVATE S_IRUSR S_IWUSR);
my $id = shmget(IPC_PRIVATE, 4096, S_IRUSR | S_IWUSR)
    or die "shmget: $!";
shmread($id, my $buf, 0, 128)
    or die "shmread: $!";

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

Αληθή σε επιτυχία, ψευδή σε αποτυχία με το $! ρυθμισμένο. Σε επιτυχία το VAR έχει επικαλυφθεί με ακριβώς SIZE bytes· καμία σύντομη ανάγνωση - είτε όλο το εύρος αντιγράφεται είτε η κλήση αποτυγχάνει. Σε αποτυχία τα περιεχόμενα του VAR είναι απροσδιόριστα· μη βασίζεστε σε αυτά.

Πάντα ελέγχετε την τιμή επιστροφής. Κακό ID, εκτός εύρους POS/ SIZE, ή τμήμα στο οποίο η διεργασία δεν έχει δικαίωμα σύνδεσης, όλα αναδύονται εδώ ως ψευδής επιστροφή:

shmread($id, my $buf, $pos, $size)
    or die "shmread(id=$id, pos=$pos, size=$size): $!";

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

  • $! - τίθεται σε αποτυχία (οποιοδήποτε από τα υποκείμενα σφάλματα shmat/memcpy/shmdt αναδύεται εδώ).

  • Σημαία taint στο VAR - τίθεται υπό -T ανεξάρτητα από το πώς δηλώθηκε το VAR, επειδή τα bytes προέρχονται από έξω από το πρόγραμμα.

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

Ανάγνωση εγγραφής σταθερού μεγέθους από τμήμα:

use IPC::SysV qw(IPC_PRIVATE S_IRUSR S_IWUSR);
my $id = shmget(IPC_PRIVATE, 1024, S_IRUSR | S_IWUSR) or die "shmget: $!";
shmwrite($id, "hello, world", 0, 12)                  or die "shmwrite: $!";
shmread($id, my $buf, 0, 12)                          or die "shmread: $!";
print $buf, "\n";                                     # hello, world

Ανάγνωση σε ένα offset. Τα POS και SIZE είναι σε bytes, όχι σε στοιχεία - το τμήμα δεν έχει έννοια εγγραφών:

shmread($id, my $chunk, 256, 64)
    or die "shmread: $!";                             # bytes 256..319

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

shmread($id, my $raw, 0, 16) or die "shmread: $!";
my ($magic, $len, $flags) = unpack "a4 N N", $raw;

Ανάγνωση tainted δεδομένων υπό -T. Η ανάθεση εγγυάται να παράγει tainted βαθμωτό ακόμα κι αν το VAR κρατούσε ήδη untainted τιμή:

# perl -T
shmread($id, my $buf, 0, $n) or die "shmread: $!";
# $buf is tainted; untaint via a regex match before using
# it in a sensitive context.

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

  • Στο VAR γίνεται ανάθεση, όχι προσάρτηση. Οποιαδήποτε προηγούμενη τιμή απορρίπτεται. Χρησιμοποιήστε φρέσκια λεξιλογική μεταβλητή αν χρειάζεστε και τα παλιά και τα νέα δεδομένα.

  • Το SIZE είναι ακριβές, όχι μέγιστο. Η shmread δεν κάνει σύντομες αναγνώσεις· το να ζητήσετε περισσότερα bytes από αυτά που κρατά το τμήμα από το POS και μετά αποτυγχάνει αντί να επιστρέψει ό,τι χωρά.

  • Τα POS και SIZE πρέπει να βρίσκονται εντός του τμήματος που δηλώθηκε κατά την κλήση shmget. POS + SIZE πέρα από το τέλος του τμήματος αποτυγχάνει με EINVAL.

  • Μηδενικό SIZE παράγει κενή συμβολοσειρά στο VAR και πετυχαίνει, υποθέτοντας ότι το ίδιο το POS είναι έγκυρο.

  • Δικαιώματα. Η καλούσα διεργασία πρέπει να έχει δικαίωμα ανάγνωσης στο τμήμα, όπως υπαγορεύουν τα mode bits που πέρασαν στην shmget (και, όπου ισχύει, από τον ιδιοκτήτη του τμήματος και τα τρέχοντα uid/gid).

  • Το VAR δεν χρειάζεται προ-διαστασιολόγηση. Σε αντίθεση με την sysread, δεν χρειάζεται να γεμίσετε με substr ή να προεκχωρήσετε το VAR - η shmread αναθέτει το αποτέλεσμα απευθείας.

  • Taint. Υπό -T, το VAR είναι tainted σε επιτυχία ανεξάρτητα από αυτό που κρατούσε πριν. Ξεπλύνετέ το μέσω αντιστοίχισης με capture-group ($data =~ /\A(.*)\z/s and $data = $1) μόνο αφού έχετε επικυρώσει ότι τα bytes είναι ασφαλή για την ευαίσθητη λειτουργία που πρόκειται να εκτελέσετε.

  • Δεν έχει κάθε πλατφόρμα SysV IPC. Σε συστήματα χωρίς shmat(2) η κλήση αποτυγχάνει κατά τον χρόνο εκτέλεσης (τυπικά ENOSYS)· φορητός κώδικας θα πρέπει να φυλαχθεί με eval ή έλεγχο δυνατότητας.

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

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

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

  • shmwrite - η αντίστροφη: αντιγραφή συμβολοσειράς σε τμήμα σε δοθέν offset

  • shmget - απόκτηση ή δημιουργία του ID τμήματος στο οποίο λειτουργεί η shmread

  • shmctl - ερώτηση μεταδεδομένων τμήματος (το IPC_STAT γεμίζει ένα shmid_ds που μπορείτε να χρησιμοποιήσετε για να ελέγξετε τα όρια του POS + SIZE) ή αφαίρεση του τμήματος όταν τελειώσετε

  • sysread - το αντίστοιχο σε επίπεδο περιγραφέα αρχείου· ίδιο σχήμα «bytes σε βαθμωτό», διαφορετική πηγή

  • unpack - μετατροπή των ωμών bytes που επιστρέφονται στο VAR σε πεδία με τύπο

  • IPC::SysV - το άρθρωμα που παρέχει τα IPC_PRIVATE, S_IRUSR, και τις άλλες σταθερές που θα περάσετε στην shmget