setprotoent#
פותח את מסד נתוני הפרוטוקולים ומכין אותו לקריאות עוקבות.
setprotoent מחזיר לאחור (או פותח) את מסד נתוני הפרוטוקולים של המערכת - ברוב המערכות הדומות־ל־Unix זהו /etc/protocols - כך שרצף עוקב של קריאות getprotoent מתחיל ברשומה הראשונה. זהו הצלע הראשון של שלישיית האיטרציה setprotoent / getprotoent / endprotoent. הארגומנט היחיד STAYOPEN הוא רמז לספריית ה־C לגבי האם מטפל הקובץ המגבה את האיטרציה צריך להישאר פתוח בין קריאות: ערך אמת מבקש מהספרייה לשמור אותו פתוח (מהיר יותר להליכות ארוכות), ערך שקר מאפשר לה לסגור ולפתוח מחדש בכל קריאה.
קריאה ל־getprotobyname או getprotobynumber בכל מקום באמצע איטרציה עלולה לאפס את מיקום ההליכה בפלטפורמות מסוימות; ראו מקרי קצה.
תקציר#
setprotoent STAYOPEN
setprotoent(1)
מה מקבלים בחזרה#
אין ערך־החזרה משמעותי. כמו אחיו endprotoent ו־sethostent, setprotoent נקרא בשל תופעת הלוואי שלו: החזרת האיטרציה לאחור, ובהתאם ל־STAYOPEN, קיבוע ה־descriptor כפתוח. אין דבר ששווה לבדוק בערך־ההחזרה שלו.
מצב גלובלי שהוא נוגע בו#
setprotoent מנהל סמן לכל־תהליך שבבעלות ספריית ה־C לתוך מסד נתוני הפרוטוקולים. מצב זה משותף לכל קריאת getprotoent עוקבת באותו תהליך - כולל קריאות ממודולים אחרים שלא כתבתם. קוד המהלך על מסד הנתונים חייב או לרוקנו במלואו עם endprotoent או לקבל שקורא מאוחר עלול לראות איטרציה שכבר בעיצומה. שום משתנים מיוחדים ברמת Perl לא נקראים או נכתבים.
דוגמאות#
פתיחת מסד הנתונים ואיטרציה על כל רשומה, תוך שמירת ה־descriptor הבסיסי חי במהלך כל ההליכה:
setprotoent(1); # 1 = keep file open between calls
while (my @p = getprotoent()) {
my ($name, $aliases, $proto) = @p;
print "$proto\t$name\n";
}
endprotoent();
הפעלה מחדש של איטרציה בעיצומה מההתחלה:
setprotoent(1);
my @first = getprotoent();
my @second = getprotoent();
setprotoent(1); # rewind
my @again = getprotoent(); # same as @first
endprotoent();
הניחו לספריית ה־C לסגור ולפתוח מחדש את /etc/protocols בכל getprotoent - זול יותר בזיכרון, יקר יותר בקריאות מערכת, שימושי רק כשאתם קוראים מספר מועט של רשומות:
setprotoent(0);
my @tcp = getprotoent();
endprotoent();
שיוך עם חיפוש חד־פעמי - getprotobyname ו־getprotobynumber אינם משתתפים באיטרציה ואינם זקוקים ל־setprotoent:
my @tcp = getprotobyname('tcp'); # no setprotoent needed
מקרי קצה#
STAYOPENהוא רמז, לא חוזה: ספריות C רבות מתעלמות ממנו לחלוטין ומתנהגות כאילו ה־descriptor נשמר תמיד פתוח. אל תסתמכו על הארגומנט לבקרת שימוש במשאבים בגרגיריות עדינה.עירוב עם חיפושים חד־פעמיים: קריאה ל־
getprotobynameאוgetprotobynumberבמהלך הליכה עלולה לאפס את סמן האיטרציה בפלטפורמות מסוימות. קוד פורטבילי מרוקן את ההליכה תחילה, או קורא ל־setprotoentשוב לאחר מכן כדי להתחיל מחדש מלמעלה.לא reentrant: סמן מסד נתוני הפרוטוקולים הוא משאב גלובלי יחיד בתוך ספריית ה־C. שתי איטרציות בו־זמניות באותו תהליך (threads, signal handlers, כל דבר) משחיתות זו את זו. השתמשו בהליכה אחת בכל פעם.
הארגומנט הוא חובה ברמת השפה:
setprotoentללא ארגומנט הוא שגיאת תחביר - לפונקציה המובנית יש arity של אחד. העבירו0אם אין לכם העדפה.פלטפורמות ללא מסד נתוני פרוטוקולים: במערכות שבהן לספריית ה־C אין מקבילה ל־
/etc/protocols, הקריאה היא no-op במקום שגיאה. ראוperlportלרשימה המלאה של מוזרויות מסד־נתוני־רשת.תוצאה לא־מוכתמת של האיטרציה: הרשומות שמוחזרות על־ידי
getprotoentלאחרsetprotoentמגיעות מקובץ שהקרנל קורא בשמכם ואינן מסומנות כמוכתמות. התייחסו אליהן כאל לא־אמינות בכל מקרה אם מסד הנתונים ניתן לעריכה על־ידי משתמש.
הבדלים מ־upstream#
תואם מלא ל־upstream Perl 5.42.
ראו גם#
getprotoent- קורא את הרשומה הבאה; גוף הלולאה ש־setprotoentמקיםendprotoent- סוגר את מסד הנתונים לאחר איטרציה; המסיים של השלישייה ש־setprotoentמתחילgetprotobyname- חיפוש חד־פעמי לפי שם; אינו משתתף באיטרציהgetprotobynumber- חיפוש חד־פעמי לפי מספר פרוטוקול; בדומה לכך בלתי־תלויsethostent- פותחן אנלוגי למסד נתוני המארחים; אותו אידיום, טבלה אחרתsetservent- פותחן אנלוגי למסד נתוני השירותים