Index: uspace/lib/posix/Makefile
===================================================================
--- uspace/lib/posix/Makefile	(revision 458d3569b4ee32678a5a8730ad70b5d4c97e4424)
+++ uspace/lib/posix/Makefile	(revision 2b83add11c5bcd828a9b4eca961890f4cbac0c38)
@@ -44,4 +44,5 @@
 	stdio.c \
 	stdlib.c \
+	stdlib/strtol.c \
 	stdlib/strtold.c \
 	string.c \
Index: uspace/lib/posix/stdlib.c
===================================================================
--- uspace/lib/posix/stdlib.c	(revision 458d3569b4ee32678a5a8730ad70b5d4c97e4424)
+++ uspace/lib/posix/stdlib.c	(revision 2b83add11c5bcd828a9b4eca961890f4cbac0c38)
@@ -37,5 +37,9 @@
 
 #include "stdlib.h"
+#include "libc/sort.h"
+#include "libc/str.h"
+#include "libc/vfs/vfs.h"
 #include "internal/common.h"
+#include <errno.h>  // FIXME: use POSIX errno
 
 /**
@@ -54,4 +58,50 @@
 /**
  * 
+ * @param i Input value.
+ * @return Absolute value of the parameter.
+ */
+int posix_abs(int i)
+{
+	return i < 0 ? -i : i;
+}
+
+/**
+ * 
+ * @param i Input value.
+ * @return Absolute value of the parameter.
+ */
+long posix_labs(long i)
+{
+	return i < 0 ? -i : i;
+}
+
+/**
+ * 
+ * @param i Input value.
+ * @return Absolute value of the parameter.
+ */
+long long posix_llabs(long long i)
+{
+	return i < 0 ? -i : i;
+}
+
+/**
+ * Private helper function that serves as a compare function for qsort().
+ *
+ * @param elem1 First element to compare.
+ * @param elem2 Second element to compare.
+ * @param compare Comparison function without userdata parameter.
+ *
+ * @return Relative ordering of the elements.
+ */
+static int sort_compare_wrapper(void *elem1, void *elem2, void *userdata)
+{
+	int (*compare)(const void *, const void *) = userdata;
+	return compare(elem1, elem2);
+}
+
+/**
+ * Array sorting utilizing the quicksort algorithm.
+ *
  * @param array
  * @param count
@@ -59,33 +109,22 @@
  * @param compare
  */
-int posix_abs(int i)
-{
-	// TODO
-	not_implemented();
-}
-
-/**
- *
- * @param array
- * @param count
- * @param size
- * @param compare
- */
 void posix_qsort(void *array, size_t count, size_t size,
     int (*compare)(const void *, const void *))
 {
-	// TODO
-	not_implemented();
-}
-
-/**
+	/* Implemented in libc with one extra argument. */
+	qsort(array, count, size, sort_compare_wrapper, compare);
+}
+
+/**
+ * Retrieve a value of the given environment variable.
+ * Since HelenOS doesn't support env variables at the moment,
+ * this function always returns NULL.
  *
  * @param name
- * @return
+ * @return Always NULL.
  */
 char *posix_getenv(const char *name)
 {
-	// TODO
-	not_implemented();
+	return NULL;
 }
 
@@ -110,6 +149,40 @@
 char *posix_realpath(const char *name, char *resolved)
 {
-	// TODO
-	not_implemented();
+	#ifndef PATH_MAX
+		assert(resolved == NULL);
+	#endif
+	
+	if (name == NULL) {
+		errno = EINVAL;
+		return NULL;
+	}
+	
+	// TODO: symlink resolution
+	
+	/* Function absolutize is implemented in libc and declared in vfs.h.
+	 * No more processing is required as HelenOS doesn't have symlinks
+	 * so far (as far as I can tell), although this function will need
+	 * to be updated when that support is implemented.
+	 */
+	char* absolute = absolutize(name, NULL);
+	
+	if (absolute == NULL) {
+		/* POSIX requires some specific errnos to be set
+		 * for some cases, but there is no way to find out from
+		 * absolutize().
+		 */
+		errno = EINVAL;
+		return NULL;
+	}
+	
+	if (resolved == NULL) {
+		return absolute;
+	} else {
+		#ifdef PATH_MAX
+			str_cpy(resolved, PATH_MAX, absolute);
+		#endif
+		free(absolute);
+		return resolved;
+	}
 }
 
@@ -119,10 +192,9 @@
  *
  * @param nptr
