diff --git a/libc/Makefile b/libc/Makefile
index dbc5d54c..c8565523 100644
--- a/libc/Makefile
+++ b/libc/Makefile
@@ -221,6 +221,8 @@ getegid.o \
geteuid.o \
getgid.o \
gethostname.o \
+getlogin.o \
+getlogin_r.o \
getpagesize.o \
getpid.o \
getppid.o \
diff --git a/libc/getlogin.cpp b/libc/getlogin.cpp
new file mode 100644
index 00000000..b1e88213
--- /dev/null
+++ b/libc/getlogin.cpp
@@ -0,0 +1,48 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2013.
+
+ This file is part of the Sortix C Library.
+
+ The Sortix C Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ The Sortix C Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the Sortix C Library. If not, see .
+
+ getlogin.cpp
+ Get name of user logged in at the controlling terminal.
+
+*******************************************************************************/
+
+#include
+#include
+#include
+#include
+
+extern "C" char* getlogin()
+{
+ static char* buffer = NULL;
+ static size_t buffer_size = 0;
+
+ int ret;
+ while ( !buffer_size ||
+ ((ret = getlogin_r(buffer, buffer_size)) < 0 && errno == ERANGE) )
+ {
+ size_t new_buffer_size = buffer_size ? buffer_size * 2 : 64;
+ char* new_buffer = (char*) realloc(buffer, new_buffer_size);
+ if ( !new_buffer )
+ return NULL;
+ buffer = new_buffer;
+ buffer_size = new_buffer_size;
+ }
+
+ return ret == 0 ? buffer : NULL;
+}
diff --git a/libc/getlogin_r.cpp b/libc/getlogin_r.cpp
new file mode 100644
index 00000000..55675280
--- /dev/null
+++ b/libc/getlogin_r.cpp
@@ -0,0 +1,39 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2013.
+
+ This file is part of the Sortix C Library.
+
+ The Sortix C Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ The Sortix C Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the Sortix C Library. If not, see .
+
+ getlogin_r.cpp
+ Get name of user logged ina t the controlling terminal.
+
+*******************************************************************************/
+
+#include
+#include
+#include
+#include
+
+extern "C" int getlogin_r(char* buf, size_t size)
+{
+ const char* env_username = getenv("USERNAME");
+ const char* username = env_username ? env_username : "root";
+ size_t username_len = strlen(username);
+ if ( size < (username_len + 1) * sizeof(char) )
+ return errno = ERANGE, -1;
+ strcpy(buf, username);
+ return 0;
+}
diff --git a/libc/include/unistd.h b/libc/include/unistd.h
index 80cce606..fa49e87b 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -1,6 +1,6 @@
/*******************************************************************************
- Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
+ Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of the Sortix C Library.
@@ -115,8 +115,6 @@ int fexecve(int, char* const [], char* const []);
long fpathconf(int, int);
int getgroups(int, gid_t []);
long gethostid(void);
-char* getlogin(void);
-int getlogin_r(char*, size_t);
int getopt(int, char* const [], const char*);
pid_t getpgid(pid_t);
pid_t getpgrp(void);
@@ -170,6 +168,8 @@ char* get_current_dir_name(void);
gid_t getegid(void);
uid_t geteuid(void);
int gethostname(char*, size_t);
+char* getlogin(void);
+int getlogin_r(char*, size_t);
pid_t getpid(void);
pid_t getppid(void);
uid_t getuid(void);
diff --git a/libc/pwent.cpp b/libc/pwent.cpp
index a1e0571b..cd7cc90d 100644
--- a/libc/pwent.cpp
+++ b/libc/pwent.cpp
@@ -113,11 +113,3 @@ extern "C" int getpwuid_r(uid_t uid, struct passwd* pw, char* buf,
*ret = pw;
return 0;
}
-
-extern "C" char* getlogin()
-{
- static char username[64];
- // TODO: Potential buffer overflow.
- strcpy(username, getenv("USERNAME") ? getenv("USERNAME") : ROOT_NAME);
- return username;
-}