מידע משתמש וקבוצה

setgrent#

מחזיר את איטרטור מסד־נתוני־הקבוצות לרשומה הראשונה.

setgrent אומר לאיטרטור מסד־נתוני־הקבוצות של המערכת להתחיל מחדש. הקריאה הבאה ל־getgrent מחזירה שוב את רשומת הקבוצה הראשונה, ללא תלות בכמה רחוק איטרציה קודמת התקדמה. הוא לא מקבל ארגומנטים, אינו מחזיר ערך שימושי, וקיים כדי שתוכנית תוכל לסרוק מחדש את מסד נתוני הקבוצות מבלי להזדקק לסגור ולפתוח אותו ידנית. שלב אותו עם endgrent בסוף הסריקה כדי לשחרר את ה־file descriptor שמתחת.

תקציר#

setgrent;
setgrent();

מה מקבלים בחזרה#

ערך ההחזרה לא־מצוין ומוסכם להתעלם ממנו. קרא ל־setgrent עבור תופעת־הלוואי שלו - מיקום האיטרטור - לא עבור ערכו.

מצב גלובלי שהוא נוגע בו#

  • איטרטור מסד־נתוני־הקבוצות לכל־תהליך שמתוחזק על־ידי ספריית ה־C (getgrent(3)). הוא גלובלי לתהליך, לא מתוחם לחבילה או ללקסיקלי: כל קוד אחר שסורק את getgrent באותו תהליך, כולל בתוך threads שחולקים את האיטרטור, רואה את ה־rewind.

  • $! - במערכות שבהן setgrent(3) מדווח שגיאות (נדיר; רוב המימושים מחזירים void), כישלון משאיר את errno קבוע. קוד נייד אינו מסתמך על זה.

setgrent אינו נוגע ב־$_, @ARGV, או בכל מטפל קובץ.

דוגמאות#

ביצוע 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 מבצע לו rewind

  • endgrent - סוגר את האיטרטור כשהסריקה הסתיימה; הסוגר הסימטרי ל־setgrent

  • getgrnam - מחפש קבוצה בודדת לפי שם בלי לגעת באיטרטור כלל; עדיף לכך עבור שאילתות חד־פעמיות

  • getgrgid - מחפש קבוצה בודדת לפי GID; אותו נימוק כמו ל־getgrnam

  • setpwent - ה־rewind המקביל למסד נתוני הסיסמאות