setgid(2)

πŸ’… setgid(2) β€” like, the set group identity page bestie πŸŽ€

okay so this is setgid from the System Calls Manual (section 2, the syscall girlies ✨), and if you've ever wanted to change which group a process is cosplaying as, this is THE function. let's get into it 🫢


✨ NAME ✨

setgid β€” set group identity 🌸


πŸ“š LIBRARY πŸ“š

Standard C library (libc, -lc) β€” so yeah, just link the normal one, no extra credit πŸ’…


πŸ¦‹ SYNOPSIS πŸ¦‹

#include <unistd.h>

int setgid(gid_t gid);

πŸ’– DESCRIPTION πŸ’–

setgid() sets the effective group ID of the calling process. that's it, that's the whole glow-up ✨

and if the calling process is privileged β€” and by privileged we mean, precisely: it has the CAP_SETGID capability in its user namespace β€” then the real GID and the saved set-group-ID get set too. like, the whole trio. main character energy πŸ‘‘

under Linux, setgid() is implemented like the POSIX version with the _POSIX_SAVED_IDS feature. and the way that works is lowkey iconic: it lets a set-group-ID program that is not set-user-ID-root drop all of its group privileges, go do some unprivileged work, and then reengage the original effective group ID in a secure manner. so you can take the group privileges off, vibe unprivileged for a bit, and then put them back on safely 😌 no cap, that's genuinely useful.


πŸŽ€ RETURN VALUE πŸŽ€

  • On success, zero is returned πŸ₯³
  • On error, -1 is returned, and errno is set to indicate the error 😭

πŸ’€ ERRORS πŸ’€

  • EINVAL β€” The group ID specified in gid is not valid in this user namespace. so like, imagine a group that doesn't exist in your namespace. that one. 🚫
  • EPERM β€” The calling process is not privileged (does not have the CAP_SETGID capability in its user namespace), and gid does not match the real group ID or the saved set-group-ID of the calling process. basically: no permission, and you're not even asking for a group you already have. denied, bestie πŸ™ˆ

⭐ VERSIONS ⭐

🧚 C library/kernel differences 🧚

at the kernel level, user IDs and group IDs are a per-thread attribute. but POSIX says no bestie β€” all threads in a process must share the same credentials. periodt.

so the NPTL threading implementation handles the POSIX requirements by providing wrapper functions for the various system calls that change process UIDs and GIDs. these wrapper functions (including the one for setgid()) employ a signal-based technique to ensure that when one thread changes credentials, all of the other threads in the process also change their credentials. everyone matches, no one gets left out, the group chat is in sync πŸ’ž

for details, see nptl(7).


🌈 STANDARDS 🌈

POSIX.1-2024. she's certified, she's standardized, she ate πŸ’…


πŸ‘‘ HISTORY πŸ‘‘

POSIX.1-2001, SVr4.

and here's the lore πŸ“: the original Linux setgid() system call supported only 16-bit group IDs. subsequently, Linux 2.4 added setgid32() supporting 32-bit IDs. the glibc setgid() wrapper function transparently deals with the variation across kernel versions β€” so you never have to think about it, she just handles it for you 🫢


πŸ”₯ SEE ALSO πŸ”₯

getgid(2), setegid(2), setregid(2), capabilities(7), credentials(7), user_namespaces(7)


okay that's the whole page bestie, go forth and set those group IDs responsibly πŸ’–

this was brought to you by Linux man-pages 6.20, dated 2026-02-08, and yes, setgid(2) is serving exactly like you'd expect. slay πŸŒΈβœ¨πŸ’…

πŸ“¦ where this page comes from
  • arch rolling: man-pages 6.20-1 Β· BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
  • nixpkgs unstable: man-pages 6.20
  • πŸ“œ the page's license: Linux-man-pages-copyleft
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms