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

endgrent#

סוגר את מסד נתוני הקבוצות לאחר איטרציה עליו.

endgrent הוא חצי הניקוי של שלישיית האיטרציה על מסד נתוני הקבוצות setgrent / getgrent / endgrent. הוא מודיע לספריית C שסיימת לעבור על /etc/group (או מקור ה־NSS שמאחוריו), משחרר כל file descriptor או מצב במטמון שהספרייה פתחה בשמך. לאחר endgrent, הקריאה הבאה ל־getgrent מתחילה איטרציה רעננה מהראש.

תקציר#

endgrent;
endgrent();

ללא ארגומנטים, ללא ערך החזרה משמעותי.

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

ערך ההחזרה אינו מוגדר ואין להסתמך עליו. endgrent נקרא בעבור תופעת הלוואי שלו - סגירת מסד נתוני הקבוצות - לא בעבור תוצאה. התייחס אליו כאל קריאה ב־void.

endgrent;                           # correct
my $ok = endgrent;                  # wrong: $ok is not a success flag

אם הפלטפורמה שלך אינה ממשת endgrent, הקריאה croaks עם The endgrent function is unimplemented בזמן ריצה. זוהי למעשה בדיקת הידור־חד־פעמית - אם הפונקציה עובדת במערכת שלך בכלל, היא תמשיך לעבוד.

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

endgrent פועל אך ורק על מצב איטרציית־הקבוצות הפנימי של libc ש־setgrent ו־getgrent חולקים. הוא אינו קורא ואינו כותב משתנים מיוחדים של Perl. הוא אינו משנה את $!: מסלול כישלון שמגדיר errno בקריאת ה־C הבסיסית אינו מועלה ל־Perl.

The iteration state is per-process, not per-thread. In a threaded program, one thread’s endgrent closes the iteration for every thread

  • see Edge cases.

דוגמאות#

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

setgrent;
while (my @g = getgrent) {
    my ($name, $passwd, $gid, $members) = @g;
    print "$name ($gid): $members\n";
}
endgrent;

נפילה אל endgrent באמצע איטרציה היא חוקית - היא פשוט נוטשת את כל מיקום הסמן שהספרייה החזיקה:

setgrent;
while (my @g = getgrent) {
    last if $g[0] eq 'wheel';       # found what we wanted
}
endgrent;                           # release the handle anyway

הפעלה מחדש של איטרציה. endgrent ולאחריו setgrent היא הדרך הניידת להחזיר לאחור:

setgrent;
my @first_pass  = collect_groups();
endgrent;

setgrent;
my @second_pass = collect_groups();  # starts over from the top
endgrent;

ניקוי הגנתי בבלוק END עבור תוכניות שעלולות למות באמצע מעבר:

setgrent;
END { endgrent }
while (my @g = getgrent) { ... }    # any die still triggers END

מקרי קצה#

  • קריאה ל־endgrent ללא setgrent או getgrent קודמים היא לא־מזיקה. ספריית C אינה עושה דבר בשקט אם אין איטרציה בעיצומה.

  • קריאה לו פעמיים ברצף היא גם לא־מזיקה - הקריאה השנייה היא no-op.

  • עמימות פענוח. endgrent אינו לוקח ארגומנט ויש לו את הקדימות של אופרטור unary בעל שם. ביטוי bareword מיד מימינו יפורש כארגומנט וייפסל:

    endgrent or die;                  # WRONG: parses as endgrent(or die)
    endgrent() or die;                # right: empty parens disambiguate
    

    בפועל אין מול מה לבדוק את ערך ההחזרה, כך שמלכודת זו נושכת לעתים נדירות - אך אותו כלל חל על כל ביטוי משורשר.

  • Threads חולקים את האיטרציה. endgrent מ־thread אחד מסיים איטרציה לכל ה־threads של אותו תהליך, מאחר שהמצב הבסיסי הוא גלובלי־לתהליך. אל תשלב קריאות getgrent על פני threads בציפייה שכל אחד יראה כל רשומה.

  • NSS ושמירה במטמון. במערכות שבהן מסד נתוני הקבוצות מוגש דרך NSS (nss_ldap, nss_sss וכו«), endgrent משחרר מטמונים לכל־מודול שה־backend של NSS עשוי להחזיק. דמונים ארוכי־חיים שעוברים על מסד נתוני הקבוצות מעת לעת אמורים לקרוא ל־endgrent לאחר כל מעבר כדי להימנע מצבירת מצב backend.

  • אין השפעה על קריאות חיפוש לפי שם. getgrnam ו־getgrgid בלתי־תלויים בסמן האיטרציה. endgrent אינו פוסל את התוצאות שלהם או נתונים במטמון, ואינך צריך לקרוא ל־endgrent לפניהם או אחריהם.

  • לא ממומש בחלק מהפלטפורמות. Perl עושה croak The endgrent function is unimplemented אם ל־libc המארח אין endgrent(3). כל מערכות Linux, BSD ו־macOS מודרניות מספקות אותו.

הבדלים מהמקור#

תאימות מלאה עם Perl 5.42 המקורי.

ראו גם#

  • setgrent - פותח או מחזיר לאחור את מסד נתוני הקבוצות לפני המעבר עליו; תמיד הפרולוג לאיטרציה שמסתיימת ב־endgrent

  • getgrent - שולף את הרשומה הבאה מהאיטרציה ש־endgrent סוגר

  • getgrnam - מחפש קבוצה אחת לפי שם, בלתי־תלוי בסמן האיטרציה; אין צורך ב־endgrent

  • getgrgid - זהה ל־getgrnam אך ממופתח על gid מספרי

  • endpwent - קריאת הניקוי המקבילה למסד נתוני passwd; שתי האיטרציות בלתי־תלויות ושתיהן זקוקות לסגירה אם פתחת את שתיהן