setgrent#
מחזיר את איטרטור מסד־נתוני־הקבוצות לרשומה הראשונה.
setgrent אומר לאיטרטור מסד־נתוני־הקבוצות של המערכת להתחיל מחדש. הקריאה הבאה ל־getgrent מחזירה שוב את רשומת הקבוצה הראשונה, ללא תלות בכמה רחוק איטרציה קודמת התקדמה. הוא לא מקבל ארגומנטים, אינו מחזיר ערך שימושי, וקיים כדי שתוכנית תוכל לסרוק מחדש את מסד נתוני הקבוצות מבלי להזדקק לסגור ולפתוח אותו ידנית. שלב אותו עם endgrent בסוף הסריקה כדי לשחרר את ה־file descriptor שמתחת.
תקציר#
setgrent;
setgrent();
מה מקבלים בחזרה#
ערך ההחזרה לא־מצוין ומוסכם להתעלם ממנו. קרא ל־setgrent עבור תופעת־הלוואי שלו - מיקום האיטרטור - לא עבור ערכו.
מצב גלובלי שהוא נוגע בו#
איטרטור מסד־נתוני־הקבוצות לכל־תהליך שמתוחזק על־ידי ספריית ה־C (
getgrent(3)). הוא גלובלי לתהליך, לא מתוחם לחבילה או ללקסיקלי: כל קוד אחר שסורק אתgetgrentבאותו תהליך, כולל בתוך threads שחולקים את האיטרטור, רואה את ה־rewind.$!- במערכות שבהןsetgrent(3)מדווח שגיאות (נדיר; רוב המימושים מחזיריםvoid), כישלון משאיר אתerrnoקבוע. קוד נייד אינו מסתמך על זה.
דוגמאות#
ביצוע rewind בין שני מעברים על מסד נתוני הקבוצות - תחילה לאיסוף כל שמות הקבוצות, אחר־כך לאיסוף החברים של קבוצה ספציפית:
my @names;
while (my @g = getgrent) {
push @names, $g[0];
}
setgrent; # start over
while (my @g = getgrent) {
next unless $g[0] eq 'wheel';
print "wheel members: $g[3]\n";
last;
}
endgrent;
השתמש ב־setgrent בראש sub שנקרא שוב ושוב ורוצה סריקה רעננה בכל פעם:
sub groups_containing {
my ($user) = @_;
setgrent;
my @groups;
while (my ($name, undef, undef, $members) = getgrent) {
push @groups, $name if grep { $_ eq $user } split / /, $members;
}
endgrent;
return @groups;
}
שלב setgrent / endgrent סביב סריקה כדי שקורא לא־קשור שהיה באמצע איטרציה לא יופתע כשהשליטה חוזרת:
setgrent;
while (my @g = getgrent) {
# ... process ...
}
endgrent;
מקרי קצה#
צורת ללא־ארגומנט בלבד. בניגוד ל־
sethostent,setnetent,setprotoentו־setservent, שמקבלים דגלSTAYOPEN,setgrentלא מקבל דבר. העברת ארגומנט היא שגיאת זמן־הידור.קריאה ל־
setgrentללאgetgrentביניים היא no-op ברוב המערכות - האיטרטור פשוט ממוקם ברשומה הראשונה, וה־getgrentהראשון אחריו קורא את אותה רשומה. אל תסתמך עלsetgrentכפרימיטיב של ״פתח את קובץ הקבוצה״; ההתנהגות המוגדרת היחידה שלו היא ״rewind״.מצב גלובלי לתהליך.
setgrentבתוך מודול אחד מבצע rewind לאיטרטור עבור כל מודול אחר באותו תהליך. אם ספרייה סורקת אתgetgrentעד הסוף וקורא אז קורא ל־setgrent, הסמן של הספרייה נעלם. התייחס לאיטרטור כמשאב משותף: היה הבעלים שלו למשך הסריקה, מתוחם על־ידיsetgrentו־endgrent.threads חולקים את האיטרטור. שני threads שקוראים ל־
getgrentבמקביל יראו כל אחד תת־קבוצה של הרשומות;setgrentמ־thread אחד מפריע לאחר. לאיטרציה לכל־thread, קרא את/etc/groupישירות או השתמש בעטיפה בטוחה־ל־thread; הפונקציה המובנית אינה reentrant.לא כל הפלטפורמות ממשות זאת זהה. במערכות ללא
setgrent(3)הקריאה היא no-op ומצליחה בשקט. במערכות שכן ממשות אותו, העלות המדויקת (פתיחה־מחדש של/etc/group, התחלה־מחדש של שאילתת NSS, שאילתה־מחדש של LDAP) תלויה בשירות־השמות שמתחת ויכולה להיות לא־טריוויאלית - הימנע מקריאה לו בלולאה הדוקה.
הבדלים מ־upstream#
תואם מלא ל־upstream Perl 5.42.
ראו גם#
getgrent- קורא את רשומת הקבוצה הבאה; צורך את האיטרטור ש־setgrentמבצע לו rewindendgrent- סוגר את האיטרטור כשהסריקה הסתיימה; הסוגר הסימטרי ל־setgrentgetgrnam- מחפש קבוצה בודדת לפי שם בלי לגעת באיטרטור כלל; עדיף לכך עבור שאילתות חד־פעמיותgetgrgid- מחפש קבוצה בודדת לפי GID; אותו נימוק כמו ל־getgrnamsetpwent- ה־rewind המקביל למסד נתוני הסיסמאות