Add fchdir(), dirfd()
Original patch by olh, modified by me to make dirfd() inline

diff --git a/include/dirent.h b/include/dirent.h
index 10dd138..4db4795 100644
--- a/include/dirent.h
+++ b/include/dirent.h
@@ -8,13 +8,25 @@
 #include <klibc/extern.h>
 #include <sys/dirent.h>
 
-#ifndef __IO_DIR_DEFINED
-struct _IO_dir;
+struct _IO_dir {
+  int __fd;
+
+#ifdef __KLIBC_DIRENT_INTERNALS
+  /* These fields for internal use only */
+
+  size_t bytes_left;
+  struct dirent *next;
+  /* Declaring this as an array of struct enforces correct alignment */
+  struct dirent buffer[15];     /* 15 times max dirent size =~ 4K */
 #endif
+};
 typedef struct _IO_dir DIR;
 
 __extern DIR *opendir(const char *);
 __extern struct dirent *readdir(DIR *);
 __extern int closedir(DIR *);
+static __inline__ int dirfd (DIR *__d) {
+  return __d->__fd;
+}
 
 #endif /* _DIRENT_H */
diff --git a/include/unistd.h b/include/unistd.h
index aff3c20..51fd7b7 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -60,6 +60,7 @@
 __extern int link(const char *, const char *);
 __extern int unlink(const char *);
 __extern int chdir(const char *);
+__extern int fchdir(int);
 __extern int chmod(const char *, mode_t);
 __extern int fchmod(int, mode_t);
 __extern int mkdir(const char *, mode_t);
diff --git a/klibc/SYSCALLS.def b/klibc/SYSCALLS.def
index b9c7cac..120dee9 100644
--- a/klibc/SYSCALLS.def
+++ b/klibc/SYSCALLS.def
@@ -86,6 +86,7 @@
 int link(const char *, const char *)
 int unlink(const char *)
 int chdir(const char *)
+int fchdir(int)
 int rename(const char *, const char *)
 int mknod(const char *, mode_t, dev_t)
 int chmod(const char *, mode_t)
diff --git a/klibc/include/dirent.h b/klibc/include/dirent.h
index 10dd138..4db4795 100644
--- a/klibc/include/dirent.h
+++ b/klibc/include/dirent.h
@@ -8,13 +8,25 @@
 #include <klibc/extern.h>
 #include <sys/dirent.h>
 
-#ifndef __IO_DIR_DEFINED
-struct _IO_dir;
+struct _IO_dir {
+  int __fd;
+
+#ifdef __KLIBC_DIRENT_INTERNALS
+  /* These fields for internal use only */
+
+  size_t bytes_left;
+  struct dirent *next;
+  /* Declaring this as an array of struct enforces correct alignment */
+  struct dirent buffer[15];     /* 15 times max dirent size =~ 4K */
 #endif
+};
 typedef struct _IO_dir DIR;
 
 __extern DIR *opendir(const char *);
 __extern struct dirent *readdir(DIR *);
 __extern int closedir(DIR *);
+static __inline__ int dirfd (DIR *__d) {
+  return __d->__fd;
+}
 
 #endif /* _DIRENT_H */
diff --git a/klibc/include/unistd.h b/klibc/include/unistd.h
index aff3c20..51fd7b7 100644
--- a/klibc/include/unistd.h
+++ b/klibc/include/unistd.h
@@ -60,6 +60,7 @@
 __extern int link(const char *, const char *);
 __extern int unlink(const char *);
 __extern int chdir(const char *);
+__extern int fchdir(int);
 __extern int chmod(const char *, mode_t);
 __extern int fchmod(int, mode_t);
 __extern int mkdir(const char *, mode_t);
diff --git a/klibc/readdir.c b/klibc/readdir.c
index 3fc20a8..acfe588 100644
--- a/klibc/readdir.c
+++ b/klibc/readdir.c
@@ -5,18 +5,8 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <stdlib.h>
-#include <sys/dirent.h>
-#include <stdio.h>
 
-#define __IO_DIR_DEFINED
-struct _IO_dir {
-  int fd;
-  size_t bytes_left;
-  struct dirent *next;
-  /* Declaring this as an array of struct enforces correct alignment */
-  struct dirent buffer[15];	/* 15 times max dirent size =~ 4K */
-};
-
+#define __KLIBC_DIRENT_INTERNALS
 #include <dirent.h>
 
 DIR *opendir(const char *name)
@@ -26,9 +16,9 @@
   if ( !dp )
     return NULL;
 
-  dp->fd = open(name, O_DIRECTORY|O_RDONLY);
+  dp->__fd = open(name, O_DIRECTORY|O_RDONLY);
 
-  if ( dp->fd < 0 ) {
+  if ( dp->__fd < 0 ) {
     free(dp);
     return NULL;
   }
@@ -44,7 +34,7 @@
   int rv;
   
   if ( !dir->bytes_left ) {
-    rv = getdents(dir->fd, dir->buffer, sizeof(dir->buffer));
+    rv = getdents(dir->__fd, dir->buffer, sizeof(dir->buffer));
     if ( rv <= 0 )
       return NULL;
     dir->bytes_left = rv;
@@ -61,7 +51,7 @@
 int closedir(DIR *dir)
 {
   int rv;
-  rv = close(dir->fd);
+  rv = close(dir->__fd);
   free(dir);
   return rv;
 }