summaryrefslogtreecommitdiff
path: root/Userland/Libraries
diff options
context:
space:
mode:
authorMacDue <macdue@dueutil.tech>2023-02-04 15:44:33 +0000
committerAndreas Kling <kling@serenityos.org>2023-02-05 16:40:51 +0100
commiteea4dc5bfe271f405eb9e0db461a286f4fe2cc6b (patch)
treefc4a54ed93c280683d8da8a8a188994a9ac87048 /Userland/Libraries
parentf4236e61bf877194df72059cb64be3f49cfebe53 (diff)
downloadserenity-eea4dc5bfe271f405eb9e0db461a286f4fe2cc6b.zip
LibCore+LibC: Add putenv() wrapper
This is made safe with a special serenity_putenv() function in LibC.
Diffstat (limited to 'Userland/Libraries')
-rw-r--r--Userland/Libraries/LibC/stdlib.cpp8
-rw-r--r--Userland/Libraries/LibC/stdlib.h1
-rw-r--r--Userland/Libraries/LibCore/System.cpp14
-rw-r--r--Userland/Libraries/LibCore/System.h1
4 files changed, 24 insertions, 0 deletions
diff --git a/Userland/Libraries/LibC/stdlib.cpp b/Userland/Libraries/LibC/stdlib.cpp
index a8d2b16bb7..1cada26c97 100644
--- a/Userland/Libraries/LibC/stdlib.cpp
+++ b/Userland/Libraries/LibC/stdlib.cpp
@@ -486,6 +486,14 @@ int serenity_setenv(char const* name, ssize_t name_length, char const* value, ss
return putenv(var);
}
+// A non-evil version of putenv that will strdup the env (and free it later)
+int serenity_putenv(char const* new_var, size_t length)
+{
+ auto* var = strndup(new_var, length);
+ s_malloced_environment_variables.set((FlatPtr)var);
+ return putenv(var);
+}
+
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/putenv.html
int putenv(char* new_var)
{
diff --git a/Userland/Libraries/LibC/stdlib.h b/Userland/Libraries/LibC/stdlib.h
index d1d96daffb..eb955ae98b 100644
--- a/Userland/Libraries/LibC/stdlib.h
+++ b/Userland/Libraries/LibC/stdlib.h
@@ -28,6 +28,7 @@ __attribute__((alloc_size(2))) void* realloc(void* ptr, size_t);
char* getenv(char const* name);
char* secure_getenv(char const* name);
int putenv(char*);
+int serenity_putenv(char const* new_var, size_t length);
int unsetenv(char const*);
int clearenv(void);
int setenv(char const* name, char const* value, int overwrite);
diff --git a/Userland/Libraries/LibCore/System.cpp b/Userland/Libraries/LibCore/System.cpp
index e266eceaba..8fbda2e159 100644
--- a/Userland/Libraries/LibCore/System.cpp
+++ b/Userland/Libraries/LibCore/System.cpp
@@ -1442,6 +1442,20 @@ ErrorOr<void> setenv(StringView name, StringView value, bool overwrite)
return {};
}
+ErrorOr<void> putenv(StringView env)
+{
+#ifdef AK_OS_SERENITY
+ auto rc = serenity_putenv(env.characters_without_null_termination(), env.length());
+#else
+ // Leak somewhat unavoidable here due to the putenv API.
+ auto leaked_new_env = strndup(env.characters_without_null_termination(), env.length());
+ auto rc = ::putenv(leaked_new_env);
+#endif
+ if (rc < 0)
+ return Error::from_errno(errno);
+ return {};
+}
+
ErrorOr<int> posix_openpt(int flags)
{
int const rc = ::posix_openpt(flags);
diff --git a/Userland/Libraries/LibCore/System.h b/Userland/Libraries/LibCore/System.h
index 8791efc082..4601bc54cc 100644
--- a/Userland/Libraries/LibCore/System.h
+++ b/Userland/Libraries/LibCore/System.h
@@ -207,6 +207,7 @@ ErrorOr<void> setgroups(Span<gid_t const>);
ErrorOr<void> mknod(StringView pathname, mode_t mode, dev_t dev);
ErrorOr<void> mkfifo(StringView pathname, mode_t mode);
ErrorOr<void> setenv(StringView, StringView, bool);
+ErrorOr<void> putenv(StringView);
ErrorOr<int> posix_openpt(int flags);
ErrorOr<void> grantpt(int fildes);
ErrorOr<void> unlockpt(int fildes);