מידע רשת

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 - אותו ניב עבור מסד נתוני המארחים