shmread#
מעתיק בתים החוצה ממקטע זיכרון משותף של System V לתוך סקלר Perl.
shmread נצמד למקטע הזיכרון המשותף שמזוהה על־ידי ID, קורא SIZE בתים החל מ־offset הבתים POS, כותב אותם לתוך VAR, ומתנתק. ל־VAR נעשית השמה כאל שלם - כל מה שהחזיק לפני מוחלף בדיוק ב־SIZE בתים של נתונים. המשתנה מסומן מוכתם תחת -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 בתים; אין קריאות קצרות - או שכל הטווח מועתק פנימה או שהקריאה נכשלת. בכישלון תוכן 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הוצהר, מכיוון שהבתים מקורם מחוץ לתוכנית.
דוגמאות#
קריאת רשומה בגודל קבוע ממקטע:
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 הם בבתים, לא באלמנטים - למקטע אין מושג של רשומות:
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;
קריאת נתונים מוכתמים תחת -T. ההשמה מובטחת להפיק סקלר מוכתם גם אם VAR כבר החזיק ערך לא־מוכתם:
# 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נעשית השמה, לא צירוף לסוף. כל ערך קודם מושלך. השתמש ב־lexical רענן אם אתה צריך גם נתונים ישנים וגם חדשים.SIZEהוא מדויק, לא מקסימום.shmreadאינו עושה קריאות קצרות; בקשת בתים יותר ממה שהמקטע מחזיק מ־POSוהלאה נכשלת במקום להחזיר את מה שמתאים.POSו־SIZEחייבים לשכון בתוך המקטע שהוכרז בזמןshmget.POS + SIZEמעבר לסוף המקטע נכשל עםEINVAL.SIZEאפס מפיק מחרוזת ריקה ב־VARומצליח, בהנחה ש־POSעצמו תקף.הרשאות. לתהליך הקורא חייבת להיות הרשאת קריאה על המקטע, כפי שמוכתב על־ידי ביטי המצב שהועברו ל־
shmget(וכאשר רלוונטי, על־ידי הבעלים של המקטע ו־uid/gid הנוכחי).VARאינו חייב להיות מוגדר־גודל מראש. בניגוד ל־sysread, אינך עושהsubstr־pad או הקצאה מראש שלVAR-shmreadמשים את התוצאה ישירות.Taint. תחת
-T,VARמוכתם בהצלחה ללא קשר למה שהחזיק לפני. הלבן דרך התאמת קבוצת־לכידה ($data =~ /\A(.*)\z/s and $data = $1) רק לאחר שתיקפת שהבתים בטוחים לפעולה הרגישה שאתה עומד לבצע.לא לכל פלטפורמה יש SysV IPC. במערכות ללא
shmat(2)הקריאה נכשלת בזמן ריצה (בדרך כללENOSYS); קוד נייד אמור לשמור עםevalאו בדיקת תכונה.
הבדלים מהמקור#
תאימות מלאה עם Perl 5.42 המקורי.
ראו גם#
shmwrite- ההפוך: מעתיק מחרוזת לתוך מקטע ב־offset נתוןshmget- משיג או יוצר אתIDהמקטע ש־shmreadפועל עליוshmctl- מתשאל מטא־נתוני מקטע (IPC_STATממלאshmid_dsשאתה יכול להשתמש בו לבדיקת־גבולות שלPOS + SIZE) או מסיר את המקטע כשגמרתsysread- האנלוג של file-descriptor; אותה צורת ״בתים לתוך סקלר״, מקור שונהunpack- הופך את הבתים הגולמיים המוחזרים ב־VARלשדות מטיופסיםIPC::SysV- המודול שמספק אתIPC_PRIVATE,S_IRUSR, ואת הקבועים האחרים שתעביר ל־shmget