From 8a0efa53e44919bcf5ccb1d3353618a82afdf8bc Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Thu, 17 Feb 2000 19:39:52 +0000 Subject: import newlib-2000-02-17 snapshot --- newlib/libc/posix/Makefile.am | 29 ++++ newlib/libc/posix/Makefile.in | 303 ++++++++++++++++++++++++++++++++++++++++++ newlib/libc/posix/closedir.c | 62 +++++++++ newlib/libc/posix/creat.c | 11 ++ newlib/libc/posix/execl.c | 42 ++++++ newlib/libc/posix/execle.c | 44 ++++++ newlib/libc/posix/execlp.c | 42 ++++++ newlib/libc/posix/execv.c | 15 +++ newlib/libc/posix/execve.c | 10 ++ newlib/libc/posix/execvp.c | 88 ++++++++++++ newlib/libc/posix/isatty.c | 17 +++ newlib/libc/posix/opendir.c | 84 ++++++++++++ newlib/libc/posix/popen.c | 170 ++++++++++++++++++++++++ newlib/libc/posix/readdir.c | 76 +++++++++++ newlib/libc/posix/rewinddir.c | 50 +++++++ newlib/libc/posix/scandir.c | 142 ++++++++++++++++++++ newlib/libc/posix/seekdir.c | 56 ++++++++ newlib/libc/posix/telldir.c | 133 ++++++++++++++++++ 18 files changed, 1374 insertions(+) create mode 100644 newlib/libc/posix/Makefile.am create mode 100644 newlib/libc/posix/Makefile.in create mode 100644 newlib/libc/posix/closedir.c create mode 100644 newlib/libc/posix/creat.c create mode 100644 newlib/libc/posix/execl.c create mode 100644 newlib/libc/posix/execle.c create mode 100644 newlib/libc/posix/execlp.c create mode 100644 newlib/libc/posix/execv.c create mode 100644 newlib/libc/posix/execve.c create mode 100644 newlib/libc/posix/execvp.c create mode 100644 newlib/libc/posix/isatty.c create mode 100644 newlib/libc/posix/opendir.c create mode 100644 newlib/libc/posix/popen.c create mode 100644 newlib/libc/posix/readdir.c create mode 100644 newlib/libc/posix/rewinddir.c create mode 100644 newlib/libc/posix/scandir.c create mode 100644 newlib/libc/posix/seekdir.c create mode 100644 newlib/libc/posix/telldir.c (limited to 'newlib/libc/posix') diff --git a/newlib/libc/posix/Makefile.am b/newlib/libc/posix/Makefile.am new file mode 100644 index 000000000..afb909762 --- /dev/null +++ b/newlib/libc/posix/Makefile.am @@ -0,0 +1,29 @@ +## Process this file with automake to generate Makefile.in + +AUTOMAKE_OPTIONS = cygnus + +INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) + +noinst_LIBRARIES = lib.a + +lib_a_SOURCES = \ + closedir.c opendir.c readdir.c rewinddir.c scandir.c seekdir.c \ + telldir.c execl.c execle.c execlp.c execv.c execve.c execvp.c \ + popen.c creat.c isatty.c + +CHEWOUT_FILES = + +SUFFIXES = .def + +CHEW = ../../doc/makedoc -f $(srcdir)/../../doc/doc.str + +.c.def: + $(CHEW) < $< > $*.def 2> $*.ref + touch stmp-def + +TARGETDOC = ../tmp.texi + +# No doc for posix. +doc: + +CLEANFILES = $(CHEWOUT_FILES) *.ref diff --git a/newlib/libc/posix/Makefile.in b/newlib/libc/posix/Makefile.in new file mode 100644 index 000000000..6b41087c7 --- /dev/null +++ b/newlib/libc/posix/Makefile.in @@ -0,0 +1,303 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AR = @AR@ +AS = @AS@ +CC = @CC@ +CPP = @CPP@ +CRT0 = @CRT0@ +EXEEXT = @EXEEXT@ +LIBC_MACHINE_LIB = @LIBC_MACHINE_LIB@ +LIBC_POSIX_LIB = @LIBC_POSIX_LIB@ +LIBC_SIGNAL_DEF = @LIBC_SIGNAL_DEF@ +LIBC_SIGNAL_LIB = @LIBC_SIGNAL_LIB@ +LIBC_SYSCALL_LIB = @LIBC_SYSCALL_LIB@ +LIBC_SYS_LIB = @LIBC_SYS_LIB@ +LIBC_UNIX_LIB = @LIBC_UNIX_LIB@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +NEWLIB_CFLAGS = @NEWLIB_CFLAGS@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +VERSION = @VERSION@ +machine_dir = @machine_dir@ +newlib_basedir = @newlib_basedir@ +sys_dir = @sys_dir@ + +AUTOMAKE_OPTIONS = cygnus + +INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) + +noinst_LIBRARIES = lib.a + +lib_a_SOURCES = \ + closedir.c opendir.c readdir.c rewinddir.c scandir.c seekdir.c \ + telldir.c execl.c execle.c execlp.c execv.c execve.c execvp.c \ + popen.c creat.c isatty.c + + +CHEWOUT_FILES = + +SUFFIXES = .def + +CHEW = ../../doc/makedoc -f $(srcdir)/../../doc/doc.str + +TARGETDOC = ../tmp.texi + +CLEANFILES = $(CHEWOUT_FILES) *.ref +mkinstalldirs = $(SHELL) $(top_srcdir)/../../mkinstalldirs +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) + + +DEFS = @DEFS@ -I. -I$(srcdir) +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +lib_a_LIBADD = +lib_a_OBJECTS = closedir.o opendir.o readdir.o rewinddir.o scandir.o \ +seekdir.o telldir.o execl.o execle.o execlp.o execv.o execve.o execvp.o \ +popen.o creat.o isatty.o +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +SOURCES = $(lib_a_SOURCES) +OBJECTS = $(lib_a_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .def .o .s +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --cygnus posix/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-noinstLIBRARIES: + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +distclean-noinstLIBRARIES: + +maintainer-clean-noinstLIBRARIES: + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +lib.a: $(lib_a_OBJECTS) $(lib_a_DEPENDENCIES) + -rm -f lib.a + $(AR) cru lib.a $(lib_a_OBJECTS) $(lib_a_LIBADD) + $(RANLIB) lib.a + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = posix + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + cp -pr $$/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: +check: check-am +installcheck-am: +installcheck: installcheck-am +install-info-am: +install-info: install-info-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: +uninstall: uninstall-am +all-am: Makefile $(LIBRARIES) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + + +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \ + mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-noinstLIBRARIES clean-compile clean-tags clean-generic \ + mostlyclean-am + +clean: clean-am + +distclean-am: distclean-noinstLIBRARIES distclean-compile \ + distclean-tags distclean-generic clean-am + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-noinstLIBRARIES \ + maintainer-clean-compile maintainer-clean-tags \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \ +clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile tags mostlyclean-tags distclean-tags \ +clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \ +check-am installcheck-am installcheck install-info-am install-info \ +install-exec-am install-exec install-data-am install-data install-am \ +install uninstall-am uninstall all-redirect all-am all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +.c.def: + $(CHEW) < $< > $*.def 2> $*.ref + touch stmp-def + +# No doc for posix. +doc: + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/newlib/libc/posix/closedir.c b/newlib/libc/posix/closedir.c new file mode 100644 index 000000000..4ad6e4c97 --- /dev/null +++ b/newlib/libc/posix/closedir.c @@ -0,0 +1,62 @@ +#ifndef HAVE_OPENDIR + +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)closedir.c 5.9 (Berkeley) 2/23/91"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include + +/* + * close a directory. + */ +int +closedir(dirp) + register DIR *dirp; +{ + int fd; + + fd = dirp->dd_fd; + dirp->dd_fd = -1; + dirp->dd_loc = 0; + (void)free((void *)dirp->dd_buf); + (void)free((void *)dirp); + return(close(fd)); +} + +#endif /* ! HAVE_OPENDIR */ diff --git a/newlib/libc/posix/creat.c b/newlib/libc/posix/creat.c new file mode 100644 index 000000000..6b1116206 --- /dev/null +++ b/newlib/libc/posix/creat.c @@ -0,0 +1,11 @@ +/* creat() "system call" */ + +/* This is needed by f2c and therefore the SPEC benchmarks. */ + +#include + +int +creat (const char *path, mode_t mode) +{ + return open (path, O_WRONLY | O_CREAT | O_TRUNC, mode); +} diff --git a/newlib/libc/posix/execl.c b/newlib/libc/posix/execl.c new file mode 100644 index 000000000..075df8eba --- /dev/null +++ b/newlib/libc/posix/execl.c @@ -0,0 +1,42 @@ +/* execl.c */ + +/* This and the other exec*.c files in this directory require + the target to provide the _execve syscall. */ + +#include <_ansi.h> +#include + +#ifdef _HAVE_STDC + +#include + +int +execl (_CONST char *path, _CONST char *arg0, ...) + +#else + +#include + +int +execl (path, arg0, va_alist) + _CONST char *path; + _CONST char *arg0; + va_dcl + +#endif + +{ + int i; + va_list args; + _CONST char *argv[256]; + + va_start (args, arg0); + argv[0] = arg0; + i = 1; + do + argv[i] = va_arg (args, _CONST char *); + while (argv[i++] != NULL); + va_end (args); + + return _execve (path, (char * _CONST *) argv, environ); +} diff --git a/newlib/libc/posix/execle.c b/newlib/libc/posix/execle.c new file mode 100644 index 000000000..439437023 --- /dev/null +++ b/newlib/libc/posix/execle.c @@ -0,0 +1,44 @@ +/* execle.c */ + +/* This and the other exec*.c files in this directory require + the target to provide the _execve syscall. */ + +#include <_ansi.h> +#include + +#ifdef _HAVE_STDC + +#include + +int +execle (_CONST char *path, _CONST char *arg0, ...) + +#else + +#include + +int +execle (path, arg0, va_alist) + _CONST char *path; + _CONST char *arg0; + va_dcl + +#endif + +{ + int i; + va_list args; + _CONST char * _CONST *envp; + _CONST char *argv[256]; + + va_start (args, arg0); + argv[0] = arg0; + i = 1; + do + argv[i] = va_arg (args, _CONST char *); + while (argv[i++] != NULL); + envp = va_arg (args, _CONST char * _CONST *); + va_end (args); + + return _execve (path, (char * _CONST *) argv, (char * _CONST *) envp); +} diff --git a/newlib/libc/posix/execlp.c b/newlib/libc/posix/execlp.c new file mode 100644 index 000000000..dd04914bc --- /dev/null +++ b/newlib/libc/posix/execlp.c @@ -0,0 +1,42 @@ +/* execlp.c */ + +/* This and the other exec*.c files in this directory require + the target to provide the _execve syscall. */ + +#include <_ansi.h> +#include + +#ifdef _HAVE_STDC + +#include + +int +execlp (_CONST char *path, _CONST char *arg0, ...) + +#else + +#include + +int +execlp (path, arg0, va_alist) + _CONST char *path; + _CONST char *arg0; + va_dcl + +#endif + +{ + int i; + va_list args; + _CONST char *argv[256]; + + va_start (args, arg0); + argv[0] = arg0; + i = 1; + do + argv[i] = va_arg (args, _CONST char *); + while (argv[i++] != NULL); + va_end (args); + + return execvp (path, (char * _CONST *) argv); +} diff --git a/newlib/libc/posix/execv.c b/newlib/libc/posix/execv.c new file mode 100644 index 000000000..42a78cb52 --- /dev/null +++ b/newlib/libc/posix/execv.c @@ -0,0 +1,15 @@ +/* execv.c */ + +/* This and the other exec*.c files in this directory require + the target to provide the _execve syscall. */ + +#include <_ansi.h> +#include + +int +_DEFUN (execv, (path, argv), + const char *path _AND + char * const argv[]) +{ + return _execve (path, (char * _CONST *) argv, environ); +} diff --git a/newlib/libc/posix/execve.c b/newlib/libc/posix/execve.c new file mode 100644 index 000000000..416144e86 --- /dev/null +++ b/newlib/libc/posix/execve.c @@ -0,0 +1,10 @@ +/* execve.c */ + +/* This and the other exec*.c files in this directory require + the target to provide the _execve syscall. */ + +int +execve (const char *path, char * const argv[], char * const envp[]) +{ + return _execve (path, argv, envp); +} diff --git a/newlib/libc/posix/execvp.c b/newlib/libc/posix/execvp.c new file mode 100644 index 000000000..6957f61b2 --- /dev/null +++ b/newlib/libc/posix/execvp.c @@ -0,0 +1,88 @@ +/* execvp.c */ + +/* This and the other exec*.c files in this directory require + the target to provide the _execve syscall. */ + +#include <_ansi.h> +#include +#include +#include +#include + +#ifdef __CYGWIN32__ +static char path_delim; +#define PATH_DELIM path_delim +#else +#define PATH_DELIM ':' +#endif + +/* + * Copy string, until c or is encountered. + * NUL-terminate the destination string (s1). + */ + +static char * +_DEFUN (strccpy, (s1, s2, c), + char *s1 _AND + char *s2 _AND + char c) +{ + char *dest = s1; + + while (*s2 && *s2 != c) + *s1++ = *s2++; + *s1 = 0; + + return dest; +} + +int +_DEFUN (execvp, (file, argv), + _CONST char *file _AND + char * _CONST argv[]) +{ + char *path = getenv ("PATH"); + char buf[MAXNAMLEN]; + + /* If $PATH doesn't exist, just pass FILE on unchanged. */ + if (!path) + return execv (file, argv); + + /* If FILE contains a directory, don't search $PATH. */ + if (strchr (file, '/') +#ifdef __CYGWIN32__ + || strchr (file, '\\') +#endif + ) + return execv (file, argv); + +#ifdef __CYGWIN32__ + /* If a drive letter is passed, the path is still an absolute one. + Technically this isn't true, but Cygwin is currently defined so + that it is. */ + if ((isalpha (file[0]) && file[1] == ':') + || file[0] == '\\') + return execv (file, argv); +#endif + +#ifdef __CYGWIN32__ + path_delim = cygwin_posix_path_list_p (path) ? ':' : ';'; +#endif + + while (*path) + { + strccpy (buf, path, PATH_DELIM); + /* An empty entry means the current directory. */ + if (*buf != 0) + strcat (buf, "/"); + strcat (buf, file); + if (execv (buf, argv) == -1 && errno != ENOENT) + return -1; + while (*path && *path != PATH_DELIM) + path++; + if (*path == PATH_DELIM) + path++; /* skip over delim */ + } + + return -1; +} diff --git a/newlib/libc/posix/isatty.c b/newlib/libc/posix/isatty.c new file mode 100644 index 000000000..3c64647a9 --- /dev/null +++ b/newlib/libc/posix/isatty.c @@ -0,0 +1,17 @@ +/* isatty.c */ + +/* Dumb implementation so programs will at least run. */ + +#include + +int +isatty (int fd) +{ + struct stat buf; + + if (fstat (fd, &buf) < 0) + return 0; + if (S_ISCHR (buf.st_mode)) + return 1; + return 0; +} diff --git a/newlib/libc/posix/opendir.c b/newlib/libc/posix/opendir.c new file mode 100644 index 000000000..f924c0b52 --- /dev/null +++ b/newlib/libc/posix/opendir.c @@ -0,0 +1,84 @@ +#ifndef HAVE_OPENDIR + +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)opendir.c 5.11 (Berkeley) 2/23/91"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include + +/* + * open a directory. + */ +DIR * +opendir(name) + const char *name; +{ + register DIR *dirp; + register int fd; + + if ((fd = open(name, 0)) == -1) + return NULL; + if (fcntl(fd, F_SETFD, 1) == -1 || + (dirp = (DIR *)malloc(sizeof(DIR))) == NULL) { + close (fd); + return NULL; + } + /* + * If CLSIZE is an exact multiple of DIRBLKSIZ, use a CLSIZE + * buffer that it cluster boundary aligned. + * Hopefully this can be a big win someday by allowing page trades + * to user space to be done by getdirentries() + */ + dirp->dd_buf = malloc (512); + dirp->dd_len = 512; + + if (dirp->dd_buf == NULL) { + close (fd); + return NULL; + } + dirp->dd_fd = fd; + dirp->dd_loc = 0; + dirp->dd_seek = 0; + /* + * Set up seek point for rewinddir. + */ + return dirp; +} + +#endif /* ! HAVE_OPENDIR */ diff --git a/newlib/libc/posix/popen.c b/newlib/libc/posix/popen.c new file mode 100644 index 000000000..f6a7421ee --- /dev/null +++ b/newlib/libc/posix/popen.c @@ -0,0 +1,170 @@ +/* $NetBSD: popen.c,v 1.11 1995/06/16 07:05:33 jtc Exp $ */ + +/* + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software written by Ken Arnold and + * published in UNIX Review, Vol. 6, No. 8. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)popen.c 8.1 (Berkeley) 6/4/93"; +#else +static char rcsid[] = "$NetBSD: popen.c,v 1.11 1995/06/16 07:05:33 jtc Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +static struct pid { + struct pid *next; + FILE *fp; + pid_t pid; +} *pidlist; + +FILE * +popen(program, type) + const char *program; + const char *type; +{ + struct pid *cur; + FILE *iop; + int pdes[2], pid; + + if (*type != 'r' && *type != 'w' || type[1]) { + errno = EINVAL; + return (NULL); + } + + if ((cur = malloc(sizeof(struct pid))) == NULL) + return (NULL); + + if (pipe(pdes) < 0) { + free(cur); + return (NULL); + } + + switch (pid = vfork()) { + case -1: /* Error. */ + (void)close(pdes[0]); + (void)close(pdes[1]); + free(cur); + return (NULL); + /* NOTREACHED */ + case 0: /* Child. */ + if (*type == 'r') { + if (pdes[1] != STDOUT_FILENO) { + (void)dup2(pdes[1], STDOUT_FILENO); + (void)close(pdes[1]); + } + (void) close(pdes[0]); + } else { + if (pdes[0] != STDIN_FILENO) { + (void)dup2(pdes[0], STDIN_FILENO); + (void)close(pdes[0]); + } + (void)close(pdes[1]); + } + execl(_PATH_BSHELL, "sh", "-c", program, NULL); +#ifdef __CYGWIN32__ + /* On cygwin32, we may not have /bin/sh. In that + case, try to find sh on PATH. */ + execlp("sh", "sh", "-c", program, NULL); +#endif + _exit(127); + /* NOTREACHED */ + } + + /* Parent; assume fdopen can't fail. */ + if (*type == 'r') { + iop = fdopen(pdes[0], type); + (void)close(pdes[1]); + } else { + iop = fdopen(pdes[1], type); + (void)close(pdes[0]); + } + + /* Link into list of file descriptors. */ + cur->fp = iop; + cur->pid = pid; + cur->next = pidlist; + pidlist = cur; + + return (iop); +} + +/* + * pclose -- + * Pclose returns -1 if stream is not associated with a `popened' command, + * if already `pclosed', or waitpid returns an error. + */ +int +pclose(iop) + FILE *iop; +{ + register struct pid *cur, *last; + int pstat; + pid_t pid; + + (void)fclose(iop); + + /* Find the appropriate file pointer. */ + for (last = NULL, cur = pidlist; cur; last = cur, cur = cur->next) + if (cur->fp == iop) + break; + if (cur == NULL) + return (-1); + + do { + pid = waitpid(cur->pid, &pstat, 0); + } while (pid == -1 && errno == EINTR); + + /* Remove the entry from the linked list. */ + if (last == NULL) + pidlist = cur->next; + else + last->next = cur->next; + free(cur); + + return (pid == -1 ? -1 : pstat); +} diff --git a/newlib/libc/posix/readdir.c b/newlib/libc/posix/readdir.c new file mode 100644 index 000000000..308330cb0 --- /dev/null +++ b/newlib/libc/posix/readdir.c @@ -0,0 +1,76 @@ +#ifndef HAVE_OPENDIR + +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)readdir.c 5.7 (Berkeley) 6/1/90"; +#endif /* LIBC_SCCS and not lint */ + +#include + +/* + * get next entry in a directory. + */ +struct dirent * +readdir(dirp) +register DIR *dirp; { + register struct dirent *dp; + + for (;;) { + if (dirp->dd_loc == 0) { + dirp->dd_size = getdents (dirp->dd_fd, + dirp->dd_buf, + dirp->dd_len); + + if (dirp->dd_size <= 0) + return NULL; + } + if (dirp->dd_loc >= dirp->dd_size) { + dirp->dd_loc = 0; + continue; + } + dp = (struct dirent *)(dirp->dd_buf + dirp->dd_loc); + if ((int)dp & 03) /* bogus pointer check */ + return NULL; + if (dp->d_reclen <= 0 || + dp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc) + return NULL; + dirp->dd_loc += dp->d_reclen; + if (dp->d_ino == 0) + continue; + return (dp); + } +} + +#endif /* ! HAVE_OPENDIR */ diff --git a/newlib/libc/posix/rewinddir.c b/newlib/libc/posix/rewinddir.c new file mode 100644 index 000000000..6a3814b55 --- /dev/null +++ b/newlib/libc/posix/rewinddir.c @@ -0,0 +1,50 @@ +#ifndef HAVE_OPENDIR + +/* + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)rewinddir.c 5.1 (Berkeley) 5/25/90"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +void +rewinddir(dirp) + DIR *dirp; +{ + _seekdir((dirp), (off_t)0); +} + +#endif /* ! HAVE_OPENDIR */ diff --git a/newlib/libc/posix/scandir.c b/newlib/libc/posix/scandir.c new file mode 100644 index 000000000..895879bac --- /dev/null +++ b/newlib/libc/posix/scandir.c @@ -0,0 +1,142 @@ +#ifndef HAVE_OPENDIR + +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)scandir.c 5.10 (Berkeley) 2/23/91"; +#endif /* LIBC_SCCS and not lint */ + +/* + * Scan the directory dirname calling select to make a list of selected + * directory entries then sort using qsort and compare routine dcomp. + * Returns the number of entries and a pointer to a list of pointers to + * struct dirent (through namelist). Returns -1 if there were any errors. + */ + +#include +#include +#include +#include +#include + +/* + * The DIRSIZ macro gives the minimum record length which will hold + * the directory entry. This requires the amount of space in struct dirent + * without the d_name field, plus enough space for the name with a terminating + * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary. + */ +#undef DIRSIZ +#define DIRSIZ(dp) \ + ((sizeof (struct dirent) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3)) + +#ifndef __P +#define __P(args) () +#endif + +int +scandir(dirname, namelist, select, dcomp) + const char *dirname; + struct dirent ***namelist; + int (*select) __P((struct dirent *)); + int (*dcomp) __P((const void *, const void *)); +{ + register struct dirent *d, *p, **names; + register size_t nitems; + struct stat stb; + long arraysz; + DIR *dirp; + + if ((dirp = opendir(dirname)) == NULL) + return(-1); + if (fstat(dirp->dd_fd, &stb) < 0) + return(-1); + + /* + * estimate the array size by taking the size of the directory file + * and dividing it by a multiple of the minimum size entry. + */ + arraysz = (stb.st_size / 24); + names = (struct dirent **)malloc(arraysz * sizeof(struct dirent *)); + if (names == NULL) + return(-1); + + nitems = 0; + while ((d = readdir(dirp)) != NULL) { + if (select != NULL && !(*select)(d)) + continue; /* just selected names */ + /* + * Make a minimum size copy of the data + */ + p = (struct dirent *)malloc(DIRSIZ(d)); + if (p == NULL) + return(-1); + p->d_ino = d->d_ino; + p->d_reclen = d->d_reclen; + p->d_namlen = d->d_namlen; + bcopy(d->d_name, p->d_name, p->d_namlen + 1); + /* + * Check to make sure the array has space left and + * realloc the maximum size. + */ + if (++nitems >= arraysz) { + if (fstat(dirp->dd_fd, &stb) < 0) + return(-1); /* just might have grown */ + arraysz = stb.st_size / 12; + names = (struct dirent **)realloc((char *)names, + arraysz * sizeof(struct dirent *)); + if (names == NULL) + return(-1); + } + names[nitems-1] = p; + } + closedir(dirp); + if (nitems && dcomp != NULL) + qsort(names, nitems, sizeof(struct dirent *), dcomp); + *namelist = names; + return(nitems); +} + +/* + * Alphabetic order comparison routine for those who want it. + */ +int +alphasort(d1, d2) + const void *d1; + const void *d2; +{ + return(strcmp((*(struct dirent **)d1)->d_name, + (*(struct dirent **)d2)->d_name)); +} + +#endif /* ! HAVE_OPENDIR */ diff --git a/newlib/libc/posix/seekdir.c b/newlib/libc/posix/seekdir.c new file mode 100644 index 000000000..dab3bfb24 --- /dev/null +++ b/newlib/libc/posix/seekdir.c @@ -0,0 +1,56 @@ +#ifndef HAVE_OPENDIR + +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)seekdir.c 5.7 (Berkeley) 6/1/90"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +/* + * Seek to an entry in a directory. + * _seekdir is in telldir.c so that it can share opaque data structures. + */ +void +seekdir(dirp, loc) + DIR *dirp; + long loc; +{ + + _seekdir(dirp, loc); +} + +#endif /* ! HAVE_OPENDIR */ diff --git a/newlib/libc/posix/telldir.c b/newlib/libc/posix/telldir.c new file mode 100644 index 000000000..90b12f99c --- /dev/null +++ b/newlib/libc/posix/telldir.c @@ -0,0 +1,133 @@ +#ifndef HAVE_OPENDIR + +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)telldir.c 5.9 (Berkeley) 2/23/91"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include + +/* + * The option SINGLEUSE may be defined to say that a telldir + * cookie may be used only once before it is freed. This option + * is used to avoid having memory usage grow without bound. + */ +#define SINGLEUSE + +/* + * One of these structures is malloced to describe the current directory + * position each time telldir is called. It records the current magic + * cookie returned by getdirentries and the offset within the buffer + * associated with that return value. + */ +struct ddloc { + struct ddloc *loc_next;/* next structure in list */ + long loc_index; /* key associated with structure */ + long loc_seek; /* magic cookie returned by getdirentries */ + long loc_loc; /* offset of entry in buffer */ +}; + +#define NDIRHASH 32 /* Num of hash lists, must be a power of 2 */ +#define LOCHASH(i) ((i)&(NDIRHASH-1)) + +static long dd_loccnt; /* Index of entry for sequential readdir's */ +static struct ddloc *dd_hash[NDIRHASH]; /* Hash list heads for ddlocs */ + +/* + * return a pointer into a directory + */ +long +telldir(dirp) + const DIR *dirp; +{ + register int index; + register struct ddloc *lp; + + if ((lp = (struct ddloc *)malloc(sizeof(struct ddloc))) == NULL) + return (-1); + index = dd_loccnt++; + lp->loc_index = index; + lp->loc_seek = dirp->dd_seek; + lp->loc_loc = dirp->dd_loc; + lp->loc_next = dd_hash[LOCHASH(index)]; + dd_hash[LOCHASH(index)] = lp; + return (index); +} + +/* + * seek to an entry in a directory. + * Only values returned by "telldir" should be passed to seekdir. + */ +void +_seekdir(dirp, loc) + register DIR *dirp; + long loc; +{ + register struct ddloc *lp; + register struct ddloc **prevlp; + struct dirent *dp; + extern long lseek(); + + prevlp = &dd_hash[LOCHASH(loc)]; + lp = *prevlp; + while (lp != NULL) { + if (lp->loc_index == loc) + break; + prevlp = &lp->loc_next; + lp = lp->loc_next; + } + if (lp == NULL) + return; + if (lp->loc_loc == dirp->dd_loc && lp->loc_seek == dirp->dd_seek) + goto found; + (void) lseek(dirp->dd_fd, lp->loc_seek, 0); + dirp->dd_seek = lp->loc_seek; + dirp->dd_loc = 0; + while (dirp->dd_loc < lp->loc_loc) { + dp = readdir(dirp); + if (dp == NULL) + break; + } +found: +#ifdef SINGLEUSE + *prevlp = lp->loc_next; + free((caddr_t)lp); +#endif +} + +#endif /* ! HAVE_OPENDIR */ -- cgit v1.2.3