// Returns a pointer to the value associated with name, // or nullptr if not found. // Starts searching environ from *offset, // and sets *offset to the index at which the variable was found. staticchar* __findenv(constchar* name, size_t name_length, size_t* offset) { if (environ != nullptr) { for (char** p = environ + *offset; *p != nullptr; ++p) { if (!strncmp(name, *p, name_length) && (*p)[name_length] == '=') {
*offset = p - environ; return *p + name_length + 1;
}
}
} return nullptr;
}
staticbool __add_new_environ_slot(size_t* offset) {
size_t old_size = 0; if (environ != nullptr) { char** p = environ; for (; *p != nullptr; ++p) ++old_size;
}
// Keep track of the most recent environ allocation we did. // We can't just pass environ to reallocarray() because that might // have been replaced with non-heap-allocated memory. Supporting that // is probably a mistake, but it's our (and everyone else's) historical // behavior. staticchar** old_env = nullptr;
char** new_env = static_cast<char**>(reallocarray(old_env, old_size + 2, sizeof(char*))); if (!new_env) returnfalse; if (old_env != environ && environ != nullptr) {
memcpy(new_env, environ, old_size * sizeof(char*));
}
environ = old_env = new_env;
environ[old_size] = environ[old_size + 1] = nullptr;
*offset = old_size; returntrue;
}
template <typename F> staticint __update_environ(constchar* name, size_t name_length, bool overwrite, F string_maker) {
size_t offset = 0; if (__findenv(name, name_length, &offset) != nullptr) { if (!overwrite) return0;
} else { if (!__add_new_environ_slot(&offset)) return -1;
}
int putenv(char* str) { // Unlike the other functions where the input MUST NOT contain '=', // here the input MUST contain '='.
size_t name_length; if (str == nullptr ||
(name_length = strchrnul(str, '=') - str) == 0 ||
str[name_length] != '=') {
errno = EINVAL; return -1;
}
// While setenv()/putenv() will always ensure there's at most one assignment to any given name, // callers could replace environ with a malformed array. // getenv() wouldn't care because it will always stop at the first match, // but unsetenv() needs to make sure that _all_ assignments are removed. // POSIX says "If more than one string in an environment of a process has the same name, // the consequences are undefined" so this isn't _required_ to be a loop, // but it matches what other implementations do.
ScopedWriteLock locker(&g_environ_lock);
size_t offset = 0; while (__findenv(name, name_length, &offset)) { for (char** p = &environ[offset];; ++p) { if (!(*p = *(p + 1))) { break;
}
}
} return0;
}
int clearenv() {
ScopedWriteLock locker(&g_environ_lock); char** old_environ = environ;
environ = nullptr; if (old_environ != nullptr) { for (; *old_environ; ++old_environ) {
*old_environ = nullptr;
}
} return0;
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-06-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.