diff --git a/libc/Makefile b/libc/Makefile
index d9bec2ca..2b4a2489 100644
--- a/libc/Makefile
+++ b/libc/Makefile
@@ -22,7 +22,17 @@ aux/c++.o \
aux/op-new.o \
ctype/ctype.o \
dirent/alphasort.o \
-dirent/dir.o \
+dirent/closedir.o \
+dirent/dclearerr.o \
+dirent/dcloseall.o \
+dirent/deof.o \
+dirent/derror.o \
+dirent/dirfd.o \
+dirent/dnewdir.o \
+dirent/dregister.o \
+dirent/dunregister.o \
+dirent/readdir.o \
+dirent/rewinddir.o \
dirent/versionsort.o \
errno/errno.o \
fnmatch/fnmatch.o \
diff --git a/libc/dirent/closedir.cpp b/libc/dirent/closedir.cpp
new file mode 100644
index 00000000..52c31a6b
--- /dev/null
+++ b/libc/dirent/closedir.cpp
@@ -0,0 +1,37 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2011, 2014.
+
+ 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 .
+
+ dirent/closedir.cpp
+ Closes a directory stream.
+
+*******************************************************************************/
+
+#include
+#include
+#include
+
+extern "C" int closedir(DIR* dir)
+{
+ int result = dir->close_func ? dir->close_func(dir->user) : 0;
+ dunregister(dir);
+ free(dir->entry);
+ if ( dir->free_func )
+ dir->free_func(dir);
+ return result;
+}
diff --git a/libc/dirent/dclearerr.cpp b/libc/dirent/dclearerr.cpp
new file mode 100644
index 00000000..76b3c1dc
--- /dev/null
+++ b/libc/dirent/dclearerr.cpp
@@ -0,0 +1,31 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2011, 2014.
+
+ 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 .
+
+ dirent/dclearerr.cpp
+ Clears the error flag from a directory stream.
+
+*******************************************************************************/
+
+#include
+#include
+
+extern "C" void dclearerr(DIR* dir)
+{
+ dir->flags &= ~_DIR_ERROR;
+}
diff --git a/libc/dirent/dcloseall.cpp b/libc/dirent/dcloseall.cpp
new file mode 100644
index 00000000..84ef862e
--- /dev/null
+++ b/libc/dirent/dcloseall.cpp
@@ -0,0 +1,37 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2011, 2014.
+
+ 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 .
+
+ dirent/dcloseall.cpp
+ Closes all registered directory streams.
+
+*******************************************************************************/
+
+#include
+#include
+#include
+
+extern "C" { DIR* __firstdir = NULL; }
+
+extern "C" int dcloseall(void)
+{
+ int result = 0;
+ while ( __firstdir )
+ result |= closedir(__firstdir);
+ return result ? EOF : 0;
+}
diff --git a/libc/dirent/deof.cpp b/libc/dirent/deof.cpp
new file mode 100644
index 00000000..26c552de
--- /dev/null
+++ b/libc/dirent/deof.cpp
@@ -0,0 +1,31 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2011, 2014.
+
+ 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 .
+
+ dirent/deof.cpp
+ Returns the end-of-file flag of a directory stream.
+
+*******************************************************************************/
+
+#include
+#include
+
+extern "C" int deof(DIR* dir)
+{
+ return dir->flags & _DIR_EOF;
+}
diff --git a/libc/dirent/derror.cpp b/libc/dirent/derror.cpp
new file mode 100644
index 00000000..ac51b482
--- /dev/null
+++ b/libc/dirent/derror.cpp
@@ -0,0 +1,31 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2011, 2014.
+
+ 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 .
+
+ dirent/derror.cpp
+ Returns the error flag of a directory stream.
+
+*******************************************************************************/
+
+#include
+#include
+
+extern "C" int derror(DIR* dir)
+{
+ return dir->flags & _DIR_ERROR;
+}
diff --git a/libc/dirent/dirfd.cpp b/libc/dirent/dirfd.cpp
new file mode 100644
index 00000000..dcc4dc04
--- /dev/null
+++ b/libc/dirent/dirfd.cpp
@@ -0,0 +1,34 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2011, 2014.
+
+ 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 .
+
+ dirent/dirfd.cpp
+ Returns the file descriptor associated with the directory stream.
+
+*******************************************************************************/
+
+#include
+#include
+#include
+
+extern "C" int dirfd(DIR* dir)
+{
+ if ( !dir->fd_func )
+ return errno = EBADF, 0;
+ return dir->fd_func(dir->user);
+}
diff --git a/libc/dirent/dnewdir.cpp b/libc/dirent/dnewdir.cpp
new file mode 100644
index 00000000..b2f0148b
--- /dev/null
+++ b/libc/dirent/dnewdir.cpp
@@ -0,0 +1,44 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2011, 2014.
+
+ 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 .
+
+ dirent/dnewdir.cpp
+ Allocates and registers a new directory stream structure.
+
+*******************************************************************************/
+
+#include
+#include
+#include
+#include
+
+static void dfreedir(DIR* dir)
+{
+ free(dir);
+}
+
+extern "C" DIR* dnewdir(void)
+{
+ DIR* dir = (DIR*) calloc(sizeof(DIR), 1);
+ if ( !dir )
+ return NULL;
+ dir->flags = 0;
+ dir->free_func = dfreedir;
+ dregister(dir);
+ return dir;
+}
diff --git a/libc/dirent/dregister.cpp b/libc/dirent/dregister.cpp
new file mode 100644
index 00000000..6e05106e
--- /dev/null
+++ b/libc/dirent/dregister.cpp
@@ -0,0 +1,34 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2011, 2014.
+
+ 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 .
+
+ dirent/dregister.cpp
+ Registers an directory stream for later automatic closing.
+
+*******************************************************************************/
+
+#include
+#include
+
+extern "C" void dregister(DIR* dir)
+{
+ dir->flags |= _DIR_REGISTERED;
+ if ( (dir->next = __firstdir) )
+ dir->next->prev = dir;
+ __firstdir = dir;
+}
diff --git a/libc/dirent/dunregister.cpp b/libc/dirent/dunregister.cpp
new file mode 100644
index 00000000..2b1d544f
--- /dev/null
+++ b/libc/dirent/dunregister.cpp
@@ -0,0 +1,39 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2011, 2014.
+
+ 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 .
+
+ dirent/dunregister.cpp
+ Unregisters an directory stream for later automatic closing.
+
+*******************************************************************************/
+
+#include
+#include
+
+extern "C" void dunregister(DIR* dir)
+{
+ if ( !(dir->flags & _DIR_REGISTERED) )
+ return;
+ if ( !dir->prev )
+ __firstdir = dir->next;
+ if ( dir->prev )
+ dir->prev->next = dir->next;
+ if ( dir->next )
+ dir->next->prev = dir->prev;
+ dir->flags &= ~_DIR_REGISTERED;
+}
diff --git a/libc/dirent/dir.cpp b/libc/dirent/readdir.cpp
similarity index 50%
rename from libc/dirent/dir.cpp
rename to libc/dirent/readdir.cpp
index f04a7216..9811ef0c 100644
--- a/libc/dirent/dir.cpp
+++ b/libc/dirent/readdir.cpp
@@ -1,6 +1,6 @@
/*******************************************************************************
- Copyright(C) Jonas 'Sortie' Termansen 2011.
+ Copyright(C) Jonas 'Sortie' Termansen 2011, 2014.
This file is part of the Sortix C Library.
@@ -17,50 +17,24 @@
You should have received a copy of the GNU Lesser General Public License
along with the Sortix C Library. If not, see .
- dirent/dir.cpp
- DIR* is an interface allowing various directory backends.
+ dirent/readdir.cpp
+ Reads a directory entry from a directory stream into a DIR-specific buffer.
*******************************************************************************/
-#include
-
#include
#include
#include
-#include
+#include
#include
-static DIR* firstdir = NULL;
-
-extern "C" void dregister(DIR* dir)
-{
- dir->flags |= _DIR_REGISTERED;
- if ( !firstdir ) { firstdir = dir; return; }
- dir->next = firstdir;
- firstdir->prev = dir;
- firstdir = dir;
-}
-
-extern "C" void dunregister(DIR* dir)
-{
- if ( !(dir->flags & _DIR_REGISTERED) )
- return;
- if ( !dir->prev )
- firstdir = dir->next;
- if ( dir->prev )
- dir->prev->next = dir->next;
- if ( dir->next )
- dir->next->prev = dir->prev;
- dir->flags &= ~_DIR_REGISTERED;
-}
-
extern "C" struct dirent* readdir(DIR* dir)
{
if ( !dir->read_func )
{
dir->flags |= _DIR_ERROR;
errno = EBADF;
- return 0;
+ return NULL;
}
size_t size = dir->entrysize;
@@ -70,6 +44,7 @@ extern "C" struct dirent* readdir(DIR* dir)
dir->flags |= _DIR_ERROR;
return NULL;
}
+
if ( 0 < status )
{
struct dirent* biggerdir = (struct dirent*) malloc(size);
@@ -94,66 +69,3 @@ extern "C" struct dirent* readdir(DIR* dir)
return dir->entry;
}
-
-extern "C" int closedir(DIR* dir)
-{
- int result = (dir->close_func) ? dir->close_func(dir->user) : 0;
- dunregister(dir);
- free(dir->entry);
- if ( dir->free_func )
- dir->free_func(dir);
- return result;
-}
-
-extern "C" void rewinddir(DIR* dir)
-{
- if ( dir->rewind_func )
- dir->rewind_func(dir->user);
- dir->flags &= ~_DIR_EOF;
-}
-
-extern "C" int dirfd(DIR* dir)
-{
- if ( !dir->fd_func )
- return errno = EBADF, 0;
- return dir->fd_func(dir->user);
-}
-
-extern "C" void dclearerr(DIR* dir)
-{
- dir->flags &= ~_DIR_ERROR;
-}
-
-extern "C" int derror(DIR* dir)
-{
- return dir->flags & _DIR_ERROR;
-}
-
-extern "C" int deof(DIR* dir)
-{
- return dir->flags & _DIR_EOF;
-}
-
-static void dfreedir(DIR* dir)
-{
- free(dir);
-}
-
-extern "C" DIR* dnewdir(void)
-{
- DIR* dir = (DIR*) calloc(sizeof(DIR), 1);
- if ( !dir )
- return NULL;
- dir->flags = 0;
- dir->free_func = dfreedir;
- dregister(dir);
- return dir;
-}
-
-extern "C" int dcloseall(void)
-{
- int result = 0;
- while ( firstdir )
- result |= closedir(firstdir);
- return result ? EOF : 0;
-}
diff --git a/libc/dirent/rewinddir.cpp b/libc/dirent/rewinddir.cpp
new file mode 100644
index 00000000..e61c6f1c
--- /dev/null
+++ b/libc/dirent/rewinddir.cpp
@@ -0,0 +1,33 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2011, 2014.
+
+ 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 .
+
+ dirent/rewinddir.cpp
+ Rewinds a directory stream to the start.
+
+*******************************************************************************/
+
+#include
+#include
+
+extern "C" void rewinddir(DIR* dir)
+{
+ if ( dir->rewind_func )
+ dir->rewind_func(dir->user);
+ dir->flags &= ~_DIR_EOF;
+}
diff --git a/libc/include/dirent.h b/libc/include/dirent.h
index 1710cab8..87b40747 100644
--- a/libc/include/dirent.h
+++ b/libc/include/dirent.h
@@ -86,6 +86,10 @@ int derror(DIR* dir);
int deof(DIR* dif);
#endif
+#if defined(__is_sortix_libc)
+extern DIR* __firstdir;
+#endif
+
__END_DECLS
#endif