Index: src/pmc/os.pmc
===================================================================
--- src/pmc/os.pmc	(revision 11510)
+++ src/pmc/os.pmc	(working copy)
@@ -21,6 +21,8 @@
 
 #ifdef WIN32
 #include <direct.h>
+#else
+#include <dirent.h>
 #endif
 
 #include "parrot/parrot.h"
@@ -429,6 +431,43 @@
 #endif
     }
 
+/*
+
+=item C<PMC* ls(STRING *path)>
+
+Changes the current working directory to the one specified by C<path>.
+
+=cut
+
+*/
+
+    METHOD PMC* ls(STRING *path) {
+        int error;
+        DIR* dir;
+        struct dirent* file;
+        PMC *array;
+        STRING *filename;
+        char *cpath = string_to_cstring(interpreter, path);
+        array = pmc_new(interpreter, enum_class_ResizableStringArray);
+        if ((dir = opendir(cpath)) != NULL) {
+            while ((file = readdir(dir)) != NULL) {
+                filename = string_from_cstring(interpreter, file->d_name, file->d_namlen);
+                VTABLE_push_string(interpreter, array, filename);
+            }
+            string_cstring_free(cpath);
+            error = closedir(dir);
+            if (error) {
+                char *errmsg = strerror(errno);
+                real_exception(interpreter, NULL, E_SystemError, errmsg);
+            }
+        }
+        else {
+            char *errmsg = strerror(errno);
+            real_exception(interpreter, NULL, E_SystemError, errmsg);
+        }
+        return array;
+    }
+
 }
 
 /*
Index: t/pmc/os.t
===================================================================
--- t/pmc/os.t	(revision 11510)
+++ t/pmc/os.t	(working copy)
@@ -6,7 +6,7 @@
 use warnings;
 use lib qw( . lib ../lib ../../lib );
 use Test::More;
-use Parrot::Test tests => 13;
+use Parrot::Test tests => 14;
 use Parrot::Config;
 use Cwd;
 use File::Spec;
@@ -321,3 +321,26 @@
   ok( $nl > 1, "hard link was really created");
   unlink "xpto" if -f "xpto"
 }
+
+# Test ls
+pir_output_is(<< 'CODE', << "OUT", "Test ls");
+.sub main :main
+    $P1 = new .OS
+    $P2 = $P1."ls"('.')
+
+    $I0 = 0
+foo:
+    $I1 = $P2
+    unless $I0 < $I1 goto bar
+    $S0 = $P2[$I0]
+    if $S0 == "MANIFEST" goto baz
+    inc $I0
+    goto foo
+bar:
+    print "not "
+baz:
+    print "ok\n"
+.end
+CODE
+ok
+OUT
