Unix::Groups::FFI(3)

πŸ“¦
version 1.000 Β· 2 versions
, in fedora 43

πŸ’– Unix::Groups::FFI β€” the vibe ✨

ok so bestie, this is Unix::Groups::FFI, part of the User Contributed Perl Documentation family, and it's literally your backstage pass to the Unix group syscalls. no cap. πŸŽ€


🌸 NAME 🌸

Unix::Groups::FFI β€” Interface to Unix group syscalls. that's it, that's the whole thing, she's an interface to Unix group syscalls and she's serving πŸ’…


✨ SYNOPSIS ✨

use Unix::Groups::FFI qw(getgroups setgroups getgrouplist initgroups);

my @gids = getgroups;
setgroups(@gids);
my @gids = getgrouplist($username, $gid);
initgroups($username, $gid);

look at her. four little lines and you're already doing group stuff. iconic behavior honestly πŸ¦‹


🫢 DESCRIPTION 🫢

So like, this module is an FFI interface to a whole lil squad of syscalls that all have to do with Unix groups β€” we're talking getgroups(2), setgroups(2), getgrouplist(3), and initgroups(3). πŸ’œ

And because of that, she's a Unix girlie only. Unix-like operating systems, that's the vibe check. anywhere else? not happening. sorry bestie 😭


πŸ‘‘ FUNCTIONS πŸ‘‘

okay so the way this works: every single function is exported individually on demand β€” you ask for her by name, she shows up. and here's the tea: a function will not be available for export if the system doesn't implement the corresponding syscall. so if your OS said no, the function said "can't come to the phone right now." periodt. πŸ’€

πŸ“ getgroups

my @gids = getgroups;

Returns the supplementary group IDs of the current process via getgroups(2). that's it, that's the function, she ate and left no crumbs ✨

🌈 setgroups

setgroups(@gids);

Sets the supplementary group IDs for the current process via setgroups(2). πŸ‘‘

now the important part, listen up:

  • Trying to set more than NGROUPS_MAX groups will throw an EINVAL error. and what is NGROUPS_MAX? it's 32 before Linux 2.6.4, or 65536 since Linux 2.6.4. so like, know your era πŸ’…
  • Passing an empty list of group IDs may result in unspecified behavior. not "will", not "won't" β€” may. it's giving mystery, and not in a cute way πŸ™ˆ
  • The CAP_SETGID capability or equivalent privilege is required. so like, you gotta have the badge to get in the door, fr fr.

🧚 getgrouplist

my @gids = getgrouplist($username, $gid);
my @gids = getgrouplist($username);

Returns the group IDs for all groups of which $username is a member, also including $gid (without repetition), via getgrouplist(3). πŸ”₯

if $username doesn't exist on the system? EINVAL error. she's not ghosting you, she's erroring at you, and there's a difference 😀

and as a special case: the primary group ID of $username is included if $gid is not passed. cute little bonus, no extra charge πŸŽ€

πŸ¦‹ initgroups

initgroups($username, $gid);
initgroups($username);

Initializes the supplementary group access list for the current process to all groups of which $username is a member, also including $gid (without repetition), via initgroups(3). she's setting the whole vibe up for you, main character energy only πŸ‘‘

if $username doesn't exist on the system, EINVAL error will result. same as above, she does not play about that. The CAP_SETGID capability or equivalent privilege is required β€” again, badge, door, you know the drill πŸ’…

and as a special case: the primary group ID of $username is included if $gid is not passed. matching set with getgrouplist, we love consistency 🫢


😭 ERROR HANDLING 😭

okay this part actually matters so put your phone down for a sec bestie.

All functions will throw an exception containing the syscall error message in the event of an error. and not only that β€” $! in perlvar will also have been set by the syscall, so you could check it after trapping the exception if you want finer exception handling. it's giving layered, it's giving detail-oriented, we're obsessed ✨

here's the whole thing, verbatim, look at her go:

use Unix::Groups::FFI 'setgroups';
use Syntax::Keyword::Try;
use Errno qw(EINVAL EPERM ENOMEM);

try { setgroups((0)x2**16) }
catch {
  if ($! == EINVAL) {
    die 'Tried to set too many groups';
  } elsif ($! == EPERM) {
    die 'Insufficient privileges to set groups';
  } elsif ($! == ENOMEM) {
    die 'Out of memory';
  } else {
    die $@;
  }
}

see how she catches it and then peeks at $! to figure out which flavor of problem she's dealing with? that's the move. πŸ’–

and if you want the full list of possible error codes, go read the documentation for each syscall. that's where the receipts live. πŸ“œ

πŸ’€ BUGS πŸ’€

Report any issues on the public bugtracker. that's the whole section. short, sweet, to the point. she said "if something's wrong, tell the bugtracker, not me." πŸ’…


🌸 AUTHOR 🌸

Dan Book <dbook@cpan.org> β€” the legend herself. 🫢


This software is Copyright (c) 2018 by Dan Book.

This is free software, licensed under:

The Artistic License 2.0 (GPL Compatible)

free software, iconic licensing, no notes πŸ”₯


πŸ’œ SEE ALSO πŸ’œ

go read these if you want the deeper lore, iykyk πŸ“š


okay that's the whole page bestie, you're officially a Unix groups girlie now 🌈

and for the record: this was perl v5.42.0, dated 2025-07-25, and the page is Unix::Groups::FFI(3). mwah, bye, go set some groups responsibly πŸ’–βœ¨πŸŽ€

πŸ“¦ where this page comes from