putenv(3)

πŸ’– putenv(3) β€” the "change or add an environment variable" era πŸ’–

okay bestie, we're in putenv(3) territory, which lives in the Library Functions Manual (that's the manual name, iykyk) and it's giving chaotic-but-iconic. Let's get into it 🫢


✨ NAME ✨

putenv β€” change or add an environment variable. that's it. that's the whole job. πŸ’…


πŸ“š LIBRARY πŸ“š

Standard C library (libc, -lc). the blueprint, the moment, the classic. πŸŽ€


🌸 SYNOPSIS 🌸

#include <stdlib.h>

int putenv(char *string);

πŸ¦‹ Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

putenv():
    _XOPEN_SOURCE
        || /* glibc >= 2.19: */ _DEFAULT_SOURCE
        || /* glibc <= 2.19: */ _SVID_SOURCE

yes gorgeous, you gotta declare your vibe (I mean your feature test macro) before glibc will let you have this one. slots open, no cap ✨


πŸ’œ DESCRIPTION πŸ’œ

so putenv() adds or changes the value of environment variables. lowkey iconic behaviour.

the argument string is of the form name=value. classic.

here's the tea β˜•:

  • if name does not already exist in the environment, then string is added to the environment. new entry, who dis πŸ’–
  • if name does exist, then the value of name in the environment is changed to value. makeover time πŸ’…

and now the part that makes this function spicy: the string pointed to by string becomes part of the environment, so altering the string changes the environment. not a copy, bestie. it's your string now. no take-backs, no backsies πŸ™ˆ


⭐ RETURN VALUE ⭐

putenv() returns zero on success. slay.

on failure, it returns a nonzero value, and errno is set to indicate the error. sad girl hours 😭


πŸ’€ ERRORS πŸ’€

  • ENOMEM β€” Insufficient space to allocate new environment. the environment said "no room, I'm booked" πŸ’€

πŸ‘‘ ATTRIBUTES πŸ‘‘

for an explanation of the terms used in this section, see attributes(7).

  • Interface: putenv()
  • Attribute: Thread safety
  • Value: MT-Unsafe const:env

so like... thread safety? not it. she's MT-Unsafe const:env, which is the technical way of saying "please don't share her across threads while she's mid-glow-up" 🫠


🌈 STANDARDS 🌈

POSIX.1-2008. certified, periodt ✨


🧚 HISTORY 🧚

POSIX.1-2001, SVr2, 4.3BSD-Reno. ancient lineage, main character energy since forever πŸ‘‘

putenv() is not required to be reentrant, and the one in glibc 2.0 is not, but the glibc 2.1 version is. glow-up confirmed πŸ’…

Since glibc 2.1.2, the glibc implementation conforms to SUSv2: the pointer string given to putenv() is used. In particular, this string becomes part of the environment; changing it later will change the environment.

⚠️ ok so this is the DRAMATIC part: (Thus, it is an error to call putenv() with an automatic variable as the argument, then return from the calling function while string is still part of the environment.) like, if you put a stack variable in there and then yeet out of the function, the environment is holding a pointer to something that no longer exists. that's undefined behaviour-flavoured chaos. do not. πŸ™ˆ

However, from glibc 2.0 to glibc 2.1.1, it differs: a copy of the string is used. on the one hand this causes a memory leak, and on the other hand it violates SUSv2. baby glibc was messy fr fr 😭

The 4.3BSD-Reno version, like glibc 2.0, uses a copy; this is fixed in all modern BSDs. growth! healing! 🌱

SUSv2 removes the const from the prototype, and so does glibc 2.1.3. bye const πŸ‘‹

✨ the nonstandard bonus round ✨

The GNU C library implementation provides a nonstandard extension. If string does not include an equal sign:

putenv("NAME");

then the named variable is removed from the caller's environment. surprise! she can also ghost variables πŸ’…βœ¨


πŸŽ€ SEE ALSO πŸŽ€


and that's the whole page, bestie 🫢 this was Linux man-pages 6.20, dated 2026-02-08, and we read putenv(3) together like the icons we are. go forth and not pass it a stack variable okay? mwah πŸ’–πŸŒΈπŸ¦‹

πŸ“¦ 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