- * @param endptr
- * @return
- */
-float posix_strtof(const char *restrict nptr, char **restrict endptr)
-{
-	return (float) posix_strtold(nptr, endptr);
+ * @return
+ */
+double posix_atof(const char *nptr)
+{
+	return posix_strtod(nptr, NULL);
 }
 
@@ -135,18 +207,20 @@
  * @return
  */
+float posix_strtof(const char *restrict nptr, char **restrict endptr)
+{
+	return (float) posix_strtold(nptr, endptr);
+}
+
+/**
+ * Converts a string representation of a floating-point number to
+ * its native representation. See posix_strtold().
+ *
+ * @param nptr
+ * @param endptr
+ * @return
+ */
 double posix_strtod(const char *restrict nptr, char **restrict endptr)
 {
 	return (double) posix_strtold(nptr, endptr);
-}
-
-/**
- * 
- * @param str
- * @return
- */
-int posix_atoi(const char *str)
-{
-	// TODO
-	not_implemented();
 }
 
Index: uspace/lib/posix/stdlib.h
===================================================================
--- uspace/lib/posix/stdlib.h	(revision 458d3569b4ee32678a5a8730ad70b5d4c97e4424)
+++ uspace/lib/posix/stdlib.h	(revision 2b83add11c5bcd828a9b4eca961890f4cbac0c38)
@@ -53,4 +53,6 @@
 /* Absolute Value */
 extern int posix_abs(int i);
+extern long posix_labs(long i);
+extern long long posix_llabs(long long i);
 
 /* Array Sort Function */
@@ -66,4 +68,5 @@
 
 /* Floating Point Conversion */
+extern double posix_atof(const char *nptr);
 extern float posix_strtof(const char *restrict nptr, char **restrict endptr);
 extern double posix_strtod(const char *restrict nptr, char **restrict endptr);
@@ -71,5 +74,17 @@
 
 /* Integer Conversion */
-extern int posix_atoi(const char *str);
+extern int posix_atoi(const char *nptr);
+extern long int posix_atol(const char *nptr);
+extern long long int posix_atoll(const char *nptr);
+
+extern long int posix_strtol(const char *restrict nptr,
+    char **restrict endptr, int base);
+extern long long int posix_strtoll(const char *restrict nptr,
+    char **restrict endptr, int base);
+extern unsigned long int posix_strtoul(const char *restrict nptr,
+    char **restrict endptr, int base);
+extern unsigned long long int posix_strtoull(
+    const char *restrict nptr, char **restrict endptr, int base);
+
 
 /* Memory Allocation */
@@ -86,11 +101,15 @@
 
 	#define abs posix_abs
+	#define labs posix_labs
+	#define llabs posix_llabs
 
 	#define qsort posix_qsort
 
 	#define getenv posix_getenv
+	#define putenv posix_putenv
 
 	#define realpath posix_realpath
 	
+	#define atof posix_atof
 	#define strtof posix_strtof
 	#define strtod posix_strtod
@@ -98,4 +117,10 @@
 	
 	#define atoi posix_atoi
+	#define atol posix_atol
+	#define atoll posix_atoll
+	#define strtol posix_strtol
+	#define strtoll posix_strtoll
+	#define strtoul posix_strtoul
+	#define strtoull posix_strtoull
 
 	#define malloc posix_malloc
Index: uspace/lib/posix/stdlib/strtol.c
===================================================================
--- uspace/lib/posix/stdlib/strtol.c	(revision 2b83add11c5bcd828a9b4eca961890f4cbac0c38)
+++ uspace/lib/posix/stdlib/strtol.c	(revision 2b83add11c5bcd828a9b4eca961890f4cbac0c38)
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2011 Jiri Zarevucky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libposix
+ * @{
+ */
+/** @file
+ */
+
+#define LIBPOSIX_INTERNAL
+
+#include "../internal/common.h"
+#include "../stdlib.h"
+#include <errno.h>  // FIXME: use POSIX errno
+#include "../limits.h"
+#include "../ctype.h"
+
+// TODO: documentation
+
+static inline bool is_digit_in_base(int c, int base)
+{
+	if (base <= 10) {
+		return c >= '0' && c < '0' + base;
+	} else {
+		return isdigit(c) ||
+		    (tolower(c) >= 'a' && tolower(c) < ('a' + base - 10));
+	}
+}
+
+static inline int get_digit_in_base(int c, int base)
+{
+	if (c <= '9') {
+		return c - '0';
+	} else {
+		return 10 + tolower(c) - 'a';
+	}
+}
+
+static inline unsigned long long internal_strtol(
+    const char *restrict nptr, char **restrict endptr, int base,
+    const long long min_value, const unsigned long long max_value,
+    bool *restrict out_negative)
+{
+	if (nptr == NULL) {
+		errno = EINVAL;
+		return 0;
+	}
+	
+	if (base < 0 || base == 1 || base > 36) {
+		errno = EINVAL;
+		return 0;
+	}
+	
+	unsigned long long real_max_value = max_value;
+	
+	/* Current index in the input string. */
+	int i = 0;
+	bool negative = false;
+	
+	/* Skip whitespace. */
+	while (isspace(nptr[i])) {
+		i++;
+	}
+	
+	/* Parse sign. */
+	switch (nptr[i]) {
+	case '-':
+		negative = true;
+		real_max_value = -min_value;
+		/* fallthrough */
+	case '+':
+		i++;
+	}
+	
+	/* Figure out the base. */
+	switch (base) {
+	case 0:
+		if (nptr[i] == '0') {
+			if (tolower(nptr[i + 1]) == 'x') {
+				base = 16;
+				i += 2;
+			} else {
+				base = 8;
+			}
+		} else {
+			base = 10;
+		}
+		break;
+	case 16:
+		if (nptr[i] == '0' && tolower(nptr[i + 1]) == 'x') {
+			i += 2;
+		}
+		break;
+	}
+	
+	if (!is_digit_in_base(nptr[i], base)) {
+		/* No digits to parse, invalid input. */
+		
+		errno = EINVAL;
+		if (endptr != NULL) {
+			*endptr = (char *) nptr;
+		}
+		return 0;
+	}
+	
+	/* Maximal value to which a digit can be added without a risk
+	 * of overflow.
+	 */
+	unsigned long long max_safe_value = (real_max_value - base + 1) / base;
+	
+	unsigned long long result = 0;
+	
+	if (real_max_value == 0) {
+		/* Special case when a negative number is parsed as
+		 * unsigned integer. Only -0 is accepted.
+		 */
+		
+		while (is_digit_in_base(nptr[i], base)) {
+			if (nptr[i] != '0') {
+				errno = ERANGE;
+				result = max_value;
+			}
+			i++;
+		}
+	}
+	
+	while (is_digit_in_base(nptr[i], base)) {
+		int digit = get_digit_in_base(nptr[i], base);
+		
+		if (result > max_safe_value) {
+			/* corner case, check for overflow */
+			
+			unsigned long long
+			    boundary = (real_max_value - digit) / base;
+			
+			if (result > boundary) {
+				/* overflow */
+				errno = ERANGE;
+				result = max_value;
+				break;
+			}
+		}
+		
+		result = result * base + digit;
+		i++;
+	}
+	
+	if (endptr != NULL) {
+		/* Move the pointer to the end of the number,
+		 * in case it isn't there already.
+		 */
+		while (is_digit_in_base(nptr[i], base)) {
+			i++;
+		}
+		
+		*endptr = (char *) &nptr[i];
+	}
+	if (out_negative != NULL) {
+		*out_negative = negative;
+	}
+	return result;
+}
+
+int posix_atoi(const char *nptr)
+{
+	bool neg = false;
+	unsigned long long result =
+	    internal_strtol(nptr, NULL, 10, INT_MIN, INT_MAX, &neg);
+
+	return (int) (neg ? -result : result);
+}
+
+long posix_atol(const char *nptr)
+{
+	bool neg = false;
+	unsigned long long result =
+	    internal_strtol(nptr, NULL, 10, LONG_MIN, LONG_MAX, &neg);
+
+	return (long) (neg ? -result : result);
+}
+
+long long posix_atoll(const char *nptr)
+{
+	bool neg = false;
+	unsigned long long result =
+	    internal_strtol(nptr, NULL, 10, LLONG_MIN, LLONG_MAX, &neg);
+
+	return (long long) (neg ? -result : result);
+}
+
+long posix_strtol(const char *restrict nptr, char **restrict endptr, int base)
+{
+	bool neg = false;
+	unsigned long long result =
+	    internal_strtol(nptr, endptr, base, LONG_MIN, LONG_MAX, &neg);
+
+	return (long) (neg ? -result : result);
+}
+
+long long posix_strtoll(
+    const char *restrict nptr, char **restrict endptr, int base)
+{
+	bool neg = false;
+	unsigned long long result =
+	    internal_strtol(nptr, endptr, base, LLONG_MIN, LLONG_MAX, &neg);
+
+	return (long long) (neg ? -result : result);
+}
+
+unsigned long posix_strtoul(
+    const char *restrict nptr, char **restrict endptr, int base)
+{
+	unsigned long long result =
+	    internal_strtol(nptr, endptr, base, 0, ULONG_MAX, NULL);
+
+	return (unsigned long) result;
+}
+
+unsigned long long posix_strtoull(
+    const char *restrict nptr, char **restrict endptr, int base)
+{
+	return internal_strtol(nptr, endptr, base, 0, ULLONG_MAX, NULL);
+}
+
+
+/** @}
+ */
+
