summaryrefslogtreecommitdiff
path: root/libtecla-1.4.1/direader.c
diff options
context:
space:
mode:
authorcvs2git <rtems-devel@rtems.org>2002-11-19 12:59:32 +0000
committercvs2git <rtems-devel@rtems.org>2002-11-19 12:59:32 +0000
commit41248c786ad051eaac50770ab5c02de48f4c04a7 (patch)
tree28179131c73d9d53f3435d841961db84d7b8acbb /libtecla-1.4.1/direader.c
parentcbc2d8125987241306ba82aa853e3f6bb3069405 (diff)
This commit was manufactured by cvs2svn to create tag 'rtems-addon-rtems-addon-packages-20021119
packages-20021119'. Sprout from addons 2002-06-28 21:58:41 UTC Eric Norum <WENorum@lbl.gov> 'Useful add-on libraries' Cherrypick from master 2002-11-19 12:59:31 UTC Joel Sherrill <joel.sherrill@OARcorp.com> '2002-11-19 Joel Sherrill <joel@OARcorp.com>': ChangeLog RTEMS_Makefiles/Makefile.libtecla RTEMS_Makefiles/Makefile.ncurses RTEMS_Makefiles/Makefile.readline-4.3 SUPPORT VERSION bit libtecla-1.4.1/CHANGES libtecla-1.4.1/INSTALL libtecla-1.4.1/LICENSE.TERMS libtecla-1.4.1/Makefile libtecla-1.4.1/Makefile.in libtecla-1.4.1/Makefile.rules libtecla-1.4.1/Makefile.stub libtecla-1.4.1/PORTING libtecla-1.4.1/README libtecla-1.4.1/RELEASE.NOTES libtecla-1.4.1/config.guess libtecla-1.4.1/config.sub libtecla-1.4.1/configure libtecla-1.4.1/configure.in libtecla-1.4.1/cplfile.c libtecla-1.4.1/cplfile.h libtecla-1.4.1/cplmatch.c libtecla-1.4.1/demo.c libtecla-1.4.1/demo2.c libtecla-1.4.1/direader.c libtecla-1.4.1/direader.h libtecla-1.4.1/enhance.c libtecla-1.4.1/expand.c libtecla-1.4.1/freelist.c libtecla-1.4.1/freelist.h libtecla-1.4.1/getline.c libtecla-1.4.1/getline.h libtecla-1.4.1/hash.c libtecla-1.4.1/hash.h libtecla-1.4.1/history.c libtecla-1.4.1/history.h libtecla-1.4.1/homedir.c libtecla-1.4.1/homedir.h libtecla-1.4.1/html/changes.html libtecla-1.4.1/html/cpl_complete_word.html libtecla-1.4.1/html/ef_expand_file.html libtecla-1.4.1/html/enhance.html libtecla-1.4.1/html/gl_get_line.html libtecla-1.4.1/html/index.html libtecla-1.4.1/html/libtecla.html libtecla-1.4.1/html/pca_lookup_file.html libtecla-1.4.1/html/release.html libtecla-1.4.1/install-sh libtecla-1.4.1/keytab.c libtecla-1.4.1/keytab.h libtecla-1.4.1/libtecla.h libtecla-1.4.1/libtecla.map libtecla-1.4.1/man3/cfc_file_start.3 libtecla-1.4.1/man3/cfc_literal_escapes.3 libtecla-1.4.1/man3/cfc_set_check_fn.3 libtecla-1.4.1/man3/cpl_add_completion.3 libtecla-1.4.1/man3/cpl_complete_word.3 libtecla-1.4.1/man3/cpl_file_completions.3 libtecla-1.4.1/man3/cpl_last_error.3 libtecla-1.4.1/man3/cpl_list_completions.3 libtecla-1.4.1/man3/cpl_record_error.3 libtecla-1.4.1/man3/del_CplFileConf.3 libtecla-1.4.1/man3/del_ExpandFile.3 libtecla-1.4.1/man3/del_GetLine.3 libtecla-1.4.1/man3/del_PathCache.3 libtecla-1.4.1/man3/del_PcaPathConf.3 libtecla-1.4.1/man3/del_WordCompletion.3 libtecla-1.4.1/man3/ef_expand_file.3 libtecla-1.4.1/man3/ef_last_error.3 libtecla-1.4.1/man3/ef_list_expansions.3 libtecla-1.4.1/man3/enhance.3 libtecla-1.4.1/man3/gl_change_terminal.3 libtecla-1.4.1/man3/gl_clear_history.3 libtecla-1.4.1/man3/gl_configure_getline.3 libtecla-1.4.1/man3/gl_customize_completion.3 libtecla-1.4.1/man3/gl_echo_mode.3 libtecla-1.4.1/man3/gl_get_line.3 libtecla-1.4.1/man3/gl_group_history.3 libtecla-1.4.1/man3/gl_ignore_signal.3 libtecla-1.4.1/man3/gl_last_signal.3 libtecla-1.4.1/man3/gl_limit_history.3 libtecla-1.4.1/man3/gl_load_history.3 libtecla-1.4.1/man3/gl_lookup_history.3 libtecla-1.4.1/man3/gl_prompt_style.3 libtecla-1.4.1/man3/gl_range_of_history.3 libtecla-1.4.1/man3/gl_resize_history.3 libtecla-1.4.1/man3/gl_save_history.3 libtecla-1.4.1/man3/gl_show_history.3 libtecla-1.4.1/man3/gl_size_of_history.3 libtecla-1.4.1/man3/gl_state_of_history.3 libtecla-1.4.1/man3/gl_terminal_size.3 libtecla-1.4.1/man3/gl_toggle_history.3 libtecla-1.4.1/man3/gl_trap_signal.3 libtecla-1.4.1/man3/gl_watch_fd.3 libtecla-1.4.1/man3/libtecla.3 libtecla-1.4.1/man3/libtecla_version.3 libtecla-1.4.1/man3/new_CplFileConf.3 libtecla-1.4.1/man3/new_ExpandFile.3 libtecla-1.4.1/man3/new_GetLine.3 libtecla-1.4.1/man3/new_PathCache.3 libtecla-1.4.1/man3/new_PcaPathConf.3 libtecla-1.4.1/man3/new_WordCompletion.3 libtecla-1.4.1/man3/pca_last_error.3 libtecla-1.4.1/man3/pca_lookup_file.3 libtecla-1.4.1/man3/pca_path_completions.3 libtecla-1.4.1/man3/pca_scan_path.3 libtecla-1.4.1/man3/pca_set_check_fn.3 libtecla-1.4.1/man3/ppc_file_start.3 libtecla-1.4.1/man3/ppc_literal_escapes.3 libtecla-1.4.1/pathutil.c libtecla-1.4.1/pathutil.h libtecla-1.4.1/pcache.c libtecla-1.4.1/stringrp.c libtecla-1.4.1/stringrp.h libtecla-1.4.1/strngmem.c libtecla-1.4.1/strngmem.h libtecla-1.4.1/update_html libtecla-1.4.1/update_version libtecla-1.4.1/version.c readline-4.3.orig/CHANGELOG readline-4.3.orig/CHANGES readline-4.3.orig/COPYING readline-4.3.orig/INSTALL readline-4.3.orig/MANIFEST readline-4.3.orig/Makefile.in readline-4.3.orig/README readline-4.3.orig/USAGE readline-4.3.orig/aclocal.m4 readline-4.3.orig/ansi_stdlib.h readline-4.3.orig/bind.c readline-4.3.orig/callback.c readline-4.3.orig/chardefs.h readline-4.3.orig/compat.c readline-4.3.orig/complete.c readline-4.3.orig/config.h.in readline-4.3.orig/configure readline-4.3.orig/configure.in readline-4.3.orig/display.c readline-4.3.orig/doc/Makefile.in readline-4.3.orig/doc/hist.texinfo readline-4.3.orig/doc/history.0 readline-4.3.orig/doc/history.3 readline-4.3.orig/doc/history.dvi readline-4.3.orig/doc/history.html readline-4.3.orig/doc/history.info readline-4.3.orig/doc/history.ps readline-4.3.orig/doc/history_3.ps readline-4.3.orig/doc/hstech.texinfo readline-4.3.orig/doc/hsuser.texinfo readline-4.3.orig/doc/manvers.texinfo readline-4.3.orig/doc/readline.0 readline-4.3.orig/doc/readline.3 readline-4.3.orig/doc/readline.dvi readline-4.3.orig/doc/readline.html readline-4.3.orig/doc/readline.info readline-4.3.orig/doc/readline.ps readline-4.3.orig/doc/readline_3.ps readline-4.3.orig/doc/rlman.texinfo readline-4.3.orig/doc/rltech.texinfo readline-4.3.orig/doc/rluser.texinfo readline-4.3.orig/doc/rluserman.dvi readline-4.3.orig/doc/rluserman.html readline-4.3.orig/doc/rluserman.info readline-4.3.orig/doc/rluserman.ps readline-4.3.orig/doc/rluserman.texinfo readline-4.3.orig/doc/texi2dvi readline-4.3.orig/doc/texi2html readline-4.3.orig/doc/texinfo.tex readline-4.3.orig/emacs_keymap.c readline-4.3.orig/examples/Inputrc readline-4.3.orig/examples/Makefile.in readline-4.3.orig/examples/excallback.c readline-4.3.orig/examples/fileman.c readline-4.3.orig/examples/histexamp.c readline-4.3.orig/examples/manexamp.c readline-4.3.orig/examples/readlinebuf.h readline-4.3.orig/examples/rl.c readline-4.3.orig/examples/rlcat.c readline-4.3.orig/examples/rlfe.c readline-4.3.orig/examples/rltest.c readline-4.3.orig/examples/rlversion.c readline-4.3.orig/funmap.c readline-4.3.orig/histexpand.c readline-4.3.orig/histfile.c readline-4.3.orig/histlib.h readline-4.3.orig/history.c readline-4.3.orig/history.h readline-4.3.orig/histsearch.c readline-4.3.orig/input.c readline-4.3.orig/isearch.c readline-4.3.orig/keymaps.c readline-4.3.orig/keymaps.h readline-4.3.orig/kill.c readline-4.3.orig/macro.c readline-4.3.orig/mbutil.c readline-4.3.orig/misc.c readline-4.3.orig/nls.c readline-4.3.orig/parens.c readline-4.3.orig/posixdir.h readline-4.3.orig/posixjmp.h readline-4.3.orig/posixstat.h readline-4.3.orig/readline.c readline-4.3.orig/readline.h readline-4.3.orig/rlconf.h readline-4.3.orig/rldefs.h readline-4.3.orig/rlmbutil.h readline-4.3.orig/rlprivate.h readline-4.3.orig/rlshell.h readline-4.3.orig/rlstdc.h readline-4.3.orig/rltty.c readline-4.3.orig/rltty.h readline-4.3.orig/rltypedefs.h readline-4.3.orig/rlwinsize.h readline-4.3.orig/savestring.c readline-4.3.orig/search.c readline-4.3.orig/shell.c readline-4.3.orig/shlib/Makefile.in readline-4.3.orig/signals.c readline-4.3.orig/support/config.guess readline-4.3.orig/support/config.sub readline-4.3.orig/support/install.sh readline-4.3.orig/support/mkdirs readline-4.3.orig/support/mkdist readline-4.3.orig/support/shlib-install readline-4.3.orig/support/shobj-conf readline-4.3.orig/support/wcwidth.c readline-4.3.orig/tcap.h readline-4.3.orig/terminal.c readline-4.3.orig/text.c readline-4.3.orig/tilde.c readline-4.3.orig/tilde.h readline-4.3.orig/undo.c readline-4.3.orig/util.c readline-4.3.orig/vi_keymap.c readline-4.3.orig/vi_mode.c readline-4.3.orig/xmalloc.c readline-4.3.orig/xmalloc.h readline-4.3/CHANGELOG-ReadLine readline-4.3/CHANGES readline-4.3/COPYING readline-4.3/INSTALL readline-4.3/MANIFEST readline-4.3/Makefile.in readline-4.3/README readline-4.3/USAGE readline-4.3/aclocal.m4 readline-4.3/ansi_stdlib.h readline-4.3/bind.c readline-4.3/callback.c readline-4.3/chardefs.h readline-4.3/compat.c readline-4.3/complete.c readline-4.3/config.h.in readline-4.3/configure readline-4.3/configure.in readline-4.3/display.c readline-4.3/doc/Makefile.in readline-4.3/doc/hist.texinfo readline-4.3/doc/history.3 readline-4.3/doc/hstech.texinfo readline-4.3/doc/hsuser.texinfo readline-4.3/doc/manvers.texinfo readline-4.3/doc/readline.3 readline-4.3/doc/rlman.texinfo readline-4.3/doc/rltech.texinfo readline-4.3/doc/rluser.texinfo readline-4.3/doc/rluserman.texinfo readline-4.3/doc/texi2dvi readline-4.3/doc/texi2html readline-4.3/doc/texinfo.tex readline-4.3/emacs_keymap.c readline-4.3/examples/Inputrc readline-4.3/examples/Makefile.in readline-4.3/examples/excallback.c readline-4.3/examples/fileman.c readline-4.3/examples/histexamp.c readline-4.3/examples/manexamp.c readline-4.3/examples/readlinebuf.h readline-4.3/examples/rl.c readline-4.3/examples/rlcat.c readline-4.3/examples/rlfe.c readline-4.3/examples/rltest.c readline-4.3/examples/rlversion.c readline-4.3/funmap.c readline-4.3/histexpand.c readline-4.3/histfile.c readline-4.3/histlib.h readline-4.3/history.c readline-4.3/history.h readline-4.3/histsearch.c readline-4.3/input.c readline-4.3/isearch.c readline-4.3/keymaps.c readline-4.3/keymaps.h readline-4.3/kill.c readline-4.3/macro.c readline-4.3/mbutil.c readline-4.3/misc.c readline-4.3/nls.c readline-4.3/parens.c readline-4.3/posixdir.h readline-4.3/posixjmp.h readline-4.3/posixstat.h readline-4.3/readline.c readline-4.3/readline.h readline-4.3/rlconf.h readline-4.3/rldefs.h readline-4.3/rlmbutil.h readline-4.3/rlprivate.h readline-4.3/rlshell.h readline-4.3/rlstdc.h readline-4.3/rltty.c readline-4.3/rltty.h readline-4.3/rltypedefs.h readline-4.3/rlwinsize.h readline-4.3/savestring.c readline-4.3/search.c readline-4.3/shell.c readline-4.3/shlib/Makefile.in readline-4.3/signals.c readline-4.3/support/config.guess readline-4.3/support/config.sub readline-4.3/support/install.sh readline-4.3/support/mkdirs readline-4.3/support/mkdist readline-4.3/support/shlib-install readline-4.3/support/shobj-conf readline-4.3/support/wcwidth.c readline-4.3/tcap.h readline-4.3/terminal.c readline-4.3/text.c readline-4.3/tilde.c readline-4.3/tilde.h readline-4.3/undo.c readline-4.3/util.c readline-4.3/vi_keymap.c readline-4.3/vi_mode.c readline-4.3/xmalloc.c readline-4.3/xmalloc.h readline-doc-4.3/MANIFEST.doc readline-doc-4.3/doc/history.0 readline-doc-4.3/doc/history.dvi readline-doc-4.3/doc/history.html readline-doc-4.3/doc/history.info readline-doc-4.3/doc/history.ps readline-doc-4.3/doc/history_3.ps readline-doc-4.3/doc/readline.0 readline-doc-4.3/doc/readline.dvi readline-doc-4.3/doc/readline.html readline-doc-4.3/doc/readline.info readline-doc-4.3/doc/readline.ps readline-doc-4.3/doc/readline_3.ps readline-doc-4.3/doc/rluserman.dvi readline-doc-4.3/doc/rluserman.html readline-doc-4.3/doc/rluserman.info readline-doc-4.3/doc/rluserman.ps Delete: RTEMS_Makefiles/Makefile.readline SendSrc.bash readline-4.2/CHANGELOG readline-4.2/CHANGES readline-4.2/COPYING readline-4.2/INSTALL readline-4.2/MANIFEST readline-4.2/Makefile.in readline-4.2/README readline-4.2/USAGE readline-4.2/aclocal.m4 readline-4.2/ansi_stdlib.h readline-4.2/bind.c readline-4.2/callback.c readline-4.2/chardefs.h readline-4.2/compat.c readline-4.2/complete.c readline-4.2/config.h.in readline-4.2/configure readline-4.2/configure.in readline-4.2/display.c readline-4.2/doc/Makefile.in readline-4.2/doc/hist.texinfo readline-4.2/doc/history.0 readline-4.2/doc/history.3 readline-4.2/doc/history.dvi readline-4.2/doc/history.html readline-4.2/doc/history.info readline-4.2/doc/history.ps readline-4.2/doc/history_3.ps readline-4.2/doc/hstech.texinfo readline-4.2/doc/hsuser.texinfo readline-4.2/doc/manvers.texinfo readline-4.2/doc/readline.0 readline-4.2/doc/readline.3 readline-4.2/doc/readline.dvi readline-4.2/doc/readline.html readline-4.2/doc/readline.info readline-4.2/doc/readline.ps readline-4.2/doc/readline_3.ps readline-4.2/doc/rlman.texinfo readline-4.2/doc/rltech.texinfo readline-4.2/doc/rluser.texinfo readline-4.2/doc/rluserman.html readline-4.2/doc/rluserman.info readline-4.2/doc/rluserman.ps readline-4.2/doc/rluserman.texinfo readline-4.2/doc/texi2dvi readline-4.2/doc/texi2html readline-4.2/doc/texinfo.tex readline-4.2/emacs_keymap.c readline-4.2/examples/Inputrc readline-4.2/examples/Makefile.in readline-4.2/examples/excallback.c readline-4.2/examples/fileman.c readline-4.2/examples/histexamp.c readline-4.2/examples/manexamp.c readline-4.2/examples/rl.c readline-4.2/examples/rlfe.c readline-4.2/examples/rltest.c readline-4.2/examples/rlversion.c readline-4.2/funmap.c readline-4.2/histexpand.c readline-4.2/histfile.c readline-4.2/histlib.h readline-4.2/history.c readline-4.2/history.h readline-4.2/histsearch.c readline-4.2/input.c readline-4.2/isearch.c readline-4.2/keymaps.c readline-4.2/keymaps.h readline-4.2/kill.c readline-4.2/macro.c readline-4.2/nls.c readline-4.2/parens.c readline-4.2/posixdir.h readline-4.2/posixjmp.h readline-4.2/posixstat.h readline-4.2/readline.c readline-4.2/readline.h readline-4.2/rlconf.h readline-4.2/rldefs.h readline-4.2/rlprivate.h readline-4.2/rlshell.h readline-4.2/rlstdc.h readline-4.2/rltty.c readline-4.2/rltty.h readline-4.2/rltypedefs.h readline-4.2/rlwinsize.h readline-4.2/savestring.c readline-4.2/search.c readline-4.2/shell.c readline-4.2/shlib/Makefile.in readline-4.2/signals.c readline-4.2/support/config.guess readline-4.2/support/config.sub readline-4.2/support/install.sh readline-4.2/support/mkdirs readline-4.2/support/mkdist readline-4.2/support/shlib-install readline-4.2/support/shobj-conf readline-4.2/tcap.h readline-4.2/terminal.c readline-4.2/tilde.c readline-4.2/tilde.h readline-4.2/undo.c readline-4.2/util.c readline-4.2/vi_keymap.c readline-4.2/vi_mode.c readline-4.2/xmalloc.c readline-4.2/xmalloc.h readline/CHANGES readline/COPYING readline/ChangeLog readline/MANIFEST readline/MANIFEST.doc readline/Makefile.in readline/Makefile.rtems readline/README readline/acconfig.h readline/aclocal.m4 readline/ansi_stdlib.h readline/bind.c readline/callback.c readline/chardefs.h readline/complete.c readline/config.guess readline/config.h.bot readline/config.h.in readline/config.h.rtems readline/config.sub readline/configure readline/configure.in readline/configure_jnk readline/configure_rtems readline/cross-build/cygwin.cache readline/display.c readline/doc/ChangeLog readline/doc/Makefile.in readline/doc/hist.texinfo readline/doc/hstech.texinfo readline/doc/hsuser.texinfo readline/doc/inc-hist.texi readline/doc/readline.3 readline/doc/rlman.texinfo readline/doc/rltech.texinfo readline/doc/rluser.texinfo readline/doc/texi2dvi readline/doc/texi2html readline/emacs_keymap.c readline/examples/Inputrc readline/examples/Makefile.in readline/examples/fileman.c readline/examples/histexamp.c readline/examples/manexamp.c readline/examples/rl.c readline/examples/rltest.c readline/funmap.c readline/histexpand.c readline/histfile.c readline/histlib.h readline/history.c readline/history.h readline/histsearch.c readline/input.c readline/install readline/install-sh readline/install.sh readline/isearch.c readline/keymaps.c readline/keymaps.h readline/kill.c readline/macro.c readline/mkdirs readline/mkdist readline/nls.c readline/parens.c readline/posixdir.h readline/posixjmp.h readline/posixstat.h readline/readline.c readline/readline.h readline/rlconf.h readline/rldefs.h readline/rltty.c readline/rltty.h readline/rlwinsize.h readline/search.c readline/shell.c readline/signals.c readline/support/config.guess readline/support/config.sub readline/support/install.sh readline/support/mkdirs readline/support/mkdist readline/tcap.h readline/terminal.c readline/tilde.c readline/tilde.h readline/undo.c readline/util.c readline/vi_keymap.c readline/vi_mode.c readline/xmalloc.c
Diffstat (limited to 'libtecla-1.4.1/direader.c')
-rw-r--r--libtecla-1.4.1/direader.c299
1 files changed, 299 insertions, 0 deletions
diff --git a/libtecla-1.4.1/direader.c b/libtecla-1.4.1/direader.c
new file mode 100644
index 0000000..8a81fbf
--- /dev/null
+++ b/libtecla-1.4.1/direader.c
@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 2000, 2001 by Martin C. Shepherd.
+ *
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, and/or sell copies of the Software, and to permit persons
+ * to whom the Software is furnished to do so, provided that the above
+ * copyright notice(s) and this permission notice appear in all copies of
+ * the Software and that both the above copyright notice(s) and this
+ * permission notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+ * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
+ * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * of the copyright holder.
+ */
+
+/*
+ * Standard includes.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+/*
+ * Operating system includes.
+ */
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+
+#include "direader.h"
+
+/*
+ * Use the reentrant POSIX threads version of readdir()?
+ */
+#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199506L
+#define USE_READDIR_R 1
+#endif
+
+/*
+ * Set the max length of the error-reporting string. There is no point
+ * in this being longer than the width of a typical terminal window.
+ * In composing error messages, I have assumed that this number is
+ * at least 80, so you don't decrease it below this number.
+ */
+#define ERRLEN 200
+
+/*
+ * Objects of the following type are used to maintain the resources
+ * needed to read directories.
+ */
+struct DirReader {
+ DIR *dir; /* The directory stream (if open, NULL otherwise) */
+ struct dirent *file; /* The latest directory entry */
+ char errmsg[ERRLEN+1]; /* Error-report buffer */
+#ifdef USE_READDIR_R
+ struct dirent *buffer; /* A buffer used by the threaded version of readdir */
+ int buffer_dim; /* The allocated size of buffer[] */
+#endif
+};
+
+static int _dr_path_is_dir(const char *pathname);
+
+/*.......................................................................
+ * Create a new DirReader object.
+ *
+ * Output:
+ * return DirReader * The new object, or NULL on error.
+ */
+DirReader *_new_DirReader(void)
+{
+ DirReader *dr; /* The object to be returned */
+/*
+ * Allocate the container.
+ */
+ dr = (DirReader *) malloc(sizeof(DirReader));
+ if(!dr) {
+ fprintf(stderr, "_new_DirReader: Insufficient memory.\n");
+ return NULL;
+ };
+/*
+ * Before attempting any operation that might fail, initialize the
+ * container at least up to the point at which it can safely be passed
+ * to _del_DirReader().
+ */
+ dr->dir = NULL;
+ dr->file = NULL;
+ dr->errmsg[0] = '\0';
+#ifdef USE_READDIR_R
+ dr->buffer = NULL;
+ dr->buffer_dim = 0;
+#endif
+ return dr;
+}
+
+/*.......................................................................
+ * Delete a DirReader object.
+ *
+ * Input:
+ * dr DirReader * The object to be deleted.
+ * Output:
+ * return DirReader * The deleted object (always NULL).
+ */
+DirReader *_del_DirReader(DirReader *dr)
+{
+ if(dr) {
+ _dr_close_dir(dr);
+#ifdef USE_READDIR_R
+ free(dr->buffer);
+#endif
+ free(dr);
+ };
+ return NULL;
+}
+
+/*.......................................................................
+ * Open a new directory.
+ *
+ * Input:
+ * dr DirReader * The directory reader resource object.
+ * path const char * The directory to be opened.
+ * Input/Output:
+ * errmsg char ** If an error occurs and errmsg isn't NULL, a
+ * pointer to an error description will be assigned
+ * to *errmsg.
+ * Output:
+ * return int 0 - OK.
+ * 1 - Error (see *errmsg for a description).
+ */
+int _dr_open_dir(DirReader *dr, const char *path, char **errmsg)
+{
+ DIR *dir = NULL; /* The directory stream */
+/*
+ * If a directory is already open, close it first.
+ */
+ (void) _dr_close_dir(dr);
+/*
+ * Is the path a directory?
+ */
+ if(!_dr_path_is_dir(path)) {
+ if(errmsg) {
+ const char *fmt = "Can't open directory: %.*s\n";
+ sprintf(dr->errmsg, fmt, ERRLEN - strlen(fmt), path);
+ *errmsg = dr->errmsg;
+ };
+ return 1;
+ };
+/*
+ * Attempt to open the directory.
+ */
+ dir = opendir(path);
+ if(!dir) {
+ if(errmsg) {
+ const char *fmt = "Can't open directory: %.*s\n";
+ sprintf(dr->errmsg, fmt, ERRLEN - strlen(fmt), path);
+ *errmsg = dr->errmsg;
+ };
+ return 1;
+ };
+/*
+ * If using POSIX threads, allocate a buffer for readdir_r().
+ */
+#ifdef USE_READDIR_R
+ {
+ size_t size;
+ int name_max = pathconf(path, _PC_NAME_MAX);
+#ifdef NAME_MAX
+ if(name_max < 0)
+ name_max = NAME_MAX;
+#endif
+ if(name_max < 0) {
+ if(errmsg) {
+ strcpy(dr->errmsg, "Unable to deduce readdir() buffer size.");
+ *errmsg = dr->errmsg;
+ };
+ closedir(dir);
+ return 1;
+ };
+/*
+ * How big a buffer do we need to allocate?
+ */
+ size = sizeof(struct dirent) + name_max;
+/*
+ * Extend the buffer?
+ */
+ if(size > dr->buffer_dim || !dr->buffer) {
+ struct dirent *buffer = (struct dirent *) (dr->buffer ?
+ realloc(dr->buffer, size) :
+ malloc(size));
+ if(!buffer) {
+ if(errmsg) {
+ strcpy(dr->errmsg, "Insufficient memory for readdir() buffer.");
+ *errmsg = dr->errmsg;
+ };
+ closedir(dir);
+ return 1;
+ };
+ dr->buffer = buffer;
+ dr->buffer_dim = size;
+ };
+ };
+#endif
+/*
+ * Record the successfully opened directory.
+ */
+ dr->dir = dir;
+ return 0;
+}
+
+/*.......................................................................
+ * If the DirReader object is currently contains an open directory,
+ * close it.
+ *
+ * Input:
+ * dr DirReader * The directory reader resource object.
+ */
+void _dr_close_dir(DirReader *dr)
+{
+ if(dr && dr->dir) {
+ closedir(dr->dir);
+ dr->dir = NULL;
+ dr->file = NULL;
+ dr->errmsg[0] = '\0';
+ };
+}
+
+/*.......................................................................
+ * Read the next file from the directory opened with _dr_open_dir().
+ *
+ * Input:
+ * dr DirReader * The directory reader resource object.
+ * Output:
+ * return char * The name of the new file, or NULL if we reached
+ * the end of the directory.
+ */
+char *_dr_next_file(DirReader *dr)
+{
+/*
+ * Are we currently reading a directory?
+ */
+ if(dr->dir) {
+/*
+ * Read the next directory entry.
+ */
+#ifdef USE_READDIR_R
+ if(readdir_r(dr->dir, dr->buffer, &dr->file) == 0 && dr->file)
+ return dr->file->d_name;
+#else
+ dr->file = readdir(dr->dir);
+ if(dr->file)
+ return dr->file->d_name;
+#endif
+ };
+/*
+ * When the end of a directory is reached, close it.
+ */
+ _dr_close_dir(dr);
+ return NULL;
+}
+
+/*.......................................................................
+ * Return 1 if the specified pathname refers to a directory.
+ *
+ * Input:
+ * pathname const char * The path to test.
+ * Output:
+ * return int 0 - Not a directory.
+ * 1 - pathname[] refers to a directory.
+ */
+static int _dr_path_is_dir(const char *pathname)
+{
+ struct stat statbuf; /* The file-statistics return buffer */
+/*
+ * Look up the file attributes.
+ */
+ if(stat(pathname, &statbuf) < 0)
+ return 0;
+/*
+ * Is the file a directory?
+ */
+ return S_ISDIR(statbuf.st_mode) != 0;
+}