getprotoent#
מאחזר את הרשומה הבאה ממסד נתוני הפרוטוקולים.
getprotoent עובר על מסד נתוני הפרוטוקולים של המערכת - במערכות דמויות־Unix מסורתיות מדובר ב־/etc/protocols, במערכות מודרניות מה שספריית ה־C ומחסנית ה־NSS ממפים אליו - ומחזיר רשומה אחת לכל קריאה עד שמסד הנתונים מתרוקן. זוהי הזרוע המאיטרת של השלישייה setprotoent / getprotoent / endprotoent. השתמשו ב־getprotobyname או ב־getprotobynumber כאשר אתם רוצים חיפוש ממוקד יחיד; getprotoent מיועד למניית כל פרוטוקול הידוע למערכת.
סמן האיטרציה משותף לכל התהליך ונמצא בבעלות ספריית ה־C. setprotoent מחזיר אותו לאחור ובאופן אופציונלי משאיר את ה־descriptor הגיבוי פתוח; endprotoent סוגר אותו. בין שתי הקריאות הללו getprotoent מניב כל רשומה לפי הסדר, ולאחר מכן מחזיר את הרשימה הריקה (או undef בהקשר סקלר) כאשר לא נותר דבר.
תקציר#
my ($name, $aliases, $proto) = getprotoent;
my $name = getprotoent;
מה מקבלים בחזרה#
הקשר רשימה - רשימה בעלת שלושה אלמנטים המשקפת את ה־struct protoent של C:
$name- שם הפרוטוקול הקנוני, לדוגמה"tcp","udp","icmp".$aliases- מחרוזת מופרדת ברווחים של שמות חלופיים לאותו פרוטוקול. לרוב ריקה.$proto- מספר הפרוטוקול המספרי כפי שהוא משמש בכותרות IP ומתקבל על־ידיsocket/getsockopt.
בסוף־מסד־הנתונים ההחזרה היא הרשימה הריקה. הערת ה־perlfunc של ה־upstream על ״ערך אמת חסר־משמעות יחיד״ עבור רשומות חסרות חלה על החיפושים לפי־שם ולפי־מספר, לא על getprotoent - מעבר מעבר לסוף האיטרציה הוא רשימה ריקה נקייה.
הקשר סקלר - רק $name הקנוני, או undef בסוף־מסד־הנתונים. השתמשו בהקשר רשימה בכל פעם שאתם צריכים את המספר או את הכינויים; לא ניתן לשחזר אותם מהשם בדיעבד.
פיצול הכינויים לרשימה עם split פשוט:
my @alts = split ' ', $aliases;
מצב גלובלי שהוא נוגע בו#
סמן מסד נתוני הפרוטוקולים, משאב שבבעלות ספריית ה־C לכל תהליך, משותף עם
setprotoent,endprotoent,getprotobynameו־getprotobynumber. חיפוש לפי־שם או לפי־מספר עלול לאפס את הסמן באמצע איטרציה בפלטפורמות מסוימות - ראו מקרי קצה.לא נקראים ולא נכתבים משתנים מיוחדים ברמת Perl. בניגוד ל־
gethostent, לפונקציות הפרוטוקולים אין מקבילה ל־h_errno, ולכן$?אינו נוגע. סוף מסד הנתונים אינו כשל ואינו קובע את$!.
דוגמאות#
מניית כל פרוטוקול שהמערכת מכירה:
setprotoent(1);
while (my ($name, $aliases, $proto) = getprotoent) {
print "$proto\t$name\t$aliases\n";
}
endprotoent;
הקשר סקלר - הצגת השמות הקנוניים בלבד:
setprotoent(0);
while (defined(my $name = getprotoent)) {
print "$name\n";
}
endprotoent;
בניית מיפוי שם־למספר במעבר אחד כך שחיפושים מאוחרים לא יפגעו כלל במסד הנתונים:
my %proto_num;
setprotoent(1);
while (my ($name, $aliases, $num) = getprotoent) {
$proto_num{$name} = $num;
$proto_num{$_} = $num for split ' ', $aliases;
}
endprotoent;
print $proto_num{"tcp"}, "\n"; # 6
ממשק לפי־רשומה דרך עקיפת Net::protoent - מתודות accessor במקום פירוק מיקומי:
use Net::protoent;
while (my $p = getprotoent) {
printf "%-10s %3d\n", $p->name, $p->proto;
}
מקרי קצה#
אין rewind מובלע.
getprotoentאינו פותח ואינו מחזיר לאחור את מסד הנתונים בעצמו. הקריאה הראשונה לאחר תחילת התוכנית עובדת משום שספריית ה־C פותחת את הקובץ ביעילות עצלה, אך לאחר שהגיעו לסוף, קריאות נוספות ממשיכות להחזיר סוף־מסד־נתונים עד ש־setprotoentמחזיר את הסמן לאחור. תמיד עטפו את המנייה ב־setprotoentו־endprotoentמפורשים.סוף־מסד־הנתונים הוא הרשימה הריקה, לא
undef. בהקשר רשימה תנאי הלולאהwhile (my @r = getprotoent)עובד משום שהרשימה הריקה היא שקר. בהקשר סקלר השתמשו ב־while (defined(my $name = getprotoent))- שם פרוטוקול של"0"הוא תיאורטית חוקי והיה מסיים שגוי לולאה מבוססת אמיתיות.הכינויים הם סקלר אחד, לא רשימה.
$aliasesהוא מחרוזת יחידה מופרדת ברווחים; פצלו על רווח לבן אם אתם רוצים רשימה. שדה כינויים ריק הוא המקרה השכיח, לא שגיאה.שילוב עם חיפושים לפי־שם / לפי־מספר. קריאה ל־
getprotobynameאוgetprotobynumberבמהלך מעבר עלולה לאפס את הסמן המשותף בפלטפורמות מסוימות. סיימו את האיטרציה תחילה, או הפעילו אותה מחדש עםsetprotoentלאחר החיפוש.אינו reentrant. סמן מסד הנתונים הוא משאב גלובלי יחיד בתוך ספריית ה־C. שתי איטרציות במקביל באותו תהליך - בין threads, מטפלי אותות, או callbacks מקוננים - מקלקלים זה את מצבו של זה. הגבילו כל מעבר ל־thread אחד בלבד.
פלטפורמות ללא מסד נתוני פרוטוקולים. במערכות ללא מקבילה ל־
/etc/protocols, הקריאה היא no-op המחזירה את הרשימה הריקה מיד במקום להעלות שגיאה. ראוperlportלרשימה המלאה של מוזרויות מסדי־נתוני־רשת.Tainting. רשומות מגיעות מקובץ שהקרנל קורא בשמכם ואינן מסומנות כ־tainted. התייחסו אליהן ככבלתי אמינות בכל זאת כאשר הקובץ ניתן לכתיבה על־ידי משתמש.
הבדלים מ־upstream#
תואם מלא ל־upstream Perl 5.42.
ראו גם#
setprotoent- החזרת האיטרטור לאחור ובאופן אופציונלי השארת ה־descriptor הגיבוי פתוח לכל המעברendprotoent- סגירת האיטרטור ושחרור מטפל מסד הנתונים לאחר שהמנייה הסתיימהgetprotobyname- חיפוש ממוקד לפי שם פרוטוקול במקום מנייה מלאהgetprotobynumber- חיפוש ממוקד לפי מספר פרוטוקול מספריgetservent- אותה תבנית איטרציה עבור מסד נתוני השירותים, המתייחס לשמות פרוטוקולים מזה הנוכחיgethostent- אותו ניב עבור מסד נתוני המארחים