import winsup-2000-02-17 snapshot
This commit is contained in:
46
winsup/CYGWIN_LICENSE
Normal file
46
winsup/CYGWIN_LICENSE
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
--------------------------------------------------------------------------
|
||||||
|
This program is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License (GPL) as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
This program 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 General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
*** NOTE ***
|
||||||
|
|
||||||
|
In accordance with section 10 of the GPL, Cygnus permits programs whose
|
||||||
|
sources are distributed under a license that complies with the Open
|
||||||
|
Source definition to be linked with libcygwin.a without libcygwin.a
|
||||||
|
itself causing the resulting program to be covered by the GNU GPL.
|
||||||
|
|
||||||
|
This means that you can port an Open Source(tm) application to cygwin,
|
||||||
|
and distribute that executable as if it didn't include a copy of
|
||||||
|
libcygwin.a linked into it. Note that this does not apply to the cygwin
|
||||||
|
DLL itself. If you distribute a (possibly modified) version of the DLL
|
||||||
|
you must adhere to the terms of the GPL, i.e., you must provide sources
|
||||||
|
for the cygwin DLL.
|
||||||
|
|
||||||
|
See http://www.opensource.org/osd.html for the precise Open Source
|
||||||
|
Definition referenced above.
|
||||||
|
|
||||||
|
If you have questions about any of the above or would like to arrange
|
||||||
|
for other licensing terms, please contact Cygnus using the information
|
||||||
|
given below:
|
||||||
|
|
||||||
|
Cygnus Solutions
|
||||||
|
1325 Chesapeake Terrace
|
||||||
|
Sunnyvale, CA 94089
|
||||||
|
USA
|
||||||
|
|
||||||
|
+1 408 542 9600
|
||||||
|
hotline: +1 408 542 9601
|
||||||
|
email: info@cygnus.com
|
||||||
|
fax: +1 408 542 9699
|
36
winsup/ChangeLog
Normal file
36
winsup/ChangeLog
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
Sun Feb 6 18:15:44 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
* configure.in: Do the standard CC/CFLAGS stuff for propagation to
|
||||||
|
sub-configures.
|
||||||
|
* configure: Regenerate.
|
||||||
|
|
||||||
|
2000-01-26 DJ Delorie <dj@cygnus.com>
|
||||||
|
|
||||||
|
* doc/Makefile.in: fix doctool -d options
|
||||||
|
|
||||||
|
Fri Jan 21 12:51:32 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
* Makefile.common: No need to rerun Makefile if config.status changes.
|
||||||
|
That should happen automatically.
|
||||||
|
* Makefile.in: Ditto.
|
||||||
|
|
||||||
|
Sat Jan 8 14:40:01 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
* Makefile.common: Remove cygwin DLL specific stuff. Make Makefile
|
||||||
|
target PRECIOUS.
|
||||||
|
* Makefile.in: Make Makefile target PRECIOUS.
|
||||||
|
|
||||||
|
Fri Jan 7 21:00:49 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
* Makefile.common: Remove cygwin DLL specific stuff. Correctly deal
|
||||||
|
with updir stuff when building in the same directory as the source.
|
||||||
|
|
||||||
|
Thu Jan 6 19:04:35 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
Create new directory structure
|
||||||
|
* Makefile.in: New file.
|
||||||
|
* configure.in: New file.
|
||||||
|
* configure: New file.
|
||||||
|
* Makefile.common: New file.
|
||||||
|
* cygwin: New directory.
|
||||||
|
* w32api: New directory.
|
17
winsup/MAINTAINERS
Normal file
17
winsup/MAINTAINERS
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
The following people are responsible for maintaining various pieces of
|
||||||
|
the winsup directory. Their approval is required before committing any
|
||||||
|
changes to the repository.
|
||||||
|
|
||||||
|
Makefile.* Chris Faylor <cgf@cygnus.com>
|
||||||
|
configure.* Chris Faylor <cgf@cygnus.com>
|
||||||
|
MAINTAINERS Chris Faylor <cgf@cygnus.com>
|
||||||
|
cygwin/security.cc and
|
||||||
|
ntsec stuff Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
cygwin/fhandler_tape.cc Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
cygwin/{everything else} Chris Faylor <cgf@cygnus.com>,
|
||||||
|
DJ Delorie <cgf@cygnus.com>
|
||||||
|
doc/* DJ Delorie <cgf@cygnus.com>
|
||||||
|
mingw/* Mumit Khan <xraylith.wisc.edu>
|
||||||
|
utils/* Chris Faylor <cgf@cygnus.com>,
|
||||||
|
DJ Delorie <dj@cygnus.com>
|
||||||
|
w32api/* Mumit Khan <xraylith.wisc.edu>
|
127
winsup/Makefile.common
Normal file
127
winsup/Makefile.common
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
# Makefile.common - common definitions for the winsup directory
|
||||||
|
#
|
||||||
|
# Copyright 2000 Cygnus Solutions.
|
||||||
|
#
|
||||||
|
# This file is part of Cygwin.
|
||||||
|
#
|
||||||
|
# This software is a copyrighted work licensed under the terms of the
|
||||||
|
# Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
# details.
|
||||||
|
|
||||||
|
# This makefile requires GNU make.
|
||||||
|
|
||||||
|
CFLAGS_COMMON:=-Wall -Wwrite-strings # -finline-functions
|
||||||
|
MALLOC_DEBUG:=#-DMALLOC_DEBUG -I/gotham/src/comp-tools/winsup/dlmalloc
|
||||||
|
MALLOC_OBJ:=#/gotham/src/comp-tools/winsup/dlmalloc/malloc.o
|
||||||
|
|
||||||
|
ifeq (,${findstring /,$(srcdir)})
|
||||||
|
updir:=$(srcdir)/..
|
||||||
|
updir1:=$(updir)/..
|
||||||
|
else
|
||||||
|
updir:=${patsubst %:::,%,${patsubst %/:::,%,$(dir $(srcdir)):::}}
|
||||||
|
ifneq (,${findstring /,$(updir)})
|
||||||
|
updir1:=${patsubst %:::,%,${patsubst %/:::,%,$(dir $(updir)):::}}
|
||||||
|
else
|
||||||
|
updir1:=$(updir)/..
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
pwd:=${shell pwd}
|
||||||
|
ifeq (,${findstring /,$(pwd)})
|
||||||
|
bupdir:=..
|
||||||
|
bupdir1:=../..
|
||||||
|
else
|
||||||
|
bupdir:=${patsubst %:::,%,${patsubst %/:::,%,$(dir $(pwd)):::}}
|
||||||
|
ifneq (,${findstring /,$(bupdir)})
|
||||||
|
bupdir1:=${patsubst %:::,%,${patsubst %/:::,%,$(dir $(bupdir)):::}}
|
||||||
|
else
|
||||||
|
bupdir1:=$(bupdir)/..
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
w32api_source:=$(updir)/w32api
|
||||||
|
w32api_build:=$(bupdir)/w32api
|
||||||
|
w32api_include:=$(w32api_source)/include
|
||||||
|
w32api_lib:=$(w32api_build)/lib
|
||||||
|
newlib_source:=$(updir1)/newlib
|
||||||
|
newlib_build:=$(bupdir1)/newlib
|
||||||
|
cygwin_build:=$(bupdir)/cygwin
|
||||||
|
cygwin_source:=$(updir)/cygwin
|
||||||
|
mingw_build:=$(bupdir)/mingw
|
||||||
|
mingw_source:=$(updir)/mingw
|
||||||
|
utils_build:=$(bupdir)/utils
|
||||||
|
utils_source:=$(updir)/utils
|
||||||
|
|
||||||
|
INCLUDES:=-I. -I$(cygwin_source)/include -I$(cygwin_source) -I$(newlib_source)/libc/sys/cygwin -I$(newlib_source)/libc/include -I$(w32api_include)
|
||||||
|
ifdef CONFIG_DIR
|
||||||
|
INCLUDES+=-I$(CONFIG_DIR)
|
||||||
|
endif
|
||||||
|
|
||||||
|
MINGW_INCLUDES:=-I$(updir)/mingw/include $(INCLUDES)
|
||||||
|
|
||||||
|
GCC_DEFAULT_OPTIONS:=$(CFLAGS_COMMON) $(CFLAGS_CONFIG) $(INCLUDES)
|
||||||
|
|
||||||
|
# Link in libc and libm from newlib
|
||||||
|
|
||||||
|
LIBC:=$(newlib_build)/libc/libc.a
|
||||||
|
LIBM:=$(newlib_build)/libm/libm.a
|
||||||
|
CRT0:=$(newlib_build)/libc/crt0.o
|
||||||
|
|
||||||
|
ALL_CFLAGS:=$(DEFS) $(MALLOC_DEBUG) $(CFLAGS) $(GCC_DEFAULT_OPTIONS)
|
||||||
|
ALL_CXXFLAGS:=$(DEFS) $(MALLOC_DEBUG) $(CXXFLAGS) $(GCC_DEFAULT_OPTIONS)
|
||||||
|
|
||||||
|
ifndef PREPROCESS
|
||||||
|
c=-c
|
||||||
|
o=.o
|
||||||
|
else
|
||||||
|
c=-E
|
||||||
|
o=.E
|
||||||
|
endif
|
||||||
|
|
||||||
|
LIBGCC:=${subst \,/,${shell $(CC_FOR_TARGET) -print-libgcc-file-name}}
|
||||||
|
GCC_INCLUDE:=${dir $(LIBGCC)}/include
|
||||||
|
|
||||||
|
COMPILE_CXX:=$(CC) $c -nostdinc++ $(ALL_CXXFLAGS) -I$(GCC_INCLUDE) \
|
||||||
|
-fno-rtti -fno-exceptions
|
||||||
|
COMPILE_CC:=$(CC) $c -nostdinc $(ALL_CFLAGS) -I$(GCC_INCLUDE)
|
||||||
|
|
||||||
|
vpath %.a $(cygwin_build):$(w32api_lib):$(newlib_build)/libc:$(newlib_build)/libm
|
||||||
|
|
||||||
|
unexport MAKEOVERRIDES
|
||||||
|
|
||||||
|
.PRECIOUS: %.o
|
||||||
|
|
||||||
|
%.o: %.cc
|
||||||
|
ifdef VERBOSE
|
||||||
|
$(COMPILE_CXX) -o $(@D)/$(*F)$o $<
|
||||||
|
else
|
||||||
|
@echo $(CC) $c $(CXXFLAGS) -o $(@D)/$(*F)$o ${subst $(srcdir)/,,$<}; \
|
||||||
|
$(COMPILE_CXX) -o $(@D)/$(*F)$o $<
|
||||||
|
endif
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
ifdef VERBOSE
|
||||||
|
$(COMPILE_CC) -o $(@D)/$(*F)$o $<
|
||||||
|
else
|
||||||
|
@echo $(CC) $c $(CFLAGS) -o $(@D)/$(*F)$o ${subst $(srcdir)/,,$<}; \
|
||||||
|
$(COMPILE_CC) -o $(@D)/$(*F)$o $<
|
||||||
|
endif
|
||||||
|
|
||||||
|
$(bupdir1)/libiberty/%.o: $(updir1)/libiberty/%.c
|
||||||
|
@$(MAKE) -C $(@D) $(MAKEOVERRIDES) $(@F)
|
||||||
|
|
||||||
|
$(w32api_lib)/%.a: $(w32api_lib)/Makefile
|
||||||
|
@$(MAKE) --no-print-dir -C $(@D) $(MAKEOVERRIDES) $(@F)
|
||||||
|
|
||||||
|
all:
|
||||||
|
|
||||||
|
# For auto-rebuilding the Makefile
|
||||||
|
|
||||||
|
.PRECIOUS: Makefile
|
||||||
|
|
||||||
|
Makefile: Makefile.in $(srcdir)/configure.in config.status
|
||||||
|
$(SHELL) config.status
|
||||||
|
|
||||||
|
config.status: configure
|
||||||
|
$(SHELL) config.status --recheck
|
71
winsup/Makefile.in
Normal file
71
winsup/Makefile.in
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
# Makefile.in for windows stuff
|
||||||
|
# Copyright 1995, 1996, 1997, 1998, 1999 Cygnus Solutions.
|
||||||
|
#
|
||||||
|
# This file is part of Cygwin.
|
||||||
|
#
|
||||||
|
# This software is a copyrighted work licensed under the terms of the
|
||||||
|
# Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
# details.
|
||||||
|
|
||||||
|
# This makefile requires GNU make.
|
||||||
|
|
||||||
|
SHELL:=@SHELL@
|
||||||
|
VPATH:=@srcdir@
|
||||||
|
srcdir:=@srcdir@
|
||||||
|
objdir:=.
|
||||||
|
|
||||||
|
target_alias:=@target_alias@
|
||||||
|
build_alias:=@build_alias@
|
||||||
|
host_alias:=@host_alias@
|
||||||
|
prefix:=@prefix@
|
||||||
|
|
||||||
|
program_transform_name:=@program_transform_name@
|
||||||
|
exec_prefix:=@exec_prefix@
|
||||||
|
bindir:=@bindir@
|
||||||
|
libdir:=@libdir@
|
||||||
|
ifeq ($(target_alias),$(host_alias))
|
||||||
|
ifeq ($(build_alias),$(host_alias))
|
||||||
|
tooldir:=$(exec_prefix)
|
||||||
|
else
|
||||||
|
tooldir:=$(exec_prefix)/$(target_alias)
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
tooldir:=$(exec_prefix)/$(target_alias)
|
||||||
|
endif
|
||||||
|
datadir:=@datadir@
|
||||||
|
infodir:=@infodir@
|
||||||
|
includedir:=@includedir@
|
||||||
|
|
||||||
|
SUBDIRS=@SUBDIRS@
|
||||||
|
INSTALL_SUBDIRS=${patsubst %,install_%,$(SUBDIRS)}
|
||||||
|
CLEAN_SUBDIRS=${patsubst %,clean_%,$(SUBDIRS)}
|
||||||
|
|
||||||
|
.PHONY: all install clean $(SUBDIRS) $(INSTALL_SUBDIRS) \
|
||||||
|
$(CLEAN_SUBDIRS)
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
|
||||||
|
unexport MAKEOVERRIDES
|
||||||
|
|
||||||
|
all: Makefile $(SUBDIRS)
|
||||||
|
|
||||||
|
install: Makefile $(INSTALL_SUBDIRS)
|
||||||
|
|
||||||
|
clean: $(CLEAN_SUBDIRS)
|
||||||
|
|
||||||
|
$(SUBDIRS):
|
||||||
|
@$(MAKE) -C $@ $(MAKEOVERRIDES) all
|
||||||
|
|
||||||
|
$(INSTALL_SUBDIRS):
|
||||||
|
@$(MAKE) -C ${patsubst install_%,%,$@} $(MAKEOVERRIDES) install
|
||||||
|
|
||||||
|
$(CLEAN_SUBDIRS):
|
||||||
|
@$(MAKE) -C ${patsubst clean_%,%,$@} $(MAKEOVERRIDES) clean
|
||||||
|
|
||||||
|
.PRECIOUS: Makefile
|
||||||
|
|
||||||
|
Makefile: Makefile.in $(srcdir)/configure.in config.status
|
||||||
|
$(SHELL) config.status
|
||||||
|
|
||||||
|
config.status: configure
|
||||||
|
$(SHELL) config.status --recheck
|
1223
winsup/configure
vendored
Executable file
1223
winsup/configure
vendored
Executable file
File diff suppressed because it is too large
Load Diff
65
winsup/configure.in
Executable file
65
winsup/configure.in
Executable file
@ -0,0 +1,65 @@
|
|||||||
|
dnl Autoconf configure script for Cygwin.
|
||||||
|
dnl Copyright 1996, 1997, 1998 Cygnus Solutions.
|
||||||
|
dnl
|
||||||
|
dnl This file is part of Cygwin.
|
||||||
|
dnl
|
||||||
|
dnl This software is a copyrighted work licensed under the terms of the
|
||||||
|
dnl Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
dnl details.
|
||||||
|
dnl
|
||||||
|
dnl Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
|
AC_PREREQ(2.12)dnl
|
||||||
|
AC_INIT(Makefile.in)
|
||||||
|
|
||||||
|
dnl FIXME: We temporarily define our own version of AC_PROG_CC. This is
|
||||||
|
dnl copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS. We
|
||||||
|
dnl are probably using a cross compiler, which will not be able to fully
|
||||||
|
dnl link an executable. This should really be fixed in autoconf
|
||||||
|
dnl itself.
|
||||||
|
|
||||||
|
AC_DEFUN(LIB_AC_PROG_CC,
|
||||||
|
[AC_BEFORE([$0], [AC_PROG_CPP])dnl
|
||||||
|
AC_CHECK_TOOL(CC, gcc, gcc)
|
||||||
|
if test -z "$CC"; then
|
||||||
|
AC_CHECK_PROG(CC, cc, cc, , , /usr/ucb/cc)
|
||||||
|
test -z "$CC" && AC_MSG_ERROR([no acceptable cc found in \$PATH])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_PROG_CC_GNU
|
||||||
|
|
||||||
|
if test $ac_cv_prog_gcc = yes; then
|
||||||
|
GCC=yes
|
||||||
|
dnl Check whether -g works, even if CFLAGS is set, in case the package
|
||||||
|
dnl plays around with CFLAGS (such as to build both debugging and
|
||||||
|
dnl normal versions of a library), tasteless as that idea is.
|
||||||
|
ac_test_CFLAGS="${CFLAGS+set}"
|
||||||
|
ac_save_CFLAGS="$CFLAGS"
|
||||||
|
CFLAGS=
|
||||||
|
AC_PROG_CC_G
|
||||||
|
if test "$ac_test_CFLAGS" = set; then
|
||||||
|
CFLAGS="$ac_save_CFLAGS"
|
||||||
|
elif test $ac_cv_prog_cc_g = yes; then
|
||||||
|
CFLAGS="-g -O2"
|
||||||
|
else
|
||||||
|
CFLAGS="-O2"
|
||||||
|
fi
|
||||||
|
if test "$ac_test_CXXFLAGS" != set; then
|
||||||
|
CXXFLAGS='$(CFLAGS)'
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
GCC=
|
||||||
|
test "${CFLAGS+set}" = set || CFLAGS="-g"
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_CANONICAL_SYSTEM
|
||||||
|
|
||||||
|
LIB_AC_PROG_CC
|
||||||
|
|
||||||
|
SUBDIRS="cygwin w32api mingw utils doc"
|
||||||
|
AC_CONFIG_SUBDIRS($SUBDIRS)
|
||||||
|
AC_PROG_MAKE_SET
|
||||||
|
|
||||||
|
AC_SUBST(SUBDIRS)
|
||||||
|
AC_OUTPUT(Makefile)
|
46
winsup/cygwin/CYGWIN_LICENSE
Normal file
46
winsup/cygwin/CYGWIN_LICENSE
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
--------------------------------------------------------------------------
|
||||||
|
This program is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License (GPL) as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
This program 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 General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
*** NOTE ***
|
||||||
|
|
||||||
|
In accordance with section 10 of the GPL, Cygnus permits programs whose
|
||||||
|
sources are distributed under a license that complies with the Open
|
||||||
|
Source definition to be linked with libcygwin.a without libcygwin.a
|
||||||
|
itself causing the resulting program to be covered by the GNU GPL.
|
||||||
|
|
||||||
|
This means that you can port an Open Source(tm) application to cygwin,
|
||||||
|
and distribute that executable as if it didn't include a copy of
|
||||||
|
libcygwin.a linked into it. Note that this does not apply to the cygwin
|
||||||
|
DLL itself. If you distribute a (possibly modified) version of the DLL
|
||||||
|
you must adhere to the terms of the GPL, i.e., you must provide sources
|
||||||
|
for the cygwin DLL.
|
||||||
|
|
||||||
|
See http://www.opensource.org/osd.html for the precise Open Source
|
||||||
|
Definition referenced above.
|
||||||
|
|
||||||
|
If you have questions about any of the above or would like to arrange
|
||||||
|
for other licensing terms, please contact Cygnus using the information
|
||||||
|
given below:
|
||||||
|
|
||||||
|
Cygnus Solutions
|
||||||
|
1325 Chesapeake Terrace
|
||||||
|
Sunnyvale, CA 94089
|
||||||
|
USA
|
||||||
|
|
||||||
|
+1 408 542 9600
|
||||||
|
hotline: +1 408 542 9601
|
||||||
|
email: info@cygnus.com
|
||||||
|
fax: +1 408 542 9699
|
229
winsup/cygwin/ChangeLog
Normal file
229
winsup/cygwin/ChangeLog
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
Mon Feb 7 16:50:44 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
* Makefile.in: cygrun needs libshell32.a.
|
||||||
|
|
||||||
|
Sun Feb 6 22:17:58 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
* sigproc.cc (proc_subproc): Simplify case for when a child process is
|
||||||
|
stopped since new signal handler ensures the desired behavior.
|
||||||
|
|
||||||
|
Sun Feb 6 21:52:33 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
* Makefile.in: Fix install target so that directories will be created
|
||||||
|
when necessary.
|
||||||
|
|
||||||
|
Sun Feb 6 18:12:17 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
* Makefile.in: exceptions.cc should depend on autoload.h.
|
||||||
|
* exceptions.cc: Undef DECLSPEC_IMPORT prior to including imagehlp.h to
|
||||||
|
avoid defining StackWalk as "import".
|
||||||
|
(call_handler): Minor optimizations.
|
||||||
|
(sig_handle_tty_stop): Fix typo in previous checkin.
|
||||||
|
* sigproc.cc (sigproc_init): Ditto, for signal_arrived initialization.
|
||||||
|
|
||||||
|
Sat Feb 5 15:37:37 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
* dcrt0.cc (isquote): Convert to inline function.
|
||||||
|
|
||||||
|
Sat Feb 5 00:26:01 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
Throughout, rename global_signal_arrived to signal_arrived.
|
||||||
|
Throughout, eliminate use of arm_signals and __signal_arrived.
|
||||||
|
Throughout, revert to use of simple call to WaitForSingleObject or
|
||||||
|
WaitForMultipleObjects.
|
||||||
|
* debug.h: Eliminate obsolete function declaration.
|
||||||
|
* exceptions.cc (sigWaitForSingleObject): Eliminate obsolete function
|
||||||
|
definition.
|
||||||
|
* fhandler.h: Reflect change to select_stuff wait method.
|
||||||
|
* fhandler_tape.cc (get_ll): Accomodate new w32api LARGE_INTEGER
|
||||||
|
definition.
|
||||||
|
* ntea.c (NTReadEARaw): Ditto.
|
||||||
|
(NTWriteEA): Ditto.
|
||||||
|
* security.cc (ReadSD): Ditto.
|
||||||
|
(WriteSD): Ditto.
|
||||||
|
* syscalls.cc (_link): Ditto.
|
||||||
|
* uname.cc (uname): Eliminate PPC switch.
|
||||||
|
|
||||||
|
2000-02-01 Salvador Eduardo Tropea <salvador@inti.gov.ar>
|
||||||
|
|
||||||
|
* include/io.h: add return type to setmode()
|
||||||
|
|
||||||
|
2000-01-27 DJ Delorie <dj@cygnus.com>
|
||||||
|
|
||||||
|
* include/netdb.h (h_errno): change __imp_ to dllimport
|
||||||
|
* cygwin.din (reent_data): add DATA
|
||||||
|
|
||||||
|
Thu Jan 27 01:07:14 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
* exceptions.cc (call_handler): Add debugging output.
|
||||||
|
* select.cc (MAKEready): Arm signals earlier.
|
||||||
|
* sigproc.cc (__signal_arrived:arm): Move debugging version of this
|
||||||
|
method here.
|
||||||
|
(__signal_arrived::release): Ditto.
|
||||||
|
* sigproc.h: Recognize debugging versions of above two methods.
|
||||||
|
(arm_signals::WaitForMultipleObjects): Don't release signal lock unless
|
||||||
|
signal arrived.
|
||||||
|
(arm_signals::WaitForMultipleSingleObject): Ditto.
|
||||||
|
(arm_signals::MsgWaitForMultipleObjects): Ditto.
|
||||||
|
|
||||||
|
Thu Jan 27 00:19:26 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
* sync.h (new_muto): Workaround change in gcc behavior.
|
||||||
|
|
||||||
|
Wed Jan 26 12:57:13 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
* Makefile.in: Ensure that all required libraries are built prior
|
||||||
|
to linking cygrun.exe.
|
||||||
|
|
||||||
|
Tue Jan 25 21:26:57 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
* exceptions.cc (sig_handle): Crudely work around potential problem
|
||||||
|
when main thread has a lock but is killed by a fatal signal.
|
||||||
|
* fhandler_tty.cc (fhandler_pty_master::write): Don't perform line
|
||||||
|
editing on the pty master (so why do we need the second argument to
|
||||||
|
line_edit, then?)
|
||||||
|
* thread.cc: Reformat to GNU standards.
|
||||||
|
|
||||||
|
2000-01-11 DJ Delorie <dj@cygnus.com>
|
||||||
|
|
||||||
|
* ROADMAP: new
|
||||||
|
|
||||||
|
2000-01-11 DJ Delorie <dj@cygnus.com>
|
||||||
|
|
||||||
|
* fhandler_zero.cc: new, emulate /dev/zero
|
||||||
|
* testsuite/winsup.api/devzero.c: new, test /dev/zero
|
||||||
|
* Makefile.in: build fhandler_zero.o
|
||||||
|
* fhandler.h: add support for /dev/zero
|
||||||
|
* hinfo.cc: ditto
|
||||||
|
* path.cc: ditto
|
||||||
|
|
||||||
|
2000-01-11 DJ Delorie <dj@cygnus.com>
|
||||||
|
|
||||||
|
* mmap.cc (mmap): MSDN says *one* of FILE_MAP_*, fix flags for
|
||||||
|
MAP_PRIVATE.
|
||||||
|
|
||||||
|
Mon Jan 10 01:11:00 2000 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* security.cc (acl_access): New function.
|
||||||
|
* syscalls.cc (access): Call acl_access if ntsec is on.
|
||||||
|
|
||||||
|
Mon Jan 10 01:11:00 2000 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* fhandler.cc (get_file_owner): Use of ReadSD() instead of
|
||||||
|
GetFileSecurity().
|
||||||
|
(get_file_group): Ditto.
|
||||||
|
|
||||||
|
Sun Jan 9 15:43:07 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
* debug.cc (struct thread_start): Add a flag to determine whether a
|
||||||
|
field is in use. Eliminate thread_start_ix since it was not
|
||||||
|
thread-safe.
|
||||||
|
(thread_stub): Use notavail flag to control whether the entry in
|
||||||
|
start_buf can be reused.
|
||||||
|
(makethread): Ditto.
|
||||||
|
|
||||||
|
Sun Jan 9 20:18:00 2000 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* security.cc (alloc_sd): Rearrange order of ACE creation.
|
||||||
|
(setacl): Optimize creation of ACEs related to inheritance. Code
|
||||||
|
cleanup.
|
||||||
|
(aclcheck): Disable check for existance of DEF_)CLASS_OBJ.
|
||||||
|
|
||||||
|
Sat Jan 8 18:42:32 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
* mkvers.h: Reorg fix.
|
||||||
|
|
||||||
|
Sat Jan 8 20:00:00 2000 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* cygwin.din: Add new acl API calls.
|
||||||
|
* grp.cc (getgroups): Change to work for any username.
|
||||||
|
* security.cc (get_id_from_sid): Change to work with acl API.
|
||||||
|
(is_grp_member): New function.
|
||||||
|
(get_nt_attribute): Rewritten.
|
||||||
|
(add_access_allowed_ace): New function.
|
||||||
|
(add_access_denied_ace): Ditto.
|
||||||
|
(alloc_sd): Rewritten.
|
||||||
|
(setacl): New function.
|
||||||
|
(getace): Ditto.
|
||||||
|
(searchace): Ditto.
|
||||||
|
(getacl): Ditto.
|
||||||
|
(acl): Ditto.
|
||||||
|
(facl): Ditto.
|
||||||
|
(aclcheck): Ditto.
|
||||||
|
(acecmp): Ditto.
|
||||||
|
(aclsort): Ditto.
|
||||||
|
(acltomode): Ditto.
|
||||||
|
(aclfrommode): Ditto.
|
||||||
|
(acltopbits): Ditto.
|
||||||
|
(aclfrompbits): Ditto.
|
||||||
|
(permtostr): Ditto.
|
||||||
|
(acltotext): Ditto.
|
||||||
|
(permfromstr): Ditto.
|
||||||
|
(aclfromtext): Ditto.
|
||||||
|
* syscalls.cc (access): Set errno again when needed.
|
||||||
|
* include/cygwin/acl.h: New file.
|
||||||
|
* include/sys/acl.h: Ditto.
|
||||||
|
|
||||||
|
Sat Jan 8 14:46:19 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
* Makefile.in: Add cygwin DLL specific CFLAGS define.
|
||||||
|
|
||||||
|
Fri Jan 7 21:01:57 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
* exceptions.cc (interrupt_on_return): Properly coerce assignment of
|
||||||
|
sigsave.func.
|
||||||
|
|
||||||
|
2000-01-07 Mumit Khan <khan@xraylith.wisc.edu>
|
||||||
|
|
||||||
|
* acconfig.h: New file.
|
||||||
|
* configure.in Add check for memset builtin.
|
||||||
|
(AC_CONFIG_HEADER): Use.
|
||||||
|
(STRACE_HHMMSS): Define instead of substituting.
|
||||||
|
(_MT_SAFE): Likewise.
|
||||||
|
(_CYG_THREAD_FAILSAFE): Likewise.
|
||||||
|
(DEBUGGING): Likewise.
|
||||||
|
(MT_SAFE): Substitute as a yes/no variable.
|
||||||
|
* Makefile.in: Remove DEBUGGING, STRACE_HHMMSS, and THREAD_FAILSAFE
|
||||||
|
variables and add DEFS. Update usage of MT_SAFE to reflect yes/no
|
||||||
|
values. Add config.h to winsup.h dependency.
|
||||||
|
(CFLAGS_CONFIG): Update.
|
||||||
|
(INCLUDES): Prepend `-I.'.
|
||||||
|
* utils/Makefile.in (INCLUDES): Likewise.
|
||||||
|
* winsup.h: Conditionally include config.h.
|
||||||
|
* thread.cc: Likewise.
|
||||||
|
* config.h.in: Generate new file.
|
||||||
|
* configure: Regenerate.
|
||||||
|
|
||||||
|
|
||||||
|
Fri Jan 7 16:21:01 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
* dcrt0.cc (dll_crt0): Allow signal handling for dynamically loaded
|
||||||
|
case.
|
||||||
|
|
||||||
|
Thu Jan 6 00:30:12 2000 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* path.cc (symlink_check_one): Initialize local variable `unixattr'
|
||||||
|
before calling `get_file_attribute'.
|
||||||
|
* syscalls.cc (chown): Ditto.
|
||||||
|
* security.cc (get_nt_attribute): Eliminate attribute copying from
|
||||||
|
world to user/group in case of missing ACEs.
|
||||||
|
(alloc_sd): Set special rights for administrators group only if it's
|
||||||
|
neither owner nor group.
|
||||||
|
* utils/mkpasswd.c: Create entry for local group administrators (SID
|
||||||
|
544).
|
||||||
|
|
||||||
|
Thu Jan 6 00:21:31 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
Change function calls to __stdcall throughout.
|
||||||
|
* exceptions.cc (handle_exceptions): Probe stack for return address to
|
||||||
|
use with new signal method. Fill out sigsave.cx with this information.
|
||||||
|
(call_handler): Use sigsave.cx if it is available, rather than trying
|
||||||
|
to find the context of the main thread.
|
||||||
|
(interrupt_on_return): Use address of context rather than
|
||||||
|
pass-by-reference.
|
||||||
|
(interrupt_now): Ditto.
|
||||||
|
|
||||||
|
Thu Jan 6 00:21:31 2000 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* grp.cc (getgroups): Return supplementary groups now.
|
||||||
|
* include/limits.h: Define NGROUP_MAX as 16 now.
|
177
winsup/cygwin/ChangeLog-1995
Normal file
177
winsup/cygwin/ChangeLog-1995
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
Mon Dec 18 16:44:38 1995 Jason Molenda (crash@phydeaux.cygnus.com)
|
||||||
|
|
||||||
|
* configure.in (target_cpu): specify valid Intel x86 architectures
|
||||||
|
explicitly.
|
||||||
|
|
||||||
|
Mon Dec 18 15:04:29 1995 Jason Molenda (crash@phydeaux.cygnus.com)
|
||||||
|
|
||||||
|
* sysdef/*.def: moved to sysdef/i386/.
|
||||||
|
|
||||||
|
Mon Dec 18 15:00:56 1995 Jason Molenda (crash@phydeaux.cygnus.com)
|
||||||
|
|
||||||
|
* configure.in: Set DLL_ENTRY and SYSDEF_DIR for i386 and powerpc.
|
||||||
|
* configure: Regenerated with autoconf 2.7.
|
||||||
|
|
||||||
|
* Makefile.in: Use DLL_ENTRY and SYSDEF_DIR.
|
||||||
|
|
||||||
|
Sat Dec 16 18:36:44 1995 steve chamberlain <sac@slash.cygnus.com>
|
||||||
|
|
||||||
|
Changed the way that file handles are inherited. Now
|
||||||
|
all files are opened with the inheriting turned on, and they're
|
||||||
|
closed when necessary.
|
||||||
|
|
||||||
|
Changed the way that children are waited for. Now
|
||||||
|
you can exec a non-gnuwin32 program and wait for its
|
||||||
|
result.
|
||||||
|
|
||||||
|
* Makefile.in: Turn off frame-pointer.
|
||||||
|
* dcrt0.cc (environ_init): Lint.
|
||||||
|
* dirsearch.cc (opendir): Use new path_conv mechanism.
|
||||||
|
* exceptions.cc (ctrl_c_handler): Exit with correct status
|
||||||
|
* exec.cc (file_exists): Moved to paths.cc
|
||||||
|
(_execve): Moved most of the work into spawn.cc.
|
||||||
|
* fhandler.cc (*): Much.
|
||||||
|
* libccrt0.c (foo): Deleted.
|
||||||
|
(cygwin_crt0): Lint.
|
||||||
|
* path.cc (readlink): Initialize the SECURITY_ATTRIBUTES struct.
|
||||||
|
* pipe.cc (pipe, dup*): Reorganized.
|
||||||
|
* registry.cc (read_in): Create the key in CURRENT_USER.
|
||||||
|
* wait.cc, spawn.cc (*): Much.
|
||||||
|
* sysconf.cc (sysconf): Understand SC_PAGESIZE.
|
||||||
|
* times.cc (utime): New function.
|
||||||
|
* uname.cc (uname): Dig out more info.
|
||||||
|
|
||||||
|
Wed Dec 13 05:54:55 1995 Michael Meissner <meissner@tiktok.cygnus.com>
|
||||||
|
|
||||||
|
* dcrt0.cc (environ_init): Cast alloca return to appropriate type.
|
||||||
|
* spawn.cc (spawn_guts): Ditto.
|
||||||
|
|
||||||
|
* strace.cc (__small_{v,}sprintf): Add appropriate prototypes.
|
||||||
|
|
||||||
|
* exceptions.cc (_except_list): Only use segments for 386 systems.
|
||||||
|
(__stack_trace): Add PowerPC support, and do nothing for systems
|
||||||
|
that are not supported except print stack tracing is not yet
|
||||||
|
support.
|
||||||
|
|
||||||
|
* sdata.cc (import_term): Only use __attribute__((section)) on 386
|
||||||
|
systems.
|
||||||
|
|
||||||
|
* shared.cc (shared_init): Use MARK macro instead of calling mark
|
||||||
|
directly with incorrect type arguments.
|
||||||
|
|
||||||
|
* fhandler.cc (fhandler_dev_null::{read,write}): Use size_t in
|
||||||
|
prototype, not unsigned int.
|
||||||
|
|
||||||
|
* fork.cc (find_exec): Fix type errors.
|
||||||
|
* path.cc (path_to_real_path_keep_rel): Ditto.
|
||||||
|
* syscalls.h (PATH_TO_REAL_PATH): Ditto.
|
||||||
|
|
||||||
|
* {longjmp,setjmp}.c: #ifdef i386 code.
|
||||||
|
|
||||||
|
* include/wintypes.h (ExitProcess): Add
|
||||||
|
__attribute__((__noreturn__)) so exit compiles without warnings.
|
||||||
|
|
||||||
|
Tue Dec 12 18:25:05 1995 Jason Molenda (crash@phydeaux.cygnus.com)
|
||||||
|
|
||||||
|
* include/wintypes.h (WINAPI): Only define WINAPI for x86 systems.
|
||||||
|
|
||||||
|
Tue Dec 5 16:00:05 1995 Jason Molenda (crash@phydeaux.cygnus.com)
|
||||||
|
|
||||||
|
* Makefile.in (all): Only build documentation for info target.
|
||||||
|
Expect texi2html to not be found most of the time.
|
||||||
|
|
||||||
|
Tue Dec 5 08:08:08 1995 steve chamberlain <sac@slash.cygnus.com>
|
||||||
|
|
||||||
|
Release-B10
|
||||||
|
|
||||||
|
* cygwin.dll (__assert, wait, spawnv, spawnvp): Deleted.
|
||||||
|
* dcrt0.c: Quoting rewritten.
|
||||||
|
* exec.cc (file_exists): Use new path_conv mechanism.
|
||||||
|
(_execve): Close open child process handles.
|
||||||
|
* fhandler.cc (fhandler_normal::open): Follow symlinks.
|
||||||
|
(fhandler_normal::read): Keep track of logical file posision.
|
||||||
|
(fhandler_normal::lseek): Seek in text files correctly.
|
||||||
|
(fhandler_normal::fstat): Set IFLNK bit if its a symlink.
|
||||||
|
(fhandler_normal::init): Maintain is_pipe.
|
||||||
|
(fhandler_dev_null::fstat): New.
|
||||||
|
(fhandler_dev_null::get_handle): Return INVALID_HANDLE.
|
||||||
|
* fork.cc: Use new event mechanism.
|
||||||
|
* libccrt0.cc: Keep track of _fmode variable.
|
||||||
|
* misc.c (readlink): Delete.
|
||||||
|
* path.cc (__path_to_real_path_1): Allow /d<letter> mechanism.
|
||||||
|
(path_to_real_path_keep_rel): New
|
||||||
|
(link_cookie:*): Support for symbolic links.
|
||||||
|
* spawn.cc (spawn_guts): Quoting rewritten.
|
||||||
|
* times.cc: New.
|
||||||
|
* syscalls.cc (_stat_worker): New.
|
||||||
|
(_stat, _lstat): Use _stat_worker.
|
||||||
|
* sysconf.cc (sysconf): Support _SC_CLK_TCK.
|
||||||
|
|
||||||
|
Tue Nov 28 15:29:38 1995 steve chamberlain <sac@slash.cygnus.com>
|
||||||
|
|
||||||
|
* loads of stuff. When I make < 100k of diffs in a day,
|
||||||
|
the ChangeLog will be usefull.
|
||||||
|
|
||||||
|
Tue Nov 21 18:01:39 1995 steve chamberlain <sac@slash.cygnus.com>
|
||||||
|
|
||||||
|
* Makefile.in: Build the doc.
|
||||||
|
* exceptions.cc: lint.
|
||||||
|
* fork.cc: lint.
|
||||||
|
* shared.cc (shared_init): If MapViewOfFileEx fails, then try
|
||||||
|
again, but get the OS to select the address (for win95)
|
||||||
|
* strace.cc (__sysprintf): Print pid and state in hex.
|
||||||
|
* syscalls.cc (_unlink): Translate path to realpath.
|
||||||
|
|
||||||
|
Wed Nov 15 23:47:43 1995 Jason Molenda (crash@phydeaux.cygnus.com)
|
||||||
|
|
||||||
|
* spawn.cc (_exit): set return value's lower byte to 0 by default.
|
||||||
|
|
||||||
|
Tue Oct 3 10:23:14 1995 Anders Blomdell (anders.blomdell@control.lth.se)
|
||||||
|
|
||||||
|
* spawn.cc (spawn_guts): quote doublequotes correctly
|
||||||
|
|
||||||
|
Tue Nov 14 15:05:33 1995 Jason Molenda (crash@phydeaux.cygnus.com)
|
||||||
|
|
||||||
|
* configure.in: comment out call to cfg-ml-com.in.
|
||||||
|
|
||||||
|
Tue Oct 31 11:19:18 1995 steve chamberlain <sac@slash.cygnus.com>
|
||||||
|
|
||||||
|
* libcerr.cc: New file.
|
||||||
|
* dcrt0.cc (environ_init): Initialize PATH and friends nicely.
|
||||||
|
* exceptions.cc (ctrl_c_handler): Default case is to exit.
|
||||||
|
* fork.cc (__suffixy, find_exec): translate between paths and
|
||||||
|
real_paths.
|
||||||
|
* shared.cc (shared_init): Hard wire shared memory at 0xa0000000.
|
||||||
|
* syscalls.c (__path_to_real_path, real_path_to_path): Always
|
||||||
|
translate '/' <> '\'
|
||||||
|
|
||||||
|
Mon Oct 30 17:36:10 1995 steve chamberlain <sac@slash.cygnus.com>
|
||||||
|
|
||||||
|
* syscalls.cc (_rename): Fix for win95.
|
||||||
|
|
||||||
|
Fri Oct 27 20:53:47 1995 steve chamberlain <sac@slash.cygnus.com>
|
||||||
|
|
||||||
|
* Everything changed.
|
||||||
|
|
||||||
|
Thu Oct 19 10:47:52 1995 steve chamberlain <sac@slash.cygnus.com>
|
||||||
|
|
||||||
|
* registry.cc, uinfo.cc: New files.
|
||||||
|
* crt0.c (*uinfo*, *_exe_suffix*): Delete.
|
||||||
|
(dll_crt0): Call shared_init.
|
||||||
|
* getlogin.c: deleted.
|
||||||
|
* shared.cc: Fill in.
|
||||||
|
* spawn.c (_spawn): Use __exe_suffix function.
|
||||||
|
* syscalls.c (getuid, getgid): Moved into uinfo.cc
|
||||||
|
* syscalls.h (*uinfo, __exe_suffix): Deleted
|
||||||
|
* Makefile.in: Cope with target configury.
|
||||||
|
* termios.c: Fix stub prototypes.
|
||||||
|
* win.h: Deleted.
|
||||||
|
* include/winadvapi.h: Fill in some REG prototypes.
|
||||||
|
|
||||||
|
Thu Oct 19 10:47:52 1995 steve chamberlain <sac@slash.cygnus.com>
|
||||||
|
|
||||||
|
* Makefile.in: Cope with target configury.
|
||||||
|
|
||||||
|
Wed Oct 18 15:34:49 1995 steve chamberlain <sac@slash.cygnus.com>
|
||||||
|
|
||||||
|
* Moved from newlib.
|
2031
winsup/cygwin/ChangeLog-1996
Normal file
2031
winsup/cygwin/ChangeLog-1996
Normal file
File diff suppressed because it is too large
Load Diff
2800
winsup/cygwin/ChangeLog-1997
Normal file
2800
winsup/cygwin/ChangeLog-1997
Normal file
File diff suppressed because it is too large
Load Diff
4490
winsup/cygwin/ChangeLog-1998
Normal file
4490
winsup/cygwin/ChangeLog-1998
Normal file
File diff suppressed because it is too large
Load Diff
3552
winsup/cygwin/ChangeLog-1999
Normal file
3552
winsup/cygwin/ChangeLog-1999
Normal file
File diff suppressed because it is too large
Load Diff
341
winsup/cygwin/Makefile.in
Normal file
341
winsup/cygwin/Makefile.in
Normal file
@ -0,0 +1,341 @@
|
|||||||
|
# Makefile.in for Cygwin.
|
||||||
|
# Copyright 1995, 1996, 1997, 1998, 1999, 2000 Cygnus Solutions.
|
||||||
|
#
|
||||||
|
# This file is part of Cygwin.
|
||||||
|
#
|
||||||
|
# This software is a copyrighted work licensed under the terms of the
|
||||||
|
# Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
# details.
|
||||||
|
|
||||||
|
# This makefile requires GNU make.
|
||||||
|
|
||||||
|
CONFIG_DIR:=@srcdir@/config/@CONFIG_DIR@
|
||||||
|
SHELL:=@SHELL@
|
||||||
|
VPATH:=@srcdir@:$(CONFIG_DIR):@srcdir@/regexp
|
||||||
|
srcdir:=@srcdir@
|
||||||
|
objdir:=.
|
||||||
|
|
||||||
|
target_alias:=@target_alias@
|
||||||
|
build_alias:=@build_alias@
|
||||||
|
host_alias:=@host_alias@
|
||||||
|
prefix:=@prefix@
|
||||||
|
|
||||||
|
program_transform_name:=@program_transform_name@
|
||||||
|
exec_prefix:=@exec_prefix@
|
||||||
|
bindir:=@bindir@
|
||||||
|
libdir:=@libdir@
|
||||||
|
ifeq ($(target_alias),$(host_alias))
|
||||||
|
ifeq ($(build_alias),$(host_alias))
|
||||||
|
tooldir:=$(exec_prefix)
|
||||||
|
else
|
||||||
|
tooldir:=$(exec_prefix)/$(target_alias)
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
tooldir:=$(exec_prefix)/$(target_alias)
|
||||||
|
endif
|
||||||
|
datadir:=@datadir@
|
||||||
|
infodir:=@infodir@
|
||||||
|
includedir:=@includedir@
|
||||||
|
|
||||||
|
INSTALL:=@INSTALL@
|
||||||
|
INSTALL_PROGRAM:=@INSTALL_PROGRAM@
|
||||||
|
|
||||||
|
#
|
||||||
|
# --enable options from configure
|
||||||
|
#
|
||||||
|
MT_SAFE = @MT_SAFE@
|
||||||
|
DEFS = @DEFS@
|
||||||
|
|
||||||
|
CC:=@CC@
|
||||||
|
# FIXME: Which is it, CC or CC_FOR_TARGET?
|
||||||
|
CC_FOR_TARGET:=$(CC)
|
||||||
|
CFLAGS:=@CFLAGS@
|
||||||
|
CXXFLAGS:=@CXXFLAGS@
|
||||||
|
|
||||||
|
# For linking mount, etc. crt0.o isn't accessable in a fresh build.
|
||||||
|
EXE_LDFLAGS:=@EXE_LDFLAGS@
|
||||||
|
|
||||||
|
AR:=@AR@
|
||||||
|
AR_FLAGS:=qv
|
||||||
|
RANLIB:=@RANLIB@
|
||||||
|
LD:=@LD@
|
||||||
|
DLLTOOL:=@DLLTOOL@
|
||||||
|
WINDRES:=@WINDRES@
|
||||||
|
AS:=@AS@
|
||||||
|
|
||||||
|
#
|
||||||
|
# Include common definitions for winsup directory
|
||||||
|
#
|
||||||
|
include $(srcdir)/../Makefile.common
|
||||||
|
|
||||||
|
INSTALL_DATA:=$(SHELL) $(updir1)/install-sh -c
|
||||||
|
|
||||||
|
COMPILE_CC+=-D__INSIDE_CYGWIN__
|
||||||
|
|
||||||
|
@SET_MAKE@
|
||||||
|
|
||||||
|
# Setup the testing framework, if you have one
|
||||||
|
EXPECT = `if [ -f $${rootme}/../../expect/expect$(EXEEXT) ] ; then \
|
||||||
|
echo $${rootme}/../../expect/expect$(EXEEXT) ; \
|
||||||
|
else echo expect ; fi`
|
||||||
|
|
||||||
|
RUNTEST = `if [ -f $${srcdir}/../dejagnu/runtest ] ; then \
|
||||||
|
echo $${srcdir}/../dejagnu/runtest ; \
|
||||||
|
else echo runtest; fi`
|
||||||
|
RUNTESTFLAGS =
|
||||||
|
|
||||||
|
ifdef MT_SAFE
|
||||||
|
MT_SAFE_HEADERS:=thread.h
|
||||||
|
MT_SAFE_OBJECTS:=pthread.o thread.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Parameters used in building the cygwin.dll.
|
||||||
|
# We build as new-cygwin.dll and rename at install time to overcome
|
||||||
|
# native rebuilding issues (we don't want the build tools to see a partially
|
||||||
|
# built cygwin.dll and attempt to use it instead of the old one).
|
||||||
|
|
||||||
|
DLL_NAME:=cygwin1.dll
|
||||||
|
LIB_NAME:=libcygwin.a
|
||||||
|
DEF_FILE:=cygwin.def
|
||||||
|
DLL_ENTRY:=@DLL_ENTRY@
|
||||||
|
|
||||||
|
LIBGMON_A:=libgmon.a
|
||||||
|
GMON_START:=gcrt0.o
|
||||||
|
|
||||||
|
# Some things want these from libc, but they have their own static
|
||||||
|
# data which apps can get to, which is a pain in the dll, so we
|
||||||
|
# include them directly into the library.
|
||||||
|
|
||||||
|
LIBCOS:=libccrt0.o libcmain.o getopt.o dll_entry.o dll_main.o
|
||||||
|
|
||||||
|
# Build all source files in the config directory
|
||||||
|
|
||||||
|
EXTRA_DLL_OFILES:=${addsuffix .o,${basename ${notdir ${wildcard $(CONFIG_DIR)/*.c}}}}
|
||||||
|
|
||||||
|
EXTRA_OFILES=$(bupdir1)/libiberty/random.o $(bupdir1)/libiberty/strsignal.o
|
||||||
|
|
||||||
|
DLL_IMPORTS:=$(w32api_lib)/libkernel32.a $(w32api_lib)/libadvapi32.a
|
||||||
|
|
||||||
|
DLL_OFILES:=assert.o dcrt0.o debug.o delqueue.o dir.o dlfcn.o dll_init.o \
|
||||||
|
environ.o errno.o exceptions.o exec.o external.o fcntl.o fhandler.o \
|
||||||
|
fhandler_console.o fhandler_serial.o fhandler_termios.o fhandler_tty.o \
|
||||||
|
fhandler_windows.o fhandler_raw.o fhandler_floppy.o fhandler_tape.o fhandler_zero.o \
|
||||||
|
fork.o glob.o grp.o heap.o hinfo.o init.o ioctl.o localtime.o malloc.o \
|
||||||
|
mmap.o net.o ntea.o passwd.o path.o pinfo.o pipe.o regexp.o regerror.o \
|
||||||
|
regsub.o registry.o resource.o scandir.o security.o select.o shared.o \
|
||||||
|
signal.o sigproc.o smallprint.o spawn.o strace.o strsep.o sync.o \
|
||||||
|
syscalls.o sysconf.o syslog.o termios.o times.o tty.o uinfo.o uname.o \
|
||||||
|
wait.o window.o \
|
||||||
|
$(EXTRA_DLL_OFILES) $(EXTRA_OFILES) $(MT_SAFE_OBJECTS)
|
||||||
|
|
||||||
|
GMON_OFILES:= gmon.o mcount.o profil.o
|
||||||
|
|
||||||
|
LD_STUFF=--dll $(DLL_OFILES) version.o winver.o $(DLL_IMPORTS) $(LIBM) $(LIBC) $(LIBGCC) -e $(DLL_ENTRY) --image-base=0x61000000
|
||||||
|
|
||||||
|
.PHONY: all force dll_ofiles install
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
.SUFFIXES: .c .cc .def .a .o
|
||||||
|
|
||||||
|
all: new-$(DLL_NAME) $(LIBGMON_A) $(LIB_NAME) cygrun.exe force
|
||||||
|
|
||||||
|
force:
|
||||||
|
|
||||||
|
install: all
|
||||||
|
$(INSTALL_DATA) new-$(DLL_NAME) $(bindir)/$(DLL_NAME) ; \
|
||||||
|
$(INSTALL_DATA) $(LIB_NAME) $(tooldir)/lib/$(LIB_NAME); \
|
||||||
|
cd $(srcdir); \
|
||||||
|
for sub in `find include -name '[a-z]*' -type d -print | sort`; do \
|
||||||
|
for i in $$sub/*.h ; do \
|
||||||
|
$(INSTALL_DATA) $$i $(tooldir)/$$sub/`basename $$i` ; \
|
||||||
|
done ; \
|
||||||
|
done
|
||||||
|
|
||||||
|
clean:
|
||||||
|
-rm -f *.o *.dll *.a *.exp junk *.base version.cc regexp/*.o winver_stamp
|
||||||
|
|
||||||
|
maintainer-clean realclean: clean
|
||||||
|
@echo "This command is intended for maintainers to use;"
|
||||||
|
@echo "it deletes files that may require special tools to rebuild."
|
||||||
|
-rm -fr configure
|
||||||
|
|
||||||
|
# Rule to build libcygwin.a
|
||||||
|
|
||||||
|
$(LIB_NAME): $(DEF_FILE) $(LIBCOS)
|
||||||
|
$(DLLTOOL) --as=$(AS) --dllname $(DLL_NAME) --def $(DEF_FILE) --output-lib temp.a
|
||||||
|
$(AR) rcv temp.a $(LIBCOS)
|
||||||
|
mv temp.a $(LIB_NAME)
|
||||||
|
|
||||||
|
# Rule to make stub library used by "make check"
|
||||||
|
|
||||||
|
new-$(LIB_NAME): $(DEF_FILE) $(LIBCOS)
|
||||||
|
$(DLLTOOL) --as=$(AS) --dllname new-$(DLL_NAME) --def $(DEF_FILE) --output-lib temp.a
|
||||||
|
$(AR) rcv temp.a $(LIBCOS)
|
||||||
|
mv temp.a new-$(LIB_NAME)
|
||||||
|
|
||||||
|
# Rule to build cygwin.dll
|
||||||
|
|
||||||
|
new-$(DLL_NAME): $(DLL_OFILES) $(DEF_FILE) $(DLL_IMPORTS) $(LIBC) $(LIBM) Makefile winver_stamp
|
||||||
|
$(LD) -shared -o $@ -e $(DLL_ENTRY) cygwin.def $(DLL_OFILES) version.o \
|
||||||
|
winver.o $(DLL_IMPORTS) $(LIBM) $(LIBGCC) $(MALLOC_OBJ) $(LIBC) $(LIBGCC)
|
||||||
|
|
||||||
|
dll_ofiles: $(DLL_OFILES)
|
||||||
|
|
||||||
|
$(LIBGMON_A): $(GMON_OFILES) $(GMON_START)
|
||||||
|
$(AR) rcv $(LIBGMON_A) $(GMON_OFILES)
|
||||||
|
|
||||||
|
version.cc winver.o: winver_stamp
|
||||||
|
@ :
|
||||||
|
|
||||||
|
winver_stamp: mkvers.sh include/cygwin/version.h winver.rc $(DLL_OFILES)
|
||||||
|
@echo "Making version.o and winver.o";\
|
||||||
|
$(SHELL) ${word 1,$^} ${word 2,$^} ${word 3,$^} $(WINDRES); \
|
||||||
|
touch $@; \
|
||||||
|
$(COMPILE_CXX) -o version.o version.cc
|
||||||
|
|
||||||
|
cygrun.exe : $(srcdir)/cygrun.c $(DLL_IMPORTS) $(w32api_lib)/libuser32.a \
|
||||||
|
$(w32api_lib)/libshell32.a
|
||||||
|
$(CC) -o $@ $^
|
||||||
|
|
||||||
|
#
|
||||||
|
|
||||||
|
# These targets are for the dejagnu testsuites. The file site.exp
|
||||||
|
# contains global variables that all the testsuites will use.
|
||||||
|
|
||||||
|
# Set to $(target_alias)/ for cross.
|
||||||
|
target_subdir = @target_subdir@
|
||||||
|
|
||||||
|
site.exp: ./config.status Makefile
|
||||||
|
@echo "Making a new config file..."
|
||||||
|
-@rm -f ./tmp?
|
||||||
|
@touch site.exp
|
||||||
|
-@mv site.exp site.bak
|
||||||
|
@echo "## these variables are automatically generated by make ##" > ./tmp0
|
||||||
|
@echo "# Do not edit here. If you wish to override these values" >> ./tmp0
|
||||||
|
@echo "# add them to the last section" >> ./tmp0
|
||||||
|
@echo "set rootme \"`pwd`\"" >> ./tmp0
|
||||||
|
@echo "set srcdir \"`cd ${srcdir}; pwd`\"" >> ./tmp0
|
||||||
|
@echo "set host_triplet $(host_canonical)" >> ./tmp0
|
||||||
|
@echo "set build_triplet $(build_canonical)" >> ./tmp0
|
||||||
|
@echo "set target_triplet $(target)" >> ./tmp0
|
||||||
|
@echo "set target_alias $(target_alias)" >> ./tmp0
|
||||||
|
@echo "set CC \"$(CC)\"" >> ./tmp0
|
||||||
|
# CFLAGS is set even though it's empty to show we reserve the right to set it.
|
||||||
|
@echo "set CFLAGS \"\"" >> ./tmp0
|
||||||
|
echo "set tmpdir $(objdir)/testsuite" >> ./tmp0
|
||||||
|
@echo "set srcdir \"\$${srcdir}/testsuite\"" >> ./tmp0
|
||||||
|
@echo "## All variables above are generated by configure. Do Not Edit ##" >> ./tmp0
|
||||||
|
@cat ./tmp0 > site.exp
|
||||||
|
@cat site.bak | sed \
|
||||||
|
-e '1,/^## All variables above are.*##/ d' >> site.exp
|
||||||
|
-@rm -f ./tmp?
|
||||||
|
|
||||||
|
testsuite/site.exp: site.exp
|
||||||
|
if [ -d testsuite ]; then \
|
||||||
|
true; \
|
||||||
|
else \
|
||||||
|
mkdir testsuite; \
|
||||||
|
fi
|
||||||
|
rm -rf testsuite/site.exp
|
||||||
|
cp site.exp testsuite/site.exp
|
||||||
|
|
||||||
|
# Note: we set the PATH so that we can pick up new-cygwin1.dll
|
||||||
|
|
||||||
|
check: testsuite/site.exp
|
||||||
|
-rootme=`pwd`; export rootme; \
|
||||||
|
srcdir=`cd ${srcdir}; pwd` ; export srcdir ; \
|
||||||
|
cd testsuite; \
|
||||||
|
EXPECT=${EXPECT} ; export EXPECT ; \
|
||||||
|
if [ -f $${rootme}/../expect/expect ] ; then \
|
||||||
|
TCL_LIBRARY=`cd .. ; cd ${srcdir}/../tcl/library ; pwd` ; \
|
||||||
|
export TCL_LIBRARY ; fi ; \
|
||||||
|
PATH=$${rootme}:$${PATH} ;\
|
||||||
|
$(RUNTEST) --tool winsup $(RUNTESTFLAGS)
|
||||||
|
|
||||||
|
#
|
||||||
|
|
||||||
|
Makefile: cygwin.din
|
||||||
|
|
||||||
|
# .h file dependencies
|
||||||
|
# This may be overkill, but it's better than the previous situation.
|
||||||
|
# As files/dependencies are added and removed from Cygwin, please keep
|
||||||
|
# this list up to date.
|
||||||
|
|
||||||
|
WINSUP_H:=winsup.h fhandler.h path.h shared.h \
|
||||||
|
sigproc.h include/cygwin/version.h \
|
||||||
|
$(MT_SAFE_HEADERS)
|
||||||
|
|
||||||
|
winsup.h: config.h
|
||||||
|
assert.o: $(WINSUP_H)
|
||||||
|
dcrt0.o: $(WINSUP_H) include/exceptions.h include/glob.h dll_init.h autoload.h
|
||||||
|
debug.o: $(WINSUP_H) debug.h sync.h
|
||||||
|
delqueue.o: $(WINSUP_H)
|
||||||
|
dir.o: $(WINSUP_H)
|
||||||
|
dlfcn.o: $(WINSUP_H) dll_init.h
|
||||||
|
dll_entry.o: $(WINSUP_H) include/cygwin/cygwin_dll.h
|
||||||
|
dll_init.o: $(WINSUP_H) include/exceptions.h dll_init.h
|
||||||
|
dll_main.o:
|
||||||
|
environ.o: $(WINSUP_H)
|
||||||
|
errno.o: $(WINSUP_H)
|
||||||
|
exceptions.o: $(WINSUP_H) include/exceptions.h sync.h autoload.h
|
||||||
|
exec.o: $(WINSUP_H)
|
||||||
|
external.o: $(WINSUP_H) external.h
|
||||||
|
fcntl.o: $(WINSUP_H)
|
||||||
|
fhandler.o: $(WINSUP_H)
|
||||||
|
fhandler_console.o: $(WINSUP_H)
|
||||||
|
fhandler_serial.o: $(WINSUP_H)
|
||||||
|
fhandler_termios.o: $(WINSUP_H)
|
||||||
|
fhandler_tty.o: $(WINSUP_H)
|
||||||
|
fhandler_windows.o: $(WINSUP_H)
|
||||||
|
fhandler_raw.o: $(WINSUP_H)
|
||||||
|
fhandler_floppy.o: $(WINSUP_H)
|
||||||
|
fhandler_tape.o: $(WINSUP_H)
|
||||||
|
fhandler_zero.o: $(WINSUP_H)
|
||||||
|
fork.o: $(WINSUP_H) dll_init.h
|
||||||
|
glob.o: include/glob.h
|
||||||
|
gmon.o: profil.h gmon.h
|
||||||
|
grp.o: $(WINSUP_H)
|
||||||
|
heap.o: $(WINSUP_H)
|
||||||
|
hinfo.o: $(WINSUP_H)
|
||||||
|
init.o: $(WINSUP_H)
|
||||||
|
ioctl.o: $(WINSUP_H)
|
||||||
|
libccrt0.o: $(WINSUP_H)
|
||||||
|
libcmain.o: $(WINSUP_H)
|
||||||
|
localtime.o: tz_posixrules.h
|
||||||
|
malloc.o: $(WINSUP_H)
|
||||||
|
mcount.o: gmon.h
|
||||||
|
mmap.o: $(WINSUP_H)
|
||||||
|
net.o: $(WINSUP_H) autoload.h
|
||||||
|
ntea.o:
|
||||||
|
passwd.o: $(WINSUP_H)
|
||||||
|
path.o: $(WINSUP_H)
|
||||||
|
pinfo.o: $(WINSUP_H)
|
||||||
|
pipe.o: $(WINSUP_H)
|
||||||
|
profile.o: profil.h
|
||||||
|
pthread.o: $(WINSUP_H)
|
||||||
|
registry.o: $(WINSUP_H)
|
||||||
|
resource.o: $(WINSUP_H)
|
||||||
|
scandir.o:
|
||||||
|
security.o: $(WINSUP_H)
|
||||||
|
select.o: $(WINSUP_H) select.h
|
||||||
|
shared.o: $(WINSUP_H)
|
||||||
|
signal.o: $(WINSUP_H)
|
||||||
|
sigproc.o: $(WINSUP_H) sync.h
|
||||||
|
smallprint.o: $(WINSUP_H)
|
||||||
|
spawn.o: $(WINSUP_H)
|
||||||
|
strace.o: $(WINSUP_H)
|
||||||
|
strsep.o:
|
||||||
|
sync.o: $(WINSUP_H) sync.h
|
||||||
|
syscalls.o: $(WINSUP_H)
|
||||||
|
sysconf.o: $(WINSUP_H)
|
||||||
|
syslog.o: $(WINSUP_H)
|
||||||
|
termios.o: $(WINSUP_H)
|
||||||
|
test.o: $(WINSUP_H)
|
||||||
|
times.o: $(WINSUP_H)
|
||||||
|
tty.o: $(WINSUP_H)
|
||||||
|
uinfo.o: $(WINSUP_H)
|
||||||
|
uname.o: $(WINSUP_H)
|
||||||
|
wait.o: $(WINSUP_H)
|
||||||
|
window.o: $(WINSUP_H)
|
||||||
|
thread.o: $(WINSUP_H)
|
||||||
|
|
129
winsup/cygwin/ROADMAP
Normal file
129
winsup/cygwin/ROADMAP
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
|
||||||
|
WINSUP ROADMAP
|
||||||
|
|
||||||
|
The purpose of this document is to give the briefest overview of how
|
||||||
|
the various parts of cygwin work together and where everything can be
|
||||||
|
found. The intended audience is people developing the cygwin dll
|
||||||
|
itself. Comments to dj@cygnus.com.
|
||||||
|
|
||||||
|
=== cygwin1.dll source files
|
||||||
|
|
||||||
|
- overhead
|
||||||
|
.h winsup autoload debug external shared sync
|
||||||
|
.cc assert dcrt0 debug external init ntea registry security
|
||||||
|
shared smallprint strace sync
|
||||||
|
.din cygwin
|
||||||
|
.rc winver
|
||||||
|
.sgml external shared
|
||||||
|
|
||||||
|
- processes
|
||||||
|
.h sigproc
|
||||||
|
.cc exec fork pinfo resource signal sigproc spawn wait
|
||||||
|
|
||||||
|
- signals
|
||||||
|
.cc exceptions window
|
||||||
|
|
||||||
|
- files and I/O
|
||||||
|
.h delqueue fhandler path select
|
||||||
|
.cc delqueue dir fhandler* hinfo path pipe select tty
|
||||||
|
.sgml hinfo path
|
||||||
|
|
||||||
|
- common unix functions
|
||||||
|
.h dll_init tz_posixrules
|
||||||
|
.cc dlfcn dll_init environ errno fcntl flog grp ioctl localtime
|
||||||
|
malloc passwd scandir strsep syscalls sysconf syslog termios
|
||||||
|
.c longjmp setjmp
|
||||||
|
.sgml dll_init
|
||||||
|
|
||||||
|
- unix emulation
|
||||||
|
.cc heap mmap net times unifo uname
|
||||||
|
|
||||||
|
|
||||||
|
--- if MT_SAFE
|
||||||
|
.h thread
|
||||||
|
.cc pthread thread
|
||||||
|
|
||||||
|
--- from other places
|
||||||
|
regex/*
|
||||||
|
../libiberty/{random,strsignal}
|
||||||
|
../newlib/* (libc)
|
||||||
|
|
||||||
|
=== libcygwin.a source files
|
||||||
|
|
||||||
|
libccrt0.cc
|
||||||
|
libcmain.cc
|
||||||
|
dll_entry.cc
|
||||||
|
dll_main.cc
|
||||||
|
getopt.c
|
||||||
|
|
||||||
|
=== gmon (profiling, -pg)
|
||||||
|
|
||||||
|
gcrt0.c
|
||||||
|
gmon.c gmon.h
|
||||||
|
mcount.c
|
||||||
|
profil.c profil.h
|
||||||
|
|
||||||
|
=== entry points
|
||||||
|
|
||||||
|
- normal cygwin program
|
||||||
|
|
||||||
|
newlib/libc/sys/cygwin/crt0.c has mainCRTStartup() and calls cygwin_crt0()
|
||||||
|
|
||||||
|
libccrt0.cc has cygwin_crt0() and calls dll_crt0()
|
||||||
|
|
||||||
|
dcrt0.cc - has dll_crt0()
|
||||||
|
|
||||||
|
Note: dll_init.cc has nothing to do with initializing the cygwin dll.
|
||||||
|
It initializes the dlls you have dl_open'd.
|
||||||
|
|
||||||
|
- cygwin-built dll
|
||||||
|
|
||||||
|
dll_entry.cc - has a macro for wrapping your dll startup function
|
||||||
|
(equivalent of DllMain()) in such a way that you get your
|
||||||
|
cygwin environment set up automatically when your dll is
|
||||||
|
loaded.
|
||||||
|
|
||||||
|
dll_main.cc - has empty DllMain() in case you don't have your own
|
||||||
|
|
||||||
|
- manually loading cygwin1.dll
|
||||||
|
|
||||||
|
init.cc - has dll_entry() which is called by the OS when the dll is
|
||||||
|
loaded. It doesn't do much except note if you linked
|
||||||
|
cygwin1.dll or are manually loading it.
|
||||||
|
|
||||||
|
=== About "fhandlers"
|
||||||
|
|
||||||
|
An fhandler is a file type handler. This is where the unix device
|
||||||
|
emulation happens.
|
||||||
|
|
||||||
|
hinfo.cc maps posix file descriptors to a table of file handlers (type
|
||||||
|
fhandler) in the dll. It's mostly concerned with managing the table
|
||||||
|
of descriptors (open, dup, fork, select). Most of the posix I/O
|
||||||
|
system calls (syscalls.cc) use the hinfo table to call the right
|
||||||
|
fhandler directly.
|
||||||
|
|
||||||
|
fhandler.cc is the base class; specific types are derived as
|
||||||
|
appropriate (see fhandler.h). hinfo.cc is in charge of selecting and
|
||||||
|
creating a suitable fhandler when you open a file. path.cc handles
|
||||||
|
emulated files in /dev (like /dev/null) by returning an FH_* value
|
||||||
|
from get_device_number (which hinfo.cc calls in hinfo::build_fhandler).
|
||||||
|
|
||||||
|
Note: if you're looking for read() and write(), they call _read() and
|
||||||
|
_write() in syscalls.cc. The non-underscored ones are in
|
||||||
|
newlib/libc/syscalls and just call the underscored ones.
|
||||||
|
|
||||||
|
=== How "fork" works
|
||||||
|
|
||||||
|
It all starts in fork() in fork.cc.
|
||||||
|
|
||||||
|
Set up a pid in the shared memory area for the new child. Use
|
||||||
|
setjmp() to capture state. First time (parent), set up some stuff and
|
||||||
|
use CreateProcess to run a second copy of the same executable. The
|
||||||
|
second copy will note in the shared memory area that it's a fork, and
|
||||||
|
do the longjmp. They sync up and the parent copies all it's program
|
||||||
|
memory to the child's address space. There's also code to reload
|
||||||
|
dlls, map shared memory and mmap'd files, etc.
|
||||||
|
|
||||||
|
Handling the special startup for the child is done in dcrt0.cc in many
|
||||||
|
places. This case is triggered by a special StartupInfo structure
|
||||||
|
that's passed from the parent to the child in CreateProcessA.
|
15
winsup/cygwin/acconfig.h
Normal file
15
winsup/cygwin/acconfig.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/* Define if DEBUGGING support is requested. */
|
||||||
|
#undef DEBUGGING
|
||||||
|
|
||||||
|
/* Define if building "extra" thread-safe Cygwin DLL. */
|
||||||
|
#undef _CYG_THREAD_FAILSAFE
|
||||||
|
|
||||||
|
/* Define if GCC supports builtin memset. */
|
||||||
|
#undef HAVE_BUILTIN_MEMSET
|
||||||
|
|
||||||
|
/* Define if building thread-safe Cygwin DLL. */
|
||||||
|
#undef _MT_SAFE
|
||||||
|
|
||||||
|
/* Define if strace log output has date/time stamp. */
|
||||||
|
#undef STRACE_HHMMSS
|
||||||
|
|
59
winsup/cygwin/ansi.sgml
Normal file
59
winsup/cygwin/ansi.sgml
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<sect1 id="std-ansi">
|
||||||
|
<title>Compatibility with ANSI</title>
|
||||||
|
|
||||||
|
<para>The following functions are compatible with ANSI:</para>
|
||||||
|
|
||||||
|
<sect2><title>stdio</title><para>
|
||||||
|
|
||||||
|
clearerr, fclose, feof, ferror, fflush, fgetc, fgetpos, fgets, fopen,
|
||||||
|
fprintf, fputc, fputs, fread, freopen, fscanf, fseek, fsetpos, ftell,
|
||||||
|
fwrite, getc, getchar, gets, perror, printf, putc, putchar, puts,
|
||||||
|
remove, rename, rewind, scanf, setbuf, setvbuf, sprintf, sscanf,
|
||||||
|
tmpfile, tmpnam, vfprintf, ungetc, vprintf, vsprintf,
|
||||||
|
|
||||||
|
</para></sect2>
|
||||||
|
<sect2><title>string</title><para>
|
||||||
|
|
||||||
|
memchr, memcmp, memcpy, memmove, memset, strcat, strchr, strcmp,
|
||||||
|
strcoll, strcpy, strcspn, strerror, strlen, strncat, strncmp, strncpy,
|
||||||
|
strpbrk, strrchr, strspn, strstr, strtok, strxfrm
|
||||||
|
|
||||||
|
</para></sect2>
|
||||||
|
<sect2><title>stdlib</title><para>
|
||||||
|
|
||||||
|
abort, abs, assert, atexit, atof, atoi, atol, bsearch, calloc, div,
|
||||||
|
exit, free, getenv, labs, ldiv, longjmp, malloc, mblen, mbstowcs,
|
||||||
|
mbtowc, qsort, rand, realloc, setjmp, srand, strtod, strtol, strtoul,
|
||||||
|
system, wcstombs, wctomb
|
||||||
|
|
||||||
|
</para></sect2>
|
||||||
|
<sect2><title>time</title><para>
|
||||||
|
|
||||||
|
asctime, gmtime, localtime, time, clock, ctime, difftime, mktime,
|
||||||
|
strftime
|
||||||
|
|
||||||
|
</para></sect2>
|
||||||
|
<sect2><title>signals</title><para>
|
||||||
|
|
||||||
|
raise, signal
|
||||||
|
|
||||||
|
</para></sect2>
|
||||||
|
<sect2><title>ctype</title><para>
|
||||||
|
|
||||||
|
isalnum, isalpha, iscntrl, isdigit, isgraph, islower, isprint,
|
||||||
|
ispunct, isspace, isupper, isxdigit, tolower, toupper
|
||||||
|
|
||||||
|
</para></sect2>
|
||||||
|
<sect2><title>math</title><para>
|
||||||
|
|
||||||
|
acos, asin, atan, atan2, ceil, cos, cosh, exp, fabs, floor, fmod,
|
||||||
|
frexp, ldexp, log, log10, modf, pow, sin, sinh, sqrt, tan, tanh
|
||||||
|
|
||||||
|
</para></sect2>
|
||||||
|
<sect2><title>misc</title><para>
|
||||||
|
|
||||||
|
localeconv, setlocale, va_arg, va_end, va_start
|
||||||
|
|
||||||
|
</para></sect2>
|
||||||
|
|
||||||
|
</sect1>
|
50
winsup/cygwin/assert.cc
Normal file
50
winsup/cygwin/assert.cc
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/* assert.cc: Handle the assert macro for WIN32.
|
||||||
|
|
||||||
|
Copyright 1997, 1998, 2000 Cygnus Solutions.
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include "winsup.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* This function is called when the assert macro fails. This will
|
||||||
|
override the function of the same name in newlib. */
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
__assert (const char *file, int line, const char *failedexpr)
|
||||||
|
{
|
||||||
|
HANDLE h;
|
||||||
|
|
||||||
|
/* If we don't have a console in a Windows program, then bring up a
|
||||||
|
message box for the assertion failure. */
|
||||||
|
|
||||||
|
h = CreateFileA ("CONOUT$", GENERIC_WRITE, FILE_SHARE_WRITE, &sec_none_nih,
|
||||||
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
if (h == INVALID_HANDLE_VALUE || h == 0)
|
||||||
|
{
|
||||||
|
char *buf;
|
||||||
|
|
||||||
|
buf = (char *) alloca (100 + strlen (failedexpr));
|
||||||
|
siprintf (buf, "Failed assertion\n\t%s\nat line %d of file %s",
|
||||||
|
failedexpr, line, file);
|
||||||
|
MessageBox (NULL, buf, NULL, MB_OK | MB_ICONERROR | MB_TASKMODAL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CloseHandle (h);
|
||||||
|
(void) fiprintf (stderr,
|
||||||
|
"assertion \"%s\" failed: file \"%s\", line %d\n",
|
||||||
|
failedexpr, file, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
38
winsup/cygwin/config.h.in
Normal file
38
winsup/cygwin/config.h.in
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/* config.h.in. Generated automatically from configure.in by autoheader. */
|
||||||
|
|
||||||
|
/* Define if using alloca.c. */
|
||||||
|
#undef C_ALLOCA
|
||||||
|
|
||||||
|
/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
|
||||||
|
This function is required for alloca.c support on those systems. */
|
||||||
|
#undef CRAY_STACKSEG_END
|
||||||
|
|
||||||
|
/* Define if you have alloca, as a function or macro. */
|
||||||
|
#undef HAVE_ALLOCA
|
||||||
|
|
||||||
|
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
|
||||||
|
#undef HAVE_ALLOCA_H
|
||||||
|
|
||||||
|
/* If using the C implementation of alloca, define if you know the
|
||||||
|
direction of stack growth for your system; otherwise it will be
|
||||||
|
automatically deduced at run-time.
|
||||||
|
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||||
|
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||||
|
STACK_DIRECTION = 0 => direction of growth unknown
|
||||||
|
*/
|
||||||
|
#undef STACK_DIRECTION
|
||||||
|
|
||||||
|
/* Define if DEBUGGING support is requested. */
|
||||||
|
#undef DEBUGGING
|
||||||
|
|
||||||
|
/* Define if building "extra" thread-safe Cygwin DLL. */
|
||||||
|
#undef _CYG_THREAD_FAILSAFE
|
||||||
|
|
||||||
|
/* Define if GCC supports builtin memset. */
|
||||||
|
#undef HAVE_BUILTIN_MEMSET
|
||||||
|
|
||||||
|
/* Define if building thread-safe Cygwin DLL. */
|
||||||
|
#undef _MT_SAFE
|
||||||
|
|
||||||
|
/* Define if strace log output has date/time stamp. */
|
||||||
|
#undef STRACE_HHMMSS
|
51
winsup/cygwin/config/i386/longjmp.c
Normal file
51
winsup/cygwin/config/i386/longjmp.c
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/* longjmp.c
|
||||||
|
|
||||||
|
Copyright 1996, 1998 Cygnus Solutions.
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#ifdef __i386__
|
||||||
|
#if 1
|
||||||
|
asm (" .globl _longjmp \n"
|
||||||
|
"_longjmp: \n"
|
||||||
|
" pushl %ebp \n"
|
||||||
|
" movl %esp,%ebp \n"
|
||||||
|
" movl 8(%ebp),%edi \n"
|
||||||
|
" movl 12(%ebp),%eax \n"
|
||||||
|
" testl %eax,%eax \n"
|
||||||
|
" jne 0f \n"
|
||||||
|
" incl %eax \n"
|
||||||
|
"0: \n"
|
||||||
|
" movl %eax,0(%edi) \n"
|
||||||
|
" movl 24(%edi),%ebp \n"
|
||||||
|
" pushfl \n"
|
||||||
|
" popl %ebx \n"
|
||||||
|
" movw 42(%edi),%ax \n"
|
||||||
|
" movw %ax,%ss \n"
|
||||||
|
" movl 28(%edi),%esp \n"
|
||||||
|
" pushl 32(%edi) \n"
|
||||||
|
" pushl %ebx \n"
|
||||||
|
" movw 36(%edi),%ax \n"
|
||||||
|
" movw %ax,%es \n"
|
||||||
|
#if 0
|
||||||
|
/* fs is a system register in windows; don't muck with it */
|
||||||
|
" movw 38(%edi),%ax \n"
|
||||||
|
" movw %ax,%fs \n"
|
||||||
|
#endif
|
||||||
|
" movw 40(%edi),%ax \n"
|
||||||
|
" movw %ax,%gs \n"
|
||||||
|
" movl 0(%edi),%eax \n"
|
||||||
|
" movl 4(%edi),%ebx \n"
|
||||||
|
" movl 8(%edi),%ecx \n"
|
||||||
|
" movl 12(%edi),%edx \n"
|
||||||
|
" movl 16(%edi),%esi \n"
|
||||||
|
" movl 20(%edi),%edi \n"
|
||||||
|
" popfl \n"
|
||||||
|
" ret \n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __i386__ */
|
17
winsup/cygwin/config/i386/makefrag
Normal file
17
winsup/cygwin/config/i386/makefrag
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# makefrag: included by the main Cygwin Makefile.in
|
||||||
|
|
||||||
|
# Copyright 1996, 1998 Cygnus Solutions.
|
||||||
|
|
||||||
|
# This file is part of Cygwin.
|
||||||
|
|
||||||
|
# This software is a copyrighted work licensed under the terms of the
|
||||||
|
# Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
# details.
|
||||||
|
|
||||||
|
EXTRA_DLL_OFILES=setjmp.o longjmp.o
|
||||||
|
|
||||||
|
setjmp.o:config/i386/setjmp.c
|
||||||
|
$(CC) -c $(ALL_CFLAGS) $<
|
||||||
|
|
||||||
|
longjmp.o:config/i386/longjmp.c
|
||||||
|
$(CC) -c $(ALL_CFLAGS) $<
|
58
winsup/cygwin/config/i386/profile.h
Normal file
58
winsup/cygwin/config/i386/profile.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/* $NetBSD: profile.h,v 1.6 1995/03/28 18:17:08 jtc Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @(#)profile.h 8.1 (Berkeley) 6/11/93
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _MCOUNT_DECL static inline void _mcount
|
||||||
|
|
||||||
|
#define MCOUNT \
|
||||||
|
void \
|
||||||
|
mcount() \
|
||||||
|
{ \
|
||||||
|
int selfpc, frompcindex; \
|
||||||
|
/* \
|
||||||
|
* find the return address for mcount, \
|
||||||
|
* and the return address for mcount's caller. \
|
||||||
|
* \
|
||||||
|
* selfpc = pc pushed by mcount call \
|
||||||
|
*/ \
|
||||||
|
__asm("movl 4(%%ebp),%0" : "=r" (selfpc)); \
|
||||||
|
/* \
|
||||||
|
* frompcindex = pc pushed by call into self. \
|
||||||
|
*/ \
|
||||||
|
__asm("movl (%%ebp),%0;movl 4(%0),%0" : "=r" (frompcindex)); \
|
||||||
|
_mcount(frompcindex, selfpc); \
|
||||||
|
}
|
||||||
|
|
48
winsup/cygwin/config/i386/setjmp.c
Normal file
48
winsup/cygwin/config/i386/setjmp.c
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/* setjmp.c
|
||||||
|
|
||||||
|
Copyright 1996, 1998 Cygnus Solutions.
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#ifdef __i386__
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
asm(" .globl _setjmp \n"
|
||||||
|
"_setjmp: \n"
|
||||||
|
" pushl %ebp \n"
|
||||||
|
" movl %esp,%ebp \n"
|
||||||
|
" pushl %edi \n"
|
||||||
|
" movl 8(%ebp),%edi \n"
|
||||||
|
" movl %eax,0(%edi) \n"
|
||||||
|
" movl %ebx,4(%edi) \n"
|
||||||
|
" movl %ecx,8(%edi) \n"
|
||||||
|
" movl %edx,12(%edi) \n"
|
||||||
|
" movl %esi,16(%edi) \n"
|
||||||
|
" movl -4(%ebp),%eax \n"
|
||||||
|
" movl %eax,20(%edi) \n"
|
||||||
|
" movl 0(%ebp),%eax \n"
|
||||||
|
" movl %eax,24(%edi) \n"
|
||||||
|
" movl %esp,%eax \n"
|
||||||
|
" addl $12,%eax \n"
|
||||||
|
" movl %eax,28(%edi) \n"
|
||||||
|
" movl 4(%ebp),%eax \n"
|
||||||
|
" movl %eax,32(%edi) \n"
|
||||||
|
" movw %es, %ax \n"
|
||||||
|
" movw %ax, 36(%edi) \n"
|
||||||
|
" movw %fs, %ax \n"
|
||||||
|
" movw %ax, 38(%edi) \n"
|
||||||
|
" movw %gs, %ax \n"
|
||||||
|
" movw %ax, 40(%edi) \n"
|
||||||
|
" movw %ss, %ax \n"
|
||||||
|
" movw %ax, 42(%edi) \n"
|
||||||
|
" popl %edi \n"
|
||||||
|
" movl $0,%eax \n"
|
||||||
|
" leave \n"
|
||||||
|
" ret \n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __i386__ */
|
2335
winsup/cygwin/configure
vendored
Executable file
2335
winsup/cygwin/configure
vendored
Executable file
File diff suppressed because it is too large
Load Diff
229
winsup/cygwin/configure.in
Normal file
229
winsup/cygwin/configure.in
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
dnl Autoconf configure script for Cygwin.
|
||||||
|
dnl Copyright 1996, 1997, 1998, 2000 Cygnus Solutions.
|
||||||
|
dnl
|
||||||
|
dnl This file is part of Cygwin.
|
||||||
|
dnl
|
||||||
|
dnl This software is a copyrighted work licensed under the terms of the
|
||||||
|
dnl Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
dnl details.
|
||||||
|
dnl
|
||||||
|
dnl Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
|
AC_PREREQ(2.12)dnl
|
||||||
|
AC_INIT(init.cc)
|
||||||
|
AC_CONFIG_HEADER(config.h)
|
||||||
|
|
||||||
|
AC_PROG_INSTALL
|
||||||
|
|
||||||
|
dnl FIXME: We temporarily define our own version of AC_PROG_CC. This is
|
||||||
|
dnl copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS. We
|
||||||
|
dnl are probably using a cross compiler, which will not be able to fully
|
||||||
|
dnl link an executable. This should really be fixed in autoconf
|
||||||
|
dnl itself.
|
||||||
|
|
||||||
|
AC_DEFUN(LIB_AC_PROG_CC,
|
||||||
|
[AC_BEFORE([$0], [AC_PROG_CPP])dnl
|
||||||
|
AC_CHECK_TOOL(CC, gcc, gcc)
|
||||||
|
if test -z "$CC"; then
|
||||||
|
AC_CHECK_PROG(CC, cc, cc, , , /usr/ucb/cc)
|
||||||
|
test -z "$CC" && AC_MSG_ERROR([no acceptable cc found in \$PATH])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_PROG_CC_GNU
|
||||||
|
|
||||||
|
if test $ac_cv_prog_gcc = yes; then
|
||||||
|
GCC=yes
|
||||||
|
dnl Check whether -g works, even if CFLAGS is set, in case the package
|
||||||
|
dnl plays around with CFLAGS (such as to build both debugging and
|
||||||
|
dnl normal versions of a library), tasteless as that idea is.
|
||||||
|
ac_test_CFLAGS="${CFLAGS+set}"
|
||||||
|
ac_save_CFLAGS="$CFLAGS"
|
||||||
|
CFLAGS=
|
||||||
|
AC_PROG_CC_G
|
||||||
|
if test "$ac_test_CFLAGS" = set; then
|
||||||
|
CFLAGS="$ac_save_CFLAGS"
|
||||||
|
elif test $ac_cv_prog_cc_g = yes; then
|
||||||
|
CFLAGS="-g -O2"
|
||||||
|
else
|
||||||
|
CFLAGS="-O2"
|
||||||
|
fi
|
||||||
|
if test "$ac_test_CXXFLAGS" != set; then
|
||||||
|
CXXFLAGS='$(CFLAGS)'
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
GCC=
|
||||||
|
test "${CFLAGS+set}" = set || CFLAGS="-g"
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_CANONICAL_SYSTEM
|
||||||
|
|
||||||
|
LIB_AC_PROG_CC
|
||||||
|
|
||||||
|
AC_CHECK_TOOL(AR, ar, ar)
|
||||||
|
AC_SUBST(AR)
|
||||||
|
AC_CHECK_TOOL(AS, as, as)
|
||||||
|
AC_SUBST(AS)
|
||||||
|
AC_CHECK_TOOL(RANLIB, ranlib, ranlib)
|
||||||
|
AC_SUBST(RANLIB)
|
||||||
|
AC_CHECK_TOOL(LD, ld, ld)
|
||||||
|
AC_SUBST(LD)
|
||||||
|
AC_CHECK_TOOL(DLLTOOL, dlltool, dlltool)
|
||||||
|
AC_SUBST(DLLTOOL)
|
||||||
|
AC_CHECK_TOOL(WINDRES, windres, windres)
|
||||||
|
AC_SUBST(WINDRES)
|
||||||
|
|
||||||
|
AC_ALLOCA
|
||||||
|
AC_CONFIG_SUBDIRS(utils doc)
|
||||||
|
AC_PROG_MAKE_SET
|
||||||
|
|
||||||
|
dnl check whether gcc supports __builtin_memset.
|
||||||
|
# Test for builtin mem* functions.
|
||||||
|
AC_LANG_SAVE
|
||||||
|
AC_LANG_CPLUSPLUS
|
||||||
|
AC_TRY_COMPILE([
|
||||||
|
#include <string.h>
|
||||||
|
void foo(char *s, int c, size_t n)
|
||||||
|
{
|
||||||
|
__builtin_memset(s, c, n);
|
||||||
|
}
|
||||||
|
], [ ],
|
||||||
|
use_builtin_memset=yes, use_builtin_memset=no)
|
||||||
|
if test $use_builtin_memset = "yes"; then
|
||||||
|
AC_DEFINE(HAVE_BUILTIN_MEMSET)
|
||||||
|
fi
|
||||||
|
AC_LANG_RESTORE
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(strace-hhmmss,
|
||||||
|
[ --enable-strace-hhmmss strace log output has date/time stamp],
|
||||||
|
[case "${enableval}" in
|
||||||
|
yes)
|
||||||
|
AC_DEFINE(STRACE_HHMMSS)
|
||||||
|
;;
|
||||||
|
no)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
AC_MSG_ERROR(bad value ${enableval} given for enable-strace-hhmmss option)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl set default mt safeness and then process the options.
|
||||||
|
mt_safe_val=1
|
||||||
|
MT_SAFE=yes
|
||||||
|
PTH_ALLOW=''
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(threadsafe,
|
||||||
|
[ --enable-threadsafe=[runtime] Build a cygwin DLL which is thread safe],
|
||||||
|
[case "${enableval}" in
|
||||||
|
yes)
|
||||||
|
dnl default.
|
||||||
|
;;
|
||||||
|
runtime)
|
||||||
|
mt_safe_val=2
|
||||||
|
MT_SAFE=yes
|
||||||
|
;;
|
||||||
|
no)
|
||||||
|
mt_safe_val=0
|
||||||
|
MT_SAFE=no
|
||||||
|
PTH_ALLOW=';'
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(extra-threadsafe-checking,
|
||||||
|
[ --enable-extra-threadsafe-checking Build a cygwin DLL which is thread safe with extra consistency checking],
|
||||||
|
[case "${enableval}" in
|
||||||
|
yes)
|
||||||
|
mt_safe_val=1
|
||||||
|
MT_SAFE=yes
|
||||||
|
AC_DEFINE(_CYG_THREAD_FAILSAFE)
|
||||||
|
;;
|
||||||
|
no)
|
||||||
|
dnl Don't do anything here to avoid overriding --enable-threadsafe.
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
])
|
||||||
|
|
||||||
|
if test "$MT_SAFE" = "yes"; then
|
||||||
|
AC_DEFINE_UNQUOTED(_MT_SAFE,$mt_safe_val)
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl Makefile uses MT_SAFE, so we subst as well as defining it.
|
||||||
|
AC_SUBST(MT_SAFE)
|
||||||
|
AC_SUBST(PTH_ALLOW)
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(debugging,
|
||||||
|
[ --enable-debugging Build a cygwin DLL which has more consistency checking for debugging],
|
||||||
|
[case "${enableval}" in
|
||||||
|
yes) AC_DEFINE(DEBUGGING) ;;
|
||||||
|
no) ;;
|
||||||
|
esac
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl The only time we might want to transform the install names
|
||||||
|
dnl is for unix x cygwin. Otherwise we don't. For now we don't
|
||||||
|
dnl transform names.
|
||||||
|
|
||||||
|
dnl if test "x$cross_compiling" = "xno" -a ; then
|
||||||
|
dnl if test "x$program_transform_name" = "xs,x,x,"; then
|
||||||
|
dnl program_transform_name=""
|
||||||
|
dnl fi
|
||||||
|
dnl if test "x$program_transform_name" = "x"; then
|
||||||
|
dnl program_transform_name="s,^,$target_alias-,"
|
||||||
|
dnl else
|
||||||
|
dnl program_transform_name="$program_transform_name -e s,^,$target_alias-,"
|
||||||
|
dnl fi
|
||||||
|
dnl fi
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl If newlib is part of build tree, always set EXE_LDFLAGS to point to
|
||||||
|
dnl it; this is important in cases where the installed newlib is perhaps
|
||||||
|
dnl not compatible. Check and warn for installed newlib only if it's not
|
||||||
|
dnl part of the build tree.
|
||||||
|
dnl
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([if newlib is part of the build tree])
|
||||||
|
|
||||||
|
EXE_LDFLAGS=
|
||||||
|
if test -d ../newlib
|
||||||
|
then
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
EXE_LDFLAGS="-B../../newlib/ -B../"
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
fi
|
||||||
|
AC_SUBST(EXE_LDFLAGS)
|
||||||
|
|
||||||
|
if test x"$EXE_LDFLAGS" = x
|
||||||
|
then
|
||||||
|
AC_MSG_CHECKING([if installed newlib needed])
|
||||||
|
AC_TRY_LINK(,
|
||||||
|
[/* main already defined */]
|
||||||
|
,
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
,
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_MSG_WARN(newlib not found - utility .exe's may not link))
|
||||||
|
fi
|
||||||
|
AC_SUBST(EXE_LDFLAGS)
|
||||||
|
|
||||||
|
case "$target_cpu" in
|
||||||
|
i386|i486|i586|i686) DLL_ENTRY="_dll_entry@12"
|
||||||
|
DEF_DLL_ENTRY="dll_entry@12"
|
||||||
|
ALLOCA="_alloca"
|
||||||
|
CONFIG_DIR="i386" ;;
|
||||||
|
powerpc*) DLL_ENTRY="dll_entry"
|
||||||
|
DEF_DLL_ENTRY="dll_entry"
|
||||||
|
ALLOCA=" __allocate_stack"
|
||||||
|
CONFIG_DIR="ppc" ;;
|
||||||
|
*) AC_MSG_ERROR(Invalid target processor \"$target_cpu\") ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
AC_SUBST(DLL_ENTRY)
|
||||||
|
AC_SUBST(DEF_DLL_ENTRY)
|
||||||
|
AC_SUBST(ALLOCA)
|
||||||
|
AC_SUBST(CONFIG_DIR)
|
||||||
|
AC_OUTPUT(Makefile cygwin.def:cygwin.din)
|
||||||
|
|
1051
winsup/cygwin/cygwin.din
Normal file
1051
winsup/cygwin/cygwin.din
Normal file
File diff suppressed because it is too large
Load Diff
1063
winsup/cygwin/dcrt0.cc
Normal file
1063
winsup/cygwin/dcrt0.cc
Normal file
File diff suppressed because it is too large
Load Diff
326
winsup/cygwin/debug.cc
Normal file
326
winsup/cygwin/debug.cc
Normal file
@ -0,0 +1,326 @@
|
|||||||
|
/* debug.cc
|
||||||
|
|
||||||
|
Copyright 1998, 1999, 2000 Cygnus Solutions.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#define NO_DEBUG_DEFINES
|
||||||
|
#include "winsup.h"
|
||||||
|
#include "exceptions.h"
|
||||||
|
|
||||||
|
static muto NO_COPY *threadname_lock = NULL;
|
||||||
|
#define lock_threadname() \
|
||||||
|
do {if (threadname_lock) threadname_lock->acquire (INFINITE); } while (0)
|
||||||
|
|
||||||
|
#define unlock_threadname() \
|
||||||
|
do {if (threadname_lock) threadname_lock->release (); } while (0)
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
DWORD id;
|
||||||
|
const char *name;
|
||||||
|
} thread_info;
|
||||||
|
|
||||||
|
static NO_COPY thread_info threads[32] = {{0}}; // increase as necessary
|
||||||
|
#define NTHREADS (sizeof(threads) / sizeof(threads[0]))
|
||||||
|
|
||||||
|
void
|
||||||
|
threadname_init ()
|
||||||
|
{
|
||||||
|
threadname_lock = new_muto (FALSE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __stdcall
|
||||||
|
regthread (const char *name, DWORD tid)
|
||||||
|
{
|
||||||
|
lock_threadname ();
|
||||||
|
for (DWORD i = 0; i < NTHREADS; i++)
|
||||||
|
if (threads[i].name == NULL || strcmp (threads[i].name, name) == 0 ||
|
||||||
|
threads[i].id == tid)
|
||||||
|
{
|
||||||
|
threads[i].name = name;
|
||||||
|
threads[i].id = tid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
unlock_threadname ();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct thread_start
|
||||||
|
{
|
||||||
|
LONG notavail;
|
||||||
|
LPTHREAD_START_ROUTINE func;
|
||||||
|
VOID *arg;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A place to store arguments to thread_stub since they can't be
|
||||||
|
stored on the stack. An available element is !notavail. */
|
||||||
|
thread_start NO_COPY start_buf[NTHREADS] = {{0, NULL,NULL}};
|
||||||
|
|
||||||
|
/* Initial stub called by makethread. Performs initial per-thread
|
||||||
|
initialization. */
|
||||||
|
static DWORD WINAPI
|
||||||
|
thread_stub (VOID *arg)
|
||||||
|
{
|
||||||
|
LPTHREAD_START_ROUTINE threadfunc = ((thread_start *) arg)->func;
|
||||||
|
VOID *threadarg = ((thread_start *) arg)->arg;
|
||||||
|
|
||||||
|
exception_list except_entry;
|
||||||
|
|
||||||
|
/* Give up our slot in the start_buf array */
|
||||||
|
InterlockedExchange (&((thread_start *) arg)->notavail, 0);
|
||||||
|
|
||||||
|
#ifdef _MT_SAFE
|
||||||
|
/* marco@ddi.nl: Needed for the reent's of this local dll thread
|
||||||
|
I assume that the local threads are using the reent structure of
|
||||||
|
the main thread
|
||||||
|
*/
|
||||||
|
if ( !TlsSetValue(user_data->threadinterface->reent_index,
|
||||||
|
&user_data->threadinterface->reents) )
|
||||||
|
api_fatal(" Sig proc MT init failed\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Initialize this threads ability to respond to things like
|
||||||
|
SIGSEGV or SIGFPE. */
|
||||||
|
init_exceptions (&except_entry);
|
||||||
|
|
||||||
|
return threadfunc (threadarg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wrapper for CreateThread. Registers the thread name/id and ensures that
|
||||||
|
cygwin threads are properly initialized. */
|
||||||
|
HANDLE __stdcall
|
||||||
|
makethread (LPTHREAD_START_ROUTINE start, LPVOID param, DWORD flags,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
DWORD tid;
|
||||||
|
HANDLE h;
|
||||||
|
SECURITY_ATTRIBUTES *sa;
|
||||||
|
thread_start *info; /* Various information needed by the newly created thread */
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
/* Search the start_buf array for an empty slot to use */
|
||||||
|
for (info = start_buf; info < start_buf + NTHREADS; info++)
|
||||||
|
if (!InterlockedExchange (&info->notavail, 1))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* Should never hit here, but be defensive anyway. */
|
||||||
|
Sleep (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
info->func = start; /* Real function to start */
|
||||||
|
info->arg = param; /* The single parameter to the thread */
|
||||||
|
|
||||||
|
if (*name != '+')
|
||||||
|
sa = &sec_none_nih; /* The handle should not be inherited by subprocesses. */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
name++;
|
||||||
|
sa = &sec_none; /* The handle should be inherited by subprocesses. */
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((h = CreateThread (sa, 0, thread_stub, (VOID *) info, flags, &tid)))
|
||||||
|
regthread (name, tid); /* Register this name/thread id for debugging output. */
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the symbolic name of the current thread for debugging.
|
||||||
|
*/
|
||||||
|
const char * __stdcall
|
||||||
|
threadname (DWORD tid, int lockit)
|
||||||
|
{
|
||||||
|
const char *res = NULL;
|
||||||
|
if (!tid)
|
||||||
|
tid = GetCurrentThreadId ();
|
||||||
|
|
||||||
|
if (lockit)
|
||||||
|
lock_threadname ();
|
||||||
|
for (DWORD i = 0; i < NTHREADS && threads[i].name != NULL; i++)
|
||||||
|
if (threads[i].id == tid)
|
||||||
|
{
|
||||||
|
res = threads[i].name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (lockit)
|
||||||
|
unlock_threadname ();
|
||||||
|
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
static char buf[30] NO_COPY = {0};
|
||||||
|
__small_sprintf (buf, "unknown (%p)", tid);
|
||||||
|
res = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUGGING
|
||||||
|
/* Here lies extra debugging routines which help track down internal
|
||||||
|
Cygwin problems when compiled with -DDEBUGGING . */
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
typedef struct _h
|
||||||
|
{
|
||||||
|
BOOL allocated;
|
||||||
|
HANDLE h;
|
||||||
|
const char *name;
|
||||||
|
const char *func;
|
||||||
|
int ln;
|
||||||
|
struct _h *next;
|
||||||
|
} handle_list;
|
||||||
|
|
||||||
|
static NO_COPY handle_list starth = {0};
|
||||||
|
static NO_COPY handle_list *endh = NULL;
|
||||||
|
|
||||||
|
static handle_list NO_COPY freeh[1000] = {{0}};
|
||||||
|
#define NFREEH (sizeof (freeh) / sizeof (freeh[0]))
|
||||||
|
|
||||||
|
static muto NO_COPY *debug_lock = NULL;
|
||||||
|
|
||||||
|
#define lock_debug() \
|
||||||
|
do {if (debug_lock) debug_lock->acquire (INFINITE); } while (0)
|
||||||
|
|
||||||
|
#define unlock_debug() \
|
||||||
|
do {if (debug_lock) debug_lock->release (); } while (0)
|
||||||
|
|
||||||
|
void
|
||||||
|
debug_init ()
|
||||||
|
{
|
||||||
|
debug_lock = new_muto (FALSE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find a registered handle in the linked list of handles. */
|
||||||
|
static handle_list * __stdcall
|
||||||
|
find_handle (HANDLE h)
|
||||||
|
{
|
||||||
|
handle_list *hl;
|
||||||
|
for (hl = &starth; hl->next != NULL; hl = hl->next)
|
||||||
|
if (hl->next->h == h)
|
||||||
|
goto out;
|
||||||
|
endh = hl;
|
||||||
|
hl = NULL;
|
||||||
|
|
||||||
|
out:
|
||||||
|
return hl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a new handle record */
|
||||||
|
static handle_list * __stdcall
|
||||||
|
newh ()
|
||||||
|
{
|
||||||
|
handle_list *hl;
|
||||||
|
lock_debug ();
|
||||||
|
for (hl = freeh; hl < freeh + NFREEH; hl++)
|
||||||
|
if (hl->name == NULL)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* All used up??? */
|
||||||
|
if ((hl = (handle_list *)malloc (sizeof *hl)) != NULL)
|
||||||
|
{
|
||||||
|
memset (hl, 0, sizeof (*hl));
|
||||||
|
hl->allocated = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
unlock_debug ();
|
||||||
|
return hl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add a handle to the linked list of known handles. */
|
||||||
|
void __stdcall
|
||||||
|
add_handle (const char *func, int ln, HANDLE h, const char *name)
|
||||||
|
{
|
||||||
|
handle_list *hl;
|
||||||
|
lock_debug ();
|
||||||
|
|
||||||
|
if (find_handle (h))
|
||||||
|
goto out; /* Already did this once */
|
||||||
|
|
||||||
|
if ((hl = newh()) == NULL)
|
||||||
|
{
|
||||||
|
unlock_debug ();
|
||||||
|
system_printf ("couldn't allocate memory for %s(%d): %s(%p)",
|
||||||
|
func, ln, name, h);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hl->h = h;
|
||||||
|
hl->name = name;
|
||||||
|
hl->func = func;
|
||||||
|
hl->ln = ln;
|
||||||
|
hl->next = NULL;
|
||||||
|
endh->next = hl;
|
||||||
|
endh = hl;
|
||||||
|
|
||||||
|
out:
|
||||||
|
unlock_debug ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close a known handle. Complain if !force and closing a known handle or
|
||||||
|
if the name of the handle being closed does not match the registered name. */
|
||||||
|
BOOL __stdcall
|
||||||
|
close_handle (const char *func, int ln, HANDLE h, const char *name, BOOL force)
|
||||||
|
{
|
||||||
|
BOOL ret;
|
||||||
|
handle_list *hl;
|
||||||
|
lock_debug ();
|
||||||
|
|
||||||
|
if ((hl = find_handle (h)) && !force)
|
||||||
|
{
|
||||||
|
hl = hl->next;
|
||||||
|
unlock_debug (); // race here
|
||||||
|
system_printf ("attempt to close protected handle %s:%d(%s<%p>)",
|
||||||
|
hl->func, hl->ln, hl->name, hl->h);
|
||||||
|
system_printf (" by %s:%d(%s<%p>)", func, ln, name, h);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle_list *hln;
|
||||||
|
if (hl && (hln = hl->next) && strcmp (name, hln->name))
|
||||||
|
{
|
||||||
|
system_printf ("closing protected handle %s:%d(%s<%p>)",
|
||||||
|
hln->func, hln->ln, hln->name, hln->h);
|
||||||
|
system_printf (" by %s:%d(%s<%p>)", func, ln, name, h);
|
||||||
|
}
|
||||||
|
ret = CloseHandle (h);
|
||||||
|
if (hl)
|
||||||
|
{
|
||||||
|
handle_list *hnuke = hl->next;
|
||||||
|
hl->next = hl->next->next;
|
||||||
|
if (hnuke->allocated)
|
||||||
|
free (hnuke);
|
||||||
|
else
|
||||||
|
memset (hnuke, 0, sizeof (*hnuke));
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock_debug ();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif /*DEBUGGING*/
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
/* Provide a stack frame when calling WaitFor* functions */
|
||||||
|
|
||||||
|
#undef WaitForSingleObject
|
||||||
|
|
||||||
|
DWORD __stdcall
|
||||||
|
WFSO (HANDLE hHandle, DWORD dwMilliseconds)
|
||||||
|
{
|
||||||
|
DWORD ret;
|
||||||
|
ret = WaitForSingleObject (hHandle, dwMilliseconds);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef WaitForMultipleObjects
|
||||||
|
|
||||||
|
DWORD __stdcall
|
||||||
|
WFMO (DWORD nCount, CONST HANDLE *lpHandles, BOOL fWaitAll, DWORD dwMilliseconds)
|
||||||
|
{
|
||||||
|
DWORD ret;
|
||||||
|
ret = WaitForMultipleObjects (nCount, lpHandles, fWaitAll, dwMilliseconds);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
69
winsup/cygwin/debug.h
Normal file
69
winsup/cygwin/debug.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/* debug.h
|
||||||
|
|
||||||
|
Copyright 1998, 1999, 2000 Cygnus Solutions.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#ifndef MALLOC_DEBUG
|
||||||
|
#define MALLOC_CHECK do {} while (0)
|
||||||
|
#else
|
||||||
|
#define MALLOC_CHECK ({\
|
||||||
|
debug_printf ("checking malloc pool");\
|
||||||
|
(void)mallinfo ();\
|
||||||
|
})
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
DWORD __stdcall WFSO (HANDLE, DWORD);
|
||||||
|
DWORD __stdcall WFMO (DWORD, CONST HANDLE *, BOOL, DWORD);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define WaitForSingleObject WFSO
|
||||||
|
#define WaitForMultipleObject WFMO
|
||||||
|
|
||||||
|
#if !defined(_DEBUG_H_)
|
||||||
|
#define _DEBUG_H_
|
||||||
|
|
||||||
|
void threadname_init ();
|
||||||
|
HANDLE __stdcall makethread (LPTHREAD_START_ROUTINE, LPVOID, DWORD, const char *);
|
||||||
|
const char * __stdcall threadname (DWORD, int lockit = TRUE);
|
||||||
|
void __stdcall regthread (const char *, DWORD);
|
||||||
|
|
||||||
|
#ifndef DEBUGGING
|
||||||
|
# define ForceCloseHandle CloseHandle
|
||||||
|
# define ForceCloseHandle1(h, n) CloseHandle (h)
|
||||||
|
# define ForceCloseHandle2(h, n) CloseHandle (h)
|
||||||
|
# define ProtectHandle(h) do {} while (0)
|
||||||
|
# define ProtectHandle1(h,n) do {} while (0)
|
||||||
|
# define ProtectHandle2(h,n) do {} while (0)
|
||||||
|
# define debug_init() do {} while (0)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
# ifdef NO_DEBUG_DEFINES
|
||||||
|
# undef NO_DEBUG_DEFINES
|
||||||
|
# else
|
||||||
|
# define CloseHandle(h) \
|
||||||
|
close_handle (__PRETTY_FUNCTION__, __LINE__, (h), #h, FALSE)
|
||||||
|
# define ForceCloseHandle(h) \
|
||||||
|
close_handle (__PRETTY_FUNCTION__, __LINE__, (h), #h, TRUE)
|
||||||
|
# define ForceCloseHandle1(h,n) \
|
||||||
|
close_handle (__PRETTY_FUNCTION__, __LINE__, (h), #n, TRUE)
|
||||||
|
# define ForceCloseHandle2(h,n) \
|
||||||
|
close_handle (__PRETTY_FUNCTION__, __LINE__, (h), n, TRUE)
|
||||||
|
# define lock_pinfo_for_update(n) lpfu(__PRETTY_FUNCTION__, __LINE__, n)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# define ProtectHandle(h) add_handle (__PRETTY_FUNCTION__, __LINE__, (h), #h)
|
||||||
|
# define ProtectHandle1(h,n) add_handle (__PRETTY_FUNCTION__, __LINE__, (h), #n)
|
||||||
|
# define ProtectHandle2(h,n) add_handle (__PRETTY_FUNCTION__, __LINE__, (h), n)
|
||||||
|
|
||||||
|
void debug_init ();
|
||||||
|
void __stdcall add_handle (const char *, int, HANDLE, const char *);
|
||||||
|
BOOL __stdcall close_handle (const char *, int, HANDLE, const char *, BOOL);
|
||||||
|
int __stdcall lpfu (const char *, int, DWORD timeout);
|
||||||
|
|
||||||
|
#endif /*DEBUGGING*/
|
||||||
|
#endif /*_DEBUG_H_*/
|
99
winsup/cygwin/delqueue.cc
Normal file
99
winsup/cygwin/delqueue.cc
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/* delqueue.cc
|
||||||
|
|
||||||
|
Copyright 1996, 1998 Cygnus Solutions.
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include "winsup.h"
|
||||||
|
|
||||||
|
/* FIXME: this delqueue module is very flawed and should be rewritten.
|
||||||
|
First, having an array of a fixed size for keeping track of the
|
||||||
|
unlinked but not yet deleted files is bad. Second, some programs
|
||||||
|
will unlink files and then create a new one in the same location
|
||||||
|
and this behavior is not supported in the current code. Probably
|
||||||
|
we should find a move/rename function that will work on open files,
|
||||||
|
and move delqueue files to some special location or some such
|
||||||
|
hack... */
|
||||||
|
|
||||||
|
void
|
||||||
|
delqueue_list::init ()
|
||||||
|
{
|
||||||
|
empty = 1;
|
||||||
|
memset(inuse, 0, MAX_DELQUEUES_PENDING);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
delqueue_list::queue_file (const char *dosname)
|
||||||
|
{
|
||||||
|
char temp[MAX_PATH], *end;
|
||||||
|
GetFullPathName (dosname, sizeof (temp), temp, &end);
|
||||||
|
|
||||||
|
/* Note about race conditions: The only time we get to this point is
|
||||||
|
when a delete fails because someone's holding the descriptor open.
|
||||||
|
In those cases, other programs will be unable to delete the file
|
||||||
|
also, so any entries referring to that file will not be removed
|
||||||
|
from the queue while we're here. */
|
||||||
|
|
||||||
|
if (!empty)
|
||||||
|
{
|
||||||
|
/* check for duplicates */
|
||||||
|
for (int i=0; i < MAX_DELQUEUES_PENDING; i++)
|
||||||
|
if (inuse[i] && strcmp(name[i], temp) == 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_DELQUEUES_PENDING; i++)
|
||||||
|
if (!inuse[i])
|
||||||
|
{
|
||||||
|
/* set the name first, in case someone else is running the
|
||||||
|
queue they'll get a valid name */
|
||||||
|
strcpy(name[i], temp);
|
||||||
|
inuse[i] = 1;
|
||||||
|
empty = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
system_printf ("Out of queue slots");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
delqueue_list::process_queue ()
|
||||||
|
{
|
||||||
|
if (empty)
|
||||||
|
return;
|
||||||
|
/* We set empty to 1 here, rather than later, to avoid a race
|
||||||
|
condition - some other program might queue up a file while we're
|
||||||
|
processing, and it will zero out empty also. */
|
||||||
|
empty = 1; /* but might get set to zero again, below */
|
||||||
|
|
||||||
|
syscall_printf ("Running delqueue");
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_DELQUEUES_PENDING; i++)
|
||||||
|
if (inuse[i])
|
||||||
|
{
|
||||||
|
if (DeleteFileA (name[i]))
|
||||||
|
{
|
||||||
|
syscall_printf ("Deleted %s", name[i]);
|
||||||
|
inuse[i] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int res = GetLastError ();
|
||||||
|
empty = 0;
|
||||||
|
if (res == ERROR_SHARING_VIOLATION)
|
||||||
|
{
|
||||||
|
/* File still inuse, that's ok */
|
||||||
|
syscall_printf ("Still using %s", name[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
syscall_printf ("Hmm, don't know what to do with '%s', %E", name[i]);
|
||||||
|
inuse[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
340
winsup/cygwin/dir.cc
Normal file
340
winsup/cygwin/dir.cc
Normal file
@ -0,0 +1,340 @@
|
|||||||
|
/* dir.cc: Posix directory-related routines
|
||||||
|
|
||||||
|
Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions.
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include "winsup.h"
|
||||||
|
|
||||||
|
#define _COMPILING_NEWLIB
|
||||||
|
#include "dirent.h"
|
||||||
|
|
||||||
|
/* Cygwin internal */
|
||||||
|
/* Return whether the directory of a file is writable. Return 1 if it
|
||||||
|
is. Otherwise, return 0, and set errno appropriately. */
|
||||||
|
int __stdcall
|
||||||
|
writable_directory (const char *file)
|
||||||
|
{
|
||||||
|
char dir[strlen (file) + 1];
|
||||||
|
|
||||||
|
strcpy (dir, file);
|
||||||
|
|
||||||
|
const char *usedir;
|
||||||
|
char *slash = strrchr (dir, '\\');
|
||||||
|
if (slash == NULL)
|
||||||
|
usedir = ".";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*slash = '\0';
|
||||||
|
usedir = dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
int acc = access (usedir, W_OK);
|
||||||
|
|
||||||
|
return acc == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* opendir: POSIX 5.1.2.1 */
|
||||||
|
extern "C" DIR *
|
||||||
|
opendir (const char *dirname)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
DIR *dir;
|
||||||
|
DIR *res = 0;
|
||||||
|
struct stat statbuf;
|
||||||
|
|
||||||
|
path_conv real_dirname (dirname, SYMLINK_FOLLOW, 1);
|
||||||
|
|
||||||
|
if (real_dirname.error)
|
||||||
|
{
|
||||||
|
set_errno (real_dirname.error);
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stat (real_dirname.get_win32 (), &statbuf) == -1)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
if (!(statbuf.st_mode & S_IFDIR))
|
||||||
|
{
|
||||||
|
set_errno (ENOTDIR);
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = strlen (real_dirname.get_win32 ());
|
||||||
|
if (len > MAX_PATH - 3)
|
||||||
|
{
|
||||||
|
set_errno (ENAMETOOLONG);
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((dir = (DIR *) malloc (sizeof (DIR))) == NULL)
|
||||||
|
{
|
||||||
|
set_errno (ENOMEM);
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
if ((dir->__d_dirname = (char *) malloc (len + 3)) == NULL)
|
||||||
|
{
|
||||||
|
free (dir);
|
||||||
|
set_errno (ENOMEM);
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
if ((dir->__d_dirent =
|
||||||
|
(struct dirent *) malloc (sizeof (struct dirent))) == NULL)
|
||||||
|
{
|
||||||
|
free (dir->__d_dirname);
|
||||||
|
free (dir);
|
||||||
|
set_errno (ENOMEM);
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
strcpy (dir->__d_dirname, real_dirname.get_win32 ());
|
||||||
|
/* FindFirstFile doesn't seem to like duplicate /'s. */
|
||||||
|
len = strlen (dir->__d_dirname);
|
||||||
|
if (len == 0 || SLASH_P (dir->__d_dirname[len - 1]))
|
||||||
|
strcat (dir->__d_dirname, "*");
|
||||||
|
else
|
||||||
|
strcat (dir->__d_dirname, "\\*"); /**/
|
||||||
|
dir->__d_cookie = __DIRENT_COOKIE;
|
||||||
|
dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE;
|
||||||
|
dir->__d_position = 0;
|
||||||
|
dir->__d_dirhash = statbuf.st_ino;
|
||||||
|
|
||||||
|
res = dir;
|
||||||
|
|
||||||
|
failed:
|
||||||
|
syscall_printf ("%p = opendir (%s)", res, dirname);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* readdir: POSIX 5.1.2.1 */
|
||||||
|
extern "C" struct dirent *
|
||||||
|
readdir (DIR * dir)
|
||||||
|
{
|
||||||
|
WIN32_FIND_DATA buf;
|
||||||
|
HANDLE handle;
|
||||||
|
struct dirent *res = 0;
|
||||||
|
int prior_errno;
|
||||||
|
|
||||||
|
if (dir->__d_cookie != __DIRENT_COOKIE)
|
||||||
|
{
|
||||||
|
set_errno (EBADF);
|
||||||
|
syscall_printf ("%p = readdir (%p)", res, dir);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir->__d_u.__d_data.__handle != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
if (FindNextFileA (dir->__d_u.__d_data.__handle, &buf) == 0)
|
||||||
|
{
|
||||||
|
prior_errno = get_errno();
|
||||||
|
(void) FindClose (dir->__d_u.__d_data.__handle);
|
||||||
|
dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE;
|
||||||
|
__seterrno ();
|
||||||
|
/* POSIX says you shouldn't set errno when readdir can't
|
||||||
|
find any more files; if another error we leave it set. */
|
||||||
|
if (get_errno () == ENMFILE)
|
||||||
|
set_errno (prior_errno);
|
||||||
|
syscall_printf ("%p = readdir (%p)", res, dir);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
handle = FindFirstFileA (dir->__d_dirname, &buf);
|
||||||
|
|
||||||
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
/* It's possible that someone else deleted or emptied the directory
|
||||||
|
or some such between the opendir () call and here. */
|
||||||
|
prior_errno = get_errno ();
|
||||||
|
__seterrno ();
|
||||||
|
/* POSIX says you shouldn't set errno when readdir can't
|
||||||
|
find any more files; if another error we leave it set. */
|
||||||
|
if (get_errno () == ENMFILE)
|
||||||
|
set_errno (prior_errno);
|
||||||
|
syscall_printf ("%p = readdir (%p)", res, dir);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
dir->__d_u.__d_data.__handle = handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We get here if `buf' contains valid data. */
|
||||||
|
strcpy (dir->__d_dirent->d_name, buf.cFileName);
|
||||||
|
|
||||||
|
/* Compute d_ino by combining filename hash with the directory hash
|
||||||
|
(which was stored in dir->__d_dirhash when opendir was called). */
|
||||||
|
if (buf.cFileName[0] == '.')
|
||||||
|
{
|
||||||
|
if (buf.cFileName[1] == '\0')
|
||||||
|
dir->__d_dirent->d_ino = dir->__d_dirhash;
|
||||||
|
else if (buf.cFileName[1] != '.' || buf.cFileName[2] != '\0')
|
||||||
|
goto hashit;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *p, up[strlen (dir->__d_dirname) + 1];
|
||||||
|
strcpy (up, dir->__d_dirname);
|
||||||
|
if (!(p = strrchr (up, '\\')))
|
||||||
|
goto hashit;
|
||||||
|
*p = '\0';
|
||||||
|
if (!(p = strrchr (up, '\\')))
|
||||||
|
dir->__d_dirent->d_ino = hash_path_name (0, ".");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*p = '\0';
|
||||||
|
dir->__d_dirent->d_ino = hash_path_name (0, up);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hashit:
|
||||||
|
ino_t dino = hash_path_name (dir->__d_dirhash, "\\");
|
||||||
|
dir->__d_dirent->d_ino = hash_path_name (dino, buf.cFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
++dir->__d_position;
|
||||||
|
res = dir->__d_dirent;
|
||||||
|
syscall_printf ("%p = readdir (%p) (%s)",
|
||||||
|
&dir->__d_dirent, dir, buf.cFileName);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* telldir */
|
||||||
|
extern "C" off_t
|
||||||
|
telldir (DIR * dir)
|
||||||
|
{
|
||||||
|
if (dir->__d_cookie != __DIRENT_COOKIE)
|
||||||
|
return 0;
|
||||||
|
return dir->__d_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* seekdir */
|
||||||
|
extern "C" void
|
||||||
|
seekdir (DIR * dir, off_t loc)
|
||||||
|
{
|
||||||
|
if (dir->__d_cookie != __DIRENT_COOKIE)
|
||||||
|
return;
|
||||||
|
rewinddir (dir);
|
||||||
|
while (loc > dir->__d_position)
|
||||||
|
if (! readdir (dir))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* rewinddir: POSIX 5.1.2.1 */
|
||||||
|
extern "C" void
|
||||||
|
rewinddir (DIR * dir)
|
||||||
|
{
|
||||||
|
syscall_printf ("rewinddir (%p)", dir);
|
||||||
|
|
||||||
|
if (dir->__d_cookie != __DIRENT_COOKIE)
|
||||||
|
return;
|
||||||
|
if (dir->__d_u.__d_data.__handle != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
(void) FindClose (dir->__d_u.__d_data.__handle);
|
||||||
|
dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE;
|
||||||
|
dir->__d_position = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* closedir: POSIX 5.1.2.1 */
|
||||||
|
extern "C" int
|
||||||
|
closedir (DIR * dir)
|
||||||
|
{
|
||||||
|
if (dir->__d_cookie != __DIRENT_COOKIE)
|
||||||
|
{
|
||||||
|
set_errno (EBADF);
|
||||||
|
syscall_printf ("-1 = closedir (%p)", dir);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir->__d_u.__d_data.__handle != INVALID_HANDLE_VALUE &&
|
||||||
|
FindClose (dir->__d_u.__d_data.__handle) == 0)
|
||||||
|
{
|
||||||
|
__seterrno ();
|
||||||
|
syscall_printf ("-1 = closedir (%p)", dir);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset the marker in case the caller tries to use `dir' again. */
|
||||||
|
dir->__d_cookie = 0;
|
||||||
|
|
||||||
|
free (dir->__d_dirname);
|
||||||
|
free (dir->__d_dirent);
|
||||||
|
free (dir);
|
||||||
|
syscall_printf ("0 = closedir (%p)", dir);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mkdir: POSIX 5.4.1.1 */
|
||||||
|
extern "C" int
|
||||||
|
mkdir (const char *dir, mode_t mode)
|
||||||
|
{
|
||||||
|
int res = -1;
|
||||||
|
|
||||||
|
path_conv real_dir (dir, SYMLINK_NOFOLLOW);
|
||||||
|
|
||||||
|
if (real_dir.error)
|
||||||
|
{
|
||||||
|
set_errno (real_dir.error);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
nofinalslash(real_dir.get_win32 (), real_dir.get_win32 ());
|
||||||
|
if (! writable_directory (real_dir.get_win32 ()))
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
if (CreateDirectoryA (real_dir.get_win32 (), 0))
|
||||||
|
{
|
||||||
|
set_file_attribute (real_dir.has_acls (), real_dir.get_win32 (),
|
||||||
|
(mode & 0777) & ~myself->umask);
|
||||||
|
res = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
__seterrno ();
|
||||||
|
|
||||||
|
done:
|
||||||
|
syscall_printf ("%d = mkdir (%s, %d)", res, dir, mode);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* rmdir: POSIX 5.5.2.1 */
|
||||||
|
extern "C" int
|
||||||
|
rmdir (const char *dir)
|
||||||
|
{
|
||||||
|
int res = -1;
|
||||||
|
|
||||||
|
path_conv real_dir (dir, SYMLINK_NOFOLLOW);
|
||||||
|
|
||||||
|
if (real_dir.error)
|
||||||
|
{
|
||||||
|
set_errno (real_dir.error);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RemoveDirectoryA (real_dir.get_win32 ()))
|
||||||
|
res = 0;
|
||||||
|
else if (os_being_run != winNT && GetLastError() == ERROR_ACCESS_DENIED)
|
||||||
|
{
|
||||||
|
/* Under Windows 95 & 98, ERROR_ACCESS_DENIED is returned
|
||||||
|
if you try to remove a file or a non-empty directory. */
|
||||||
|
if (GetFileAttributes (real_dir.get_win32()) != FILE_ATTRIBUTE_DIRECTORY)
|
||||||
|
set_errno (ENOTDIR);
|
||||||
|
else
|
||||||
|
set_errno (ENOTEMPTY);
|
||||||
|
}
|
||||||
|
else if (GetLastError () == ERROR_DIRECTORY)
|
||||||
|
set_errno (ENOTDIR);
|
||||||
|
else
|
||||||
|
__seterrno ();
|
||||||
|
|
||||||
|
done:
|
||||||
|
syscall_printf ("%d = rmdir (%s)", res, dir);
|
||||||
|
return res;
|
||||||
|
}
|
236
winsup/cygwin/dlfcn.cc
Normal file
236
winsup/cygwin/dlfcn.cc
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
/* dlfcn.cc
|
||||||
|
|
||||||
|
Copyright 1998, 2000 Cygnus Solutions
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "winsup.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "dlfcn.h"
|
||||||
|
#include "dll_init.h"
|
||||||
|
|
||||||
|
#ifdef _MT_SAFE
|
||||||
|
#define _dl_error _reent_winsup()->_dl_error
|
||||||
|
#define _dl_buffer _reent_winsup()->_dl_buffer
|
||||||
|
#else
|
||||||
|
static int _dl_error = 0;
|
||||||
|
static char _dl_buffer[256];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void __stdcall
|
||||||
|
set_dl_error (const char *str)
|
||||||
|
{
|
||||||
|
__small_sprintf (_dl_buffer, "%s: %E", str);
|
||||||
|
_dl_error = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// this function checks for existence of a file specified by the
|
||||||
|
// directory and name components. If successful, return a pointer
|
||||||
|
// the full pathname (static buffer), or else return 0.
|
||||||
|
//
|
||||||
|
static const char * __stdcall
|
||||||
|
check_access (const char *dir, const char *name)
|
||||||
|
{
|
||||||
|
static char buf[MAX_PATH];
|
||||||
|
const char *ret = 0;
|
||||||
|
|
||||||
|
buf[0] = 0;
|
||||||
|
strcpy (buf, dir);
|
||||||
|
strcat (buf, "\\");
|
||||||
|
strcat (buf, name);
|
||||||
|
|
||||||
|
if (!access (buf, F_OK))
|
||||||
|
ret = buf;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// this function looks for an executable file given the name and the
|
||||||
|
// environment variable to use for searching (eg., PATH); returns
|
||||||
|
// the full pathname (static buffer) if found or NULL if not.
|
||||||
|
//
|
||||||
|
static const char * __stdcall
|
||||||
|
check_path_access (const char *mywinenv, const char *name)
|
||||||
|
{
|
||||||
|
static char buf[MAX_PATH];
|
||||||
|
return find_exec (name, buf, mywinenv, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// This function simulates the same search as LoadLibary + check
|
||||||
|
// environment variable LD_LIBRARY_PATH. If found, return the full
|
||||||
|
// pathname (static buffer); if illegal, return the input string
|
||||||
|
// unchanged and let the caller deal with it; return NULL otherwise.
|
||||||
|
//
|
||||||
|
// Note that this should never be called with a NULL string, since
|
||||||
|
// that is the introspective case, and the caller should not call
|
||||||
|
// this function at all.
|
||||||
|
//
|
||||||
|
static const char * __stdcall
|
||||||
|
get_full_path_of_dll (const char* str)
|
||||||
|
{
|
||||||
|
int len = (str) ? strlen (str) : 0;
|
||||||
|
|
||||||
|
// NULL or empty string or too long to be legal win32 pathname?
|
||||||
|
if (len == 0 || len >= MAX_PATH - 1)
|
||||||
|
return str;
|
||||||
|
|
||||||
|
char buf[MAX_PATH];
|
||||||
|
static char name[MAX_PATH];
|
||||||
|
const char *ret = 0;
|
||||||
|
|
||||||
|
strcpy (name, str);
|
||||||
|
|
||||||
|
// add extension if necessary, but leave a trailing '.', if any, alone.
|
||||||
|
// Files with trailing '.'s are handled differently by win32 API.
|
||||||
|
if (str[len - 1] != '.')
|
||||||
|
{
|
||||||
|
// add .dll only if no extension provided. Handle various cases:
|
||||||
|
//
|
||||||
|
// ./shlib --> ./shlib.dll
|
||||||
|
// ./dir/shlib.so --> ./dir/shlib.so
|
||||||
|
// shlib --> shlib.dll
|
||||||
|
// shlib.dll --> shlib.dll
|
||||||
|
// shlib.so --> shlib.so
|
||||||
|
//
|
||||||
|
const char *p = strrchr (str, '.');
|
||||||
|
if (!p || isdirsep (p[1]))
|
||||||
|
strcat (name, ".dll");
|
||||||
|
}
|
||||||
|
|
||||||
|
// deal with fully qualified filename right away. Do the actual
|
||||||
|
// conversion to win32 filename just before returning however.
|
||||||
|
if (isabspath (str))
|
||||||
|
ret = name;
|
||||||
|
|
||||||
|
// current directory
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
if (GetCurrentDirectory (MAX_PATH, buf) == 0)
|
||||||
|
small_printf ("WARNING: get_full_path_of_dll can't get current directory win32 %E\n");
|
||||||
|
else
|
||||||
|
ret = check_access (buf, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// LD_LIBRARY_PATH
|
||||||
|
if (!ret)
|
||||||
|
ret = check_path_access ("LD_LIBRARY_PATH=", name);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
// system directory
|
||||||
|
if (GetSystemDirectory (buf, MAX_PATH) == 0)
|
||||||
|
small_printf ("WARNING: get_full_path_of_dll can't get system directory win32 %E\n");
|
||||||
|
else
|
||||||
|
ret = check_access (buf, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 16 bits system directory
|
||||||
|
if (!ret && (os_being_run == winNT))
|
||||||
|
{
|
||||||
|
// we assume last dir was xxxxx\SYSTEM32, so we remove 32
|
||||||
|
len = strlen (buf);
|
||||||
|
buf[len - 2] = 0;
|
||||||
|
ret = check_access (buf, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// windows directory
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
if (GetWindowsDirectory (buf, MAX_PATH) == 0)
|
||||||
|
small_printf ("WARNING: get_full_path_of_dll can't get Windows directory win32 %E\n");
|
||||||
|
else
|
||||||
|
ret = check_access (buf, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// PATH
|
||||||
|
if (!ret)
|
||||||
|
ret = check_path_access ("PATH=", name);
|
||||||
|
|
||||||
|
//
|
||||||
|
// now do a final conversion to win32 pathname. This step is necessary
|
||||||
|
// to resolve symlinks etc so that win32 API finds the underlying file.
|
||||||
|
//
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
path_conv real_filename (ret, SYMLINK_FOLLOW, 1);
|
||||||
|
if (real_filename.error)
|
||||||
|
ret = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy (name, real_filename.get_win32 ());
|
||||||
|
ret = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
dlopen (const char *name, int)
|
||||||
|
{
|
||||||
|
SetResourceLock(LOCK_DLL_LIST,READ_LOCK|WRITE_LOCK," dlopen");
|
||||||
|
|
||||||
|
void *ret = 0;
|
||||||
|
|
||||||
|
if (!name)
|
||||||
|
{
|
||||||
|
// handle for the current module
|
||||||
|
ret = (void *) GetModuleHandle (0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// handle for the named library
|
||||||
|
const char *fullpath = get_full_path_of_dll (name);
|
||||||
|
DllList::the().currentDlOpenedLib (fullpath);
|
||||||
|
ret = (void *) LoadLibrary (fullpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
set_dl_error ("dlopen");
|
||||||
|
debug_printf ("ret %p", ret);
|
||||||
|
|
||||||
|
ReleaseResourceLock(LOCK_DLL_LIST,READ_LOCK|WRITE_LOCK," dlopen");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
dlsym (void *handle, const char *name)
|
||||||
|
{
|
||||||
|
void *ret = (void *) GetProcAddress ((HMODULE) handle, name);
|
||||||
|
if (!ret)
|
||||||
|
set_dl_error ("dlsym");
|
||||||
|
debug_printf ("ret %p", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dlclose (void *handle)
|
||||||
|
{
|
||||||
|
SetResourceLock(LOCK_DLL_LIST,READ_LOCK|WRITE_LOCK," dlclose");
|
||||||
|
|
||||||
|
int ret = -1;
|
||||||
|
if (FreeLibrary ((HMODULE) handle))
|
||||||
|
ret = 0;
|
||||||
|
if (ret)
|
||||||
|
set_dl_error ("dlclose");
|
||||||
|
|
||||||
|
ReleaseResourceLock(LOCK_DLL_LIST,READ_LOCK|WRITE_LOCK," dlclose");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
dlerror ()
|
||||||
|
{
|
||||||
|
char *ret = 0;
|
||||||
|
if (_dl_error)
|
||||||
|
ret = _dl_buffer;
|
||||||
|
return ret;
|
||||||
|
}
|
499
winsup/cygwin/dll_init.cc
Normal file
499
winsup/cygwin/dll_init.cc
Normal file
@ -0,0 +1,499 @@
|
|||||||
|
/* dll_init.cc
|
||||||
|
|
||||||
|
Copyright 1998, 1999, 2000 Cygnus Solutions.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "winsup.h"
|
||||||
|
#include "exceptions.h"
|
||||||
|
#include "dll_init.h"
|
||||||
|
|
||||||
|
extern void __stdcall check_sanity_and_sync (per_process *);
|
||||||
|
|
||||||
|
#ifdef _MT_SAFE
|
||||||
|
extern ResourceLocks _reslock NO_COPY;
|
||||||
|
extern MTinterface _mtinterf NO_COPY;
|
||||||
|
#endif /*_MT_SAFE*/
|
||||||
|
|
||||||
|
/* WARNING: debug can't be called before init !!!! */
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// the private structure
|
||||||
|
|
||||||
|
typedef enum { NONE, LINK, LOAD } dllType;
|
||||||
|
|
||||||
|
struct dll
|
||||||
|
{
|
||||||
|
per_process *p;
|
||||||
|
HMODULE handle;
|
||||||
|
const char *name;
|
||||||
|
dllType type;
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define MAX_DLL_BEFORE_INIT 100 // FIXME: enough ???
|
||||||
|
static dll _list_before_init[MAX_DLL_BEFORE_INIT];
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// local variables
|
||||||
|
|
||||||
|
static DllList _the;
|
||||||
|
static int _last = 0;
|
||||||
|
static int _max = MAX_DLL_BEFORE_INIT;
|
||||||
|
static dll *_list = _list_before_init;
|
||||||
|
static int _initCalled = 0;
|
||||||
|
static int _numberOfOpenedDlls = 0;
|
||||||
|
static int _forkeeMustReloadDlls = 0;
|
||||||
|
static int _in_forkee = 0;
|
||||||
|
static const char *_dlopenedLib = 0;
|
||||||
|
static int _dlopenIndex = -1;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static int __dll_global_dtors_recorded = 0;
|
||||||
|
|
||||||
|
static void
|
||||||
|
__dll_global_dtors()
|
||||||
|
{
|
||||||
|
_the.doGlobalDestructorsOfDlls();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
doGlobalCTORS (per_process *p)
|
||||||
|
{
|
||||||
|
void (**pfunc)() = p->ctors;
|
||||||
|
|
||||||
|
/* Run ctors backwards, so skip the first entry and find how many
|
||||||
|
there are, then run them. */
|
||||||
|
|
||||||
|
if (pfunc)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 1; pfunc[i]; i++);
|
||||||
|
|
||||||
|
for (int j = i - 1; j > 0; j-- )
|
||||||
|
(pfunc[j]) ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
doGlobalDTORS (per_process *p)
|
||||||
|
{
|
||||||
|
if (!p)
|
||||||
|
return;
|
||||||
|
void (**pfunc)() = p->dtors;
|
||||||
|
for (int i = 1; pfunc[i]; i++)
|
||||||
|
(pfunc[i]) ();
|
||||||
|
}
|
||||||
|
|
||||||
|
#define INC 500
|
||||||
|
|
||||||
|
static int
|
||||||
|
add (HMODULE h, char *name, per_process *p, dllType type)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (p)
|
||||||
|
check_sanity_and_sync (p);
|
||||||
|
|
||||||
|
if (_last == _max)
|
||||||
|
{
|
||||||
|
if (!_initCalled) // we try to load more than MAX_DLL_BEFORE_INIT
|
||||||
|
{
|
||||||
|
small_printf ("try to load more dll than max allowed=%d\n",
|
||||||
|
MAX_DLL_BEFORE_INIT);
|
||||||
|
ExitProcess (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
dll* newArray = new dll[_max+INC];
|
||||||
|
if (_list)
|
||||||
|
{
|
||||||
|
memcpy (newArray, _list, _max * sizeof (dll));
|
||||||
|
if (_list != _list_before_init)
|
||||||
|
delete []_list;
|
||||||
|
}
|
||||||
|
_list = newArray;
|
||||||
|
_max += INC;
|
||||||
|
}
|
||||||
|
|
||||||
|
_list[_last].name = name && type == LOAD ? strdup (name) : NULL;
|
||||||
|
_list[_last].handle = h;
|
||||||
|
_list[_last].p = p;
|
||||||
|
_list[_last].type = type;
|
||||||
|
|
||||||
|
ret = _last++;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
initOneDll (per_process *p)
|
||||||
|
{
|
||||||
|
/* global variable user_data must be initialized */
|
||||||
|
if (user_data == NULL)
|
||||||
|
{
|
||||||
|
small_printf ("WARNING: process not inited while trying to init a DLL!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* init impure_ptr */
|
||||||
|
*(p->impure_ptr_ptr) = *(user_data->impure_ptr_ptr);
|
||||||
|
|
||||||
|
/* FIXME: init environment (useful?) */
|
||||||
|
*(p->envptr) = *(user_data->envptr);
|
||||||
|
|
||||||
|
/* FIXME: need other initializations? */
|
||||||
|
|
||||||
|
int ret = 1;
|
||||||
|
if (!_in_forkee)
|
||||||
|
{
|
||||||
|
/* global contructors */
|
||||||
|
doGlobalCTORS (p);
|
||||||
|
|
||||||
|
/* entry point of dll (use main of per_process with null args...) */
|
||||||
|
if (p->main)
|
||||||
|
ret = (*(p->main)) (0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
DllList&
|
||||||
|
DllList::the ()
|
||||||
|
{
|
||||||
|
return _the;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DllList::currentDlOpenedLib (const char *name)
|
||||||
|
{
|
||||||
|
if (_dlopenedLib != 0)
|
||||||
|
small_printf ("WARNING: previous dlopen of %s wasn't correctly performed\n", _dlopenedLib);
|
||||||
|
_dlopenedLib = name;
|
||||||
|
_dlopenIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
DllList::recordDll (HMODULE h, per_process *p)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
/* debug_printf ("Record a dll p=%p\n", p); see WARNING */
|
||||||
|
dllType type = LINK;
|
||||||
|
if (_initCalled)
|
||||||
|
{
|
||||||
|
type = LOAD;
|
||||||
|
_numberOfOpenedDlls++;
|
||||||
|
forkeeMustReloadDlls (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_in_forkee)
|
||||||
|
{
|
||||||
|
ret = 0; // Just a flag
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
char buf[MAX_PATH];
|
||||||
|
GetModuleFileName (h, buf, MAX_PATH);
|
||||||
|
|
||||||
|
if (type == LOAD && _dlopenedLib !=0)
|
||||||
|
{
|
||||||
|
// it is not the current dlopened lib
|
||||||
|
// so we insert one empty lib to preserve place for current dlopened lib
|
||||||
|
if (!strcasematch (_dlopenedLib, buf))
|
||||||
|
{
|
||||||
|
if (_dlopenIndex == -1)
|
||||||
|
_dlopenIndex = add (0, 0, 0, NONE);
|
||||||
|
ret = add (h, buf, p, type);
|
||||||
|
}
|
||||||
|
else // it is the current dlopened lib
|
||||||
|
{
|
||||||
|
if (_dlopenIndex != -1)
|
||||||
|
{
|
||||||
|
_list[_dlopenIndex].handle = h;
|
||||||
|
_list[_dlopenIndex].p = p;
|
||||||
|
_list[_dlopenIndex].type = type;
|
||||||
|
ret = _dlopenIndex;
|
||||||
|
_dlopenIndex = -1;
|
||||||
|
}
|
||||||
|
else // it this case the dlopened lib doesn't need other lib
|
||||||
|
ret = add (h, buf, p, type);
|
||||||
|
_dlopenedLib = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret = add (h, buf, p, type);
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (_initCalled) // main module is already initialized
|
||||||
|
{
|
||||||
|
if (!initOneDll (p))
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DllList::detachDll (int dll_index)
|
||||||
|
{
|
||||||
|
if (dll_index != -1)
|
||||||
|
{
|
||||||
|
dll *aDll = &(_list[dll_index]);
|
||||||
|
doGlobalDTORS (aDll->p);
|
||||||
|
if (aDll->type == LOAD)
|
||||||
|
_numberOfOpenedDlls--;
|
||||||
|
aDll->type = NONE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
small_printf ("WARNING: try to detach an already detached dll ...\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DllList::initAll ()
|
||||||
|
{
|
||||||
|
// init for destructors
|
||||||
|
// because initAll isn't called in forked process, this exit function will
|
||||||
|
// be recorded only once
|
||||||
|
if (!__dll_global_dtors_recorded)
|
||||||
|
{
|
||||||
|
atexit (__dll_global_dtors);
|
||||||
|
__dll_global_dtors_recorded = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_initCalled)
|
||||||
|
{
|
||||||
|
debug_printf ("call to DllList::initAll");
|
||||||
|
for (int i = 0; i < _last; i++)
|
||||||
|
{
|
||||||
|
per_process *p = _list[i].p;
|
||||||
|
if (p)
|
||||||
|
initOneDll (p);
|
||||||
|
}
|
||||||
|
_initCalled = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DllList::doGlobalDestructorsOfDlls ()
|
||||||
|
{
|
||||||
|
// global destructors in reverse order
|
||||||
|
for (int i = _last - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (_list[i].type != NONE)
|
||||||
|
{
|
||||||
|
per_process *p = _list[i].p;
|
||||||
|
if (p)
|
||||||
|
doGlobalDTORS (p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
DllList::numberOfOpenedDlls ()
|
||||||
|
{
|
||||||
|
return _numberOfOpenedDlls;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
DllList::forkeeMustReloadDlls ()
|
||||||
|
{
|
||||||
|
return _forkeeMustReloadDlls;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DllList::forkeeMustReloadDlls (int i)
|
||||||
|
{
|
||||||
|
_forkeeMustReloadDlls = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define A64K (64 * 1024)
|
||||||
|
|
||||||
|
/* Mark every memory address up to "here" as reserved. This may force
|
||||||
|
Windows NT to load a DLL in the next available, lowest slot. */
|
||||||
|
void
|
||||||
|
reserve_upto (const char *name, DWORD here)
|
||||||
|
{
|
||||||
|
DWORD size;
|
||||||
|
MEMORY_BASIC_INFORMATION mb;
|
||||||
|
for (DWORD start = 0x10000; start < here; start += size)
|
||||||
|
if (!VirtualQuery ((void *) start, &mb, sizeof (mb)))
|
||||||
|
size = 64 * 1024;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size = A64K * ((mb.RegionSize + A64K - 1) / A64K);
|
||||||
|
start = A64K * (((DWORD) mb.BaseAddress + A64K - 1) / A64K);
|
||||||
|
|
||||||
|
if (start + size > here)
|
||||||
|
size = here - start;
|
||||||
|
if (mb.State == MEM_FREE &&
|
||||||
|
!VirtualAlloc ((void *) start, size, MEM_RESERVE, PAGE_NOACCESS))
|
||||||
|
api_fatal ("couldn't allocate memory %p(%d) for '%s' alignment, %E\n",
|
||||||
|
start, size, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release all of the memory previously allocated by "upto" above.
|
||||||
|
Note that this may also free otherwise reserved memory. If that becomes
|
||||||
|
a problem, we'll have to keep track of the memory that we reserve above. */
|
||||||
|
void
|
||||||
|
release_upto (const char *name, DWORD here)
|
||||||
|
{
|
||||||
|
DWORD size;
|
||||||
|
MEMORY_BASIC_INFORMATION mb;
|
||||||
|
for (DWORD start = 0x10000; start < here; start += size)
|
||||||
|
if (!VirtualQuery ((void *) start, &mb, sizeof (mb)))
|
||||||
|
size = 64 * 1024;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size = mb.RegionSize;
|
||||||
|
if (!(mb.State == MEM_RESERVE && mb.AllocationProtect == PAGE_NOACCESS &&
|
||||||
|
((void *) start < user_data->heapbase || (void *) start > user_data->heaptop)))
|
||||||
|
continue;
|
||||||
|
if (!VirtualFree ((void *) start, 0, MEM_RELEASE))
|
||||||
|
api_fatal ("couldn't release memory %p(%d) for '%s' alignment, %E\n",
|
||||||
|
start, size, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reload DLLs after a fork. Iterates over the list of dynamically loaded DLLs
|
||||||
|
and attempts to load them in the same place as they were loaded in the parent. */
|
||||||
|
void
|
||||||
|
DllList::forkeeLoadDlls ()
|
||||||
|
{
|
||||||
|
_initCalled = 1;
|
||||||
|
_in_forkee = 1;
|
||||||
|
int try2 = 0;
|
||||||
|
for (int i = 0; i < _last; i++)
|
||||||
|
if (_list[i].type == LOAD)
|
||||||
|
{
|
||||||
|
const char *name = _list[i].name;
|
||||||
|
HMODULE handle = _list[i].handle;
|
||||||
|
HMODULE h = LoadLibraryEx (name, NULL, DONT_RESOLVE_DLL_REFERENCES);
|
||||||
|
|
||||||
|
if (h == handle)
|
||||||
|
{
|
||||||
|
FreeLibrary (h);
|
||||||
|
LoadLibrary (name);
|
||||||
|
}
|
||||||
|
else if (try2)
|
||||||
|
api_fatal ("unable to remap %s to same address as parent -- %p", name, h);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FreeLibrary (h);
|
||||||
|
reserve_upto (name, (DWORD) handle);
|
||||||
|
try2 = 1;
|
||||||
|
i--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (try2)
|
||||||
|
{
|
||||||
|
release_upto (name, (DWORD) handle);
|
||||||
|
try2 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_in_forkee = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// iterators
|
||||||
|
|
||||||
|
DllListIterator::DllListIterator (int type) : _type (type), _index (-1)
|
||||||
|
{
|
||||||
|
operator++ ();
|
||||||
|
}
|
||||||
|
|
||||||
|
DllListIterator::~DllListIterator ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
DllListIterator::operator per_process* ()
|
||||||
|
{
|
||||||
|
return _list[index ()].p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DllListIterator::operator++ ()
|
||||||
|
{
|
||||||
|
_index++;
|
||||||
|
while (_index < _last && (int) (_list[_index].type) != _type)
|
||||||
|
_index++;
|
||||||
|
if (_index == _last)
|
||||||
|
_index = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkedDllIterator::LinkedDllIterator () : DllListIterator ((int) LINK)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkedDllIterator::~LinkedDllIterator ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadedDllIterator::LoadedDllIterator () : DllListIterator ((int) LOAD)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadedDllIterator::~LoadedDllIterator ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// the extern symbols
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
/* This is an exported copy of environ which can be used by DLLs
|
||||||
|
which use cygwin.dll. */
|
||||||
|
extern struct _reent reent_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int
|
||||||
|
dll_dllcrt0 (HMODULE h, per_process *p)
|
||||||
|
{
|
||||||
|
/* Partially initialize Cygwin guts for non-cygwin apps. */
|
||||||
|
if (dynamically_loaded && (! user_data || user_data->magic_biscuit == 0))
|
||||||
|
{
|
||||||
|
dll_crt0 (p);
|
||||||
|
}
|
||||||
|
return _the.recordDll (h, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OBSOLETE: This function is obsolescent and will go away in the
|
||||||
|
future. Cygwin can now handle being loaded from a noncygwin app
|
||||||
|
using the same entry point. */
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int
|
||||||
|
dll_noncygwin_dllcrt0 (HMODULE h, per_process *p)
|
||||||
|
{
|
||||||
|
return dll_dllcrt0 (h, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
void
|
||||||
|
cygwin_detach_dll (int dll_index)
|
||||||
|
{
|
||||||
|
_the.detachDll (dll_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
void
|
||||||
|
dlfork (int val)
|
||||||
|
{
|
||||||
|
_the.forkeeMustReloadDlls (val);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//-----------------------------------------------------------------------------
|
102
winsup/cygwin/dll_init.h
Normal file
102
winsup/cygwin/dll_init.h
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
/* dll_init.h
|
||||||
|
|
||||||
|
Copyright 1998 Cygnus Solutions
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// list of loaded DLL (used by fork & init)
|
||||||
|
class DllList
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static DllList& the ();
|
||||||
|
|
||||||
|
// return dll index used for freeDll
|
||||||
|
int recordDll (HMODULE, per_process*);
|
||||||
|
void detachDll (int dll_index);
|
||||||
|
|
||||||
|
// called after initialization of main module in dll_crt0
|
||||||
|
void initAll ();
|
||||||
|
|
||||||
|
// global destructors of loaded dlls
|
||||||
|
void doGlobalDestructorsOfDlls ();
|
||||||
|
|
||||||
|
// number of dlls dlopened
|
||||||
|
int numberOfOpenedDlls ();
|
||||||
|
|
||||||
|
// boolean to determine if forked process must reload dlls opened with
|
||||||
|
// LoadLibrary or dlopen ...
|
||||||
|
// default = 0 (FALSE)
|
||||||
|
int forkeeMustReloadDlls ();
|
||||||
|
void forkeeMustReloadDlls (int);
|
||||||
|
|
||||||
|
void forkeeLoadDlls ();
|
||||||
|
|
||||||
|
// set name of current library opened with dlopen
|
||||||
|
void currentDlOpenedLib (const char*);
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class DllListIterator
|
||||||
|
{
|
||||||
|
int _type;
|
||||||
|
int _index;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
DllListIterator (int type);
|
||||||
|
int index () const { return _index; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~DllListIterator();
|
||||||
|
|
||||||
|
int ok() { return _index!=-1; }
|
||||||
|
void operator++ ();
|
||||||
|
void operator++ (int) { operator++ (); }
|
||||||
|
operator per_process* ();
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class LinkedDllIterator : public DllListIterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LinkedDllIterator ();
|
||||||
|
~LinkedDllIterator ();
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class LoadedDllIterator : public DllListIterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LoadedDllIterator ();
|
||||||
|
~LoadedDllIterator ();
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define DO_LINKED_DLL(var) \
|
||||||
|
{ \
|
||||||
|
LinkedDllIterator iterator; \
|
||||||
|
while (iterator.ok ()) \
|
||||||
|
{ \
|
||||||
|
per_process *var = (per_process *) iterator;
|
||||||
|
|
||||||
|
#define DO_LOADED_DLL(var) \
|
||||||
|
{ \
|
||||||
|
LoadedDllIterator iterator; \
|
||||||
|
while (iterator.ok ()) \
|
||||||
|
{ \
|
||||||
|
per_process *var = (per_process *) iterator;
|
||||||
|
|
||||||
|
#define DLL_DONE \
|
||||||
|
iterator++; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
11
winsup/cygwin/dll_init.sgml
Normal file
11
winsup/cygwin/dll_init.sgml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
<sect1 id="func-cygwin-detach-dll">
|
||||||
|
<title>cygwin_detach_dll</title>
|
||||||
|
|
||||||
|
<funcsynopsis>
|
||||||
|
<funcdef>extern "C" void
|
||||||
|
<function>cygwin_detach_dll</function></funcdef>
|
||||||
|
<paramdef>int <parameter>dll_index</parameter></paramdef>
|
||||||
|
</funcsynopsis>
|
||||||
|
|
||||||
|
</sect1>
|
603
winsup/cygwin/dtable.cc
Normal file
603
winsup/cygwin/dtable.cc
Normal file
@ -0,0 +1,603 @@
|
|||||||
|
/* hinfo.cc: file descriptor support.
|
||||||
|
|
||||||
|
Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions.
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#define __INSIDE_CYGWIN_NET__
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#define Win32_Winsock
|
||||||
|
#include "winsup.h"
|
||||||
|
|
||||||
|
hinfo dtable;
|
||||||
|
|
||||||
|
/* Set aside space for the table of fds */
|
||||||
|
void
|
||||||
|
dtable_init (void)
|
||||||
|
{
|
||||||
|
if (!dtable.size)
|
||||||
|
dtable.extend(NOFILE_INCR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __stdcall
|
||||||
|
set_std_handle (int fd)
|
||||||
|
{
|
||||||
|
if (fd == 0)
|
||||||
|
SetStdHandle (STD_INPUT_HANDLE, dtable[fd]->get_handle ());
|
||||||
|
else if (fd == 1)
|
||||||
|
SetStdHandle (STD_OUTPUT_HANDLE, dtable[fd]->get_output_handle ());
|
||||||
|
else if (fd == 2)
|
||||||
|
SetStdHandle (STD_ERROR_HANDLE, dtable[fd]->get_output_handle ());
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
hinfo::extend (int howmuch)
|
||||||
|
{
|
||||||
|
int new_size = size + howmuch;
|
||||||
|
fhandler_base **newfds;
|
||||||
|
|
||||||
|
if (howmuch <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Try to allocate more space for fd table. We can't call realloc()
|
||||||
|
here to preserve old table if memory allocation fails */
|
||||||
|
|
||||||
|
debug_printf ("here size %d", size);
|
||||||
|
|
||||||
|
if (!(newfds = (fhandler_base **) calloc (new_size, sizeof newfds[0])))
|
||||||
|
{
|
||||||
|
debug_printf ("calloc failed");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (fds)
|
||||||
|
{
|
||||||
|
memcpy (newfds, fds, size * sizeof (fds[0]));
|
||||||
|
free (fds);
|
||||||
|
}
|
||||||
|
|
||||||
|
size = new_size;
|
||||||
|
fds = newfds;
|
||||||
|
debug_printf ("size %d, fds %d", size, fds);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the file descriptor/handle mapping table.
|
||||||
|
We only initialize the parent table here. The child table is
|
||||||
|
initialized at each fork () call. */
|
||||||
|
|
||||||
|
void
|
||||||
|
hinfo_init (void)
|
||||||
|
{
|
||||||
|
/* Set these before trying to output anything from strace.
|
||||||
|
Also, always set them even if we're to pick up our parent's fds
|
||||||
|
in case they're missed. */
|
||||||
|
|
||||||
|
if (!parent_alive && NOTSTATE(myself, PID_CYGPARENT))
|
||||||
|
{
|
||||||
|
HANDLE in = GetStdHandle (STD_INPUT_HANDLE);
|
||||||
|
HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
|
||||||
|
HANDLE err = GetStdHandle (STD_ERROR_HANDLE);
|
||||||
|
|
||||||
|
dtable.init_std_file_from_handle (0, in, GENERIC_READ, "{stdin}");
|
||||||
|
|
||||||
|
/* STD_ERROR_HANDLE has been observed to be the same as
|
||||||
|
STD_OUTPUT_HANDLE. We need separate handles (e.g. using pipes
|
||||||
|
to pass data from child to parent). */
|
||||||
|
if (out == err)
|
||||||
|
{
|
||||||
|
/* Since this code is not invoked for forked tasks, we don't have
|
||||||
|
to worry about the close-on-exec flag here. */
|
||||||
|
if (!DuplicateHandle (hMainProc, out, hMainProc, &err, 0,
|
||||||
|
1, DUPLICATE_SAME_ACCESS))
|
||||||
|
{
|
||||||
|
/* If that fails, do this as a fall back. */
|
||||||
|
err = out;
|
||||||
|
system_printf ("couldn't make stderr distinct from stdout");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dtable.init_std_file_from_handle (1, out, GENERIC_WRITE, "{stdout}");
|
||||||
|
dtable.init_std_file_from_handle (2, err, GENERIC_WRITE, "{stderr}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
hinfo::not_open (int fd)
|
||||||
|
{
|
||||||
|
SetResourceLock(LOCK_FD_LIST,READ_LOCK," not_open");
|
||||||
|
|
||||||
|
int res = fd < 0 || fd >= (int)size || fds[fd] == NULL;
|
||||||
|
|
||||||
|
ReleaseResourceLock(LOCK_FD_LIST,READ_LOCK," not open");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
hinfo::find_unused_handle (int start)
|
||||||
|
{
|
||||||
|
AssertResourceOwner(LOCK_FD_LIST,READ_LOCK);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
for (int i = start; i < (int) size; i++)
|
||||||
|
if (not_open (i))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
while (extend (NOFILE_INCR));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hinfo::release (int fd)
|
||||||
|
{
|
||||||
|
if (!not_open (fd))
|
||||||
|
{
|
||||||
|
MALLOC_CHECK;
|
||||||
|
delete (fds[fd]);
|
||||||
|
MALLOC_CHECK;
|
||||||
|
fds[fd] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hinfo::init_std_file_from_handle (int fd, HANDLE handle,
|
||||||
|
DWORD myaccess, const char *name)
|
||||||
|
{
|
||||||
|
int bin = __fmode;
|
||||||
|
/* Check to see if we're being redirected - if not then
|
||||||
|
we open then as consoles */
|
||||||
|
if (fd == 0 || fd == 1 || fd == 2)
|
||||||
|
{
|
||||||
|
first_fd_for_open = 0;
|
||||||
|
/* See if we can consoleify it - if it is a console,
|
||||||
|
don't open it in binary. That will screw up our crlfs*/
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO buf;
|
||||||
|
if (GetConsoleScreenBufferInfo (handle, &buf))
|
||||||
|
{
|
||||||
|
bin = 0;
|
||||||
|
if (ISSTATE (myself, PID_USETTY))
|
||||||
|
name = "/dev/tty";
|
||||||
|
else
|
||||||
|
name = "/dev/conout";
|
||||||
|
}
|
||||||
|
else if (FlushConsoleInputBuffer (handle))
|
||||||
|
{
|
||||||
|
bin = 0;
|
||||||
|
if (ISSTATE (myself, PID_USETTY))
|
||||||
|
name = "/dev/tty";
|
||||||
|
else
|
||||||
|
name = "/dev/conin";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
build_fhandler (fd, name, handle)->init (handle, myaccess, bin);
|
||||||
|
set_std_handle (fd);
|
||||||
|
paranoid_printf ("fd %d, handle %p", fd, handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int
|
||||||
|
cygwin_attach_handle_to_fd (char *name, int fd, HANDLE handle, mode_t bin,
|
||||||
|
DWORD myaccess)
|
||||||
|
{
|
||||||
|
if (fd == -1)
|
||||||
|
fd = dtable.find_unused_handle();
|
||||||
|
fhandler_base *res = dtable.build_fhandler (fd, name, handle);
|
||||||
|
res->init (handle, myaccess, bin);
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
fhandler_base *
|
||||||
|
hinfo::build_fhandler (int fd, const char *name, HANDLE handle)
|
||||||
|
{
|
||||||
|
int unit;
|
||||||
|
DWORD devn;
|
||||||
|
|
||||||
|
if ((devn = get_device_number (name, unit)) == FH_BAD)
|
||||||
|
{
|
||||||
|
struct sockaddr sa;
|
||||||
|
int sal = sizeof (sa);
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO cinfo;
|
||||||
|
DCB dcb;
|
||||||
|
|
||||||
|
if (handle == NULL)
|
||||||
|
devn = FH_DISK;
|
||||||
|
else if (GetNumberOfConsoleInputEvents (handle, (DWORD *) &cinfo))
|
||||||
|
devn = FH_CONIN;
|
||||||
|
else if (GetConsoleScreenBufferInfo (handle, &cinfo))
|
||||||
|
devn= FH_CONOUT;
|
||||||
|
else if (wsock32_handle && getpeername ((SOCKET) handle, &sa, &sal))
|
||||||
|
devn = FH_SOCKET;
|
||||||
|
else if (GetFileType (handle) == FILE_TYPE_PIPE)
|
||||||
|
devn = FH_PIPE;
|
||||||
|
else if (GetCommState (handle, &dcb))
|
||||||
|
devn = FH_SERIAL;
|
||||||
|
else
|
||||||
|
devn = FH_DISK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return build_fhandler (fd, devn, name, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
fhandler_base *
|
||||||
|
hinfo::build_fhandler (int fd, DWORD dev, const char *name, int unit)
|
||||||
|
{
|
||||||
|
fhandler_base *fh;
|
||||||
|
void *buf = calloc (1, sizeof (fhandler_union) + 100);
|
||||||
|
|
||||||
|
switch (dev & FH_DEVMASK)
|
||||||
|
{
|
||||||
|
case FH_TTYM:
|
||||||
|
fh = new (buf) fhandler_tty_master (name, unit);
|
||||||
|
break;
|
||||||
|
case FH_CONSOLE:
|
||||||
|
case FH_CONIN:
|
||||||
|
case FH_CONOUT:
|
||||||
|
fh = new (buf) fhandler_console (name);
|
||||||
|
break;
|
||||||
|
case FH_PTYM:
|
||||||
|
fh = new (buf) fhandler_pty_master (name);
|
||||||
|
break;
|
||||||
|
case FH_TTYS:
|
||||||
|
if (unit < 0)
|
||||||
|
fh = new (buf) fhandler_tty_slave (name);
|
||||||
|
else
|
||||||
|
fh = new (buf) fhandler_tty_slave (unit, name);
|
||||||
|
break;
|
||||||
|
case FH_WINDOWS:
|
||||||
|
fh = new (buf) fhandler_windows (name);
|
||||||
|
break;
|
||||||
|
case FH_SERIAL:
|
||||||
|
fh = new (buf) fhandler_serial (name, FH_SERIAL, unit);
|
||||||
|
break;
|
||||||
|
case FH_PIPE:
|
||||||
|
case FH_PIPER:
|
||||||
|
case FH_PIPEW:
|
||||||
|
fh = new (buf) fhandler_pipe (name);
|
||||||
|
break;
|
||||||
|
case FH_SOCKET:
|
||||||
|
fh = new (buf) fhandler_socket (name);
|
||||||
|
break;
|
||||||
|
case FH_DISK:
|
||||||
|
fh = new (buf) fhandler_disk_file (NULL);
|
||||||
|
break;
|
||||||
|
case FH_FLOPPY:
|
||||||
|
fh = new (buf) fhandler_dev_floppy (name, unit);
|
||||||
|
break;
|
||||||
|
case FH_TAPE:
|
||||||
|
fh = new (buf) fhandler_dev_tape (name, unit);
|
||||||
|
break;
|
||||||
|
case FH_NULL:
|
||||||
|
fh = new (buf) fhandler_dev_null (name);
|
||||||
|
break;
|
||||||
|
case FH_ZERO:
|
||||||
|
fh = new (buf) fhandler_dev_zero (name);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* FIXME - this could recurse forever */
|
||||||
|
return build_fhandler (fd, name, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_printf ("%s - cb %d, fd %d, fh %p", fh->get_name () ?: "", fh->cb,
|
||||||
|
fd, fh);
|
||||||
|
return fd >= 0 ? (fds[fd] = fh) : fh;
|
||||||
|
}
|
||||||
|
|
||||||
|
fhandler_base *
|
||||||
|
hinfo::dup_worker (fhandler_base *oldfh)
|
||||||
|
{
|
||||||
|
fhandler_base *newfh = build_fhandler (-1, oldfh->get_device (), NULL);
|
||||||
|
*newfh = *oldfh;
|
||||||
|
newfh->set_io_handle (NULL);
|
||||||
|
if (oldfh->dup (newfh))
|
||||||
|
{
|
||||||
|
free (newfh);
|
||||||
|
newfh = NULL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
newfh->set_close_on_exec_flag (0);
|
||||||
|
MALLOC_CHECK;
|
||||||
|
return newfh;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
hinfo::dup2 (int oldfd, int newfd)
|
||||||
|
{
|
||||||
|
int res = -1;
|
||||||
|
fhandler_base *newfh = NULL; // = NULL to avoid an incorrect warning
|
||||||
|
|
||||||
|
MALLOC_CHECK;
|
||||||
|
debug_printf ("dup2 (%d, %d)", oldfd, newfd);
|
||||||
|
|
||||||
|
if (not_open (oldfd))
|
||||||
|
{
|
||||||
|
syscall_printf("dup2: fd %d not open", oldfd);
|
||||||
|
set_errno (EBADF);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newfd == oldfd)
|
||||||
|
{
|
||||||
|
res = 0;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((newfh = dup_worker (fds[oldfd])) == NULL)
|
||||||
|
{
|
||||||
|
res = -1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetResourceLock(LOCK_FD_LIST,WRITE_LOCK|READ_LOCK,"dup");
|
||||||
|
if (!not_open (newfd))
|
||||||
|
_close (newfd);
|
||||||
|
fds[newfd] = newfh;
|
||||||
|
ReleaseResourceLock(LOCK_FD_LIST,WRITE_LOCK|READ_LOCK,"dup");
|
||||||
|
MALLOC_CHECK;
|
||||||
|
|
||||||
|
if ((res = newfd) <= 2)
|
||||||
|
set_std_handle (res);
|
||||||
|
|
||||||
|
MALLOC_CHECK;
|
||||||
|
done:
|
||||||
|
syscall_printf ("%d = dup2 (%d, %d)", res, oldfd, newfd);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
select_record *
|
||||||
|
hinfo::select_read (int fd, select_record *s)
|
||||||
|
{
|
||||||
|
if (dtable.not_open (fd))
|
||||||
|
{
|
||||||
|
set_errno (EBADF);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
fhandler_base *fh = dtable[fd];
|
||||||
|
s = fh->select_read (s);
|
||||||
|
s->fd = fd;
|
||||||
|
s->fh = fh;
|
||||||
|
s->saw_error = 0;
|
||||||
|
debug_printf ("%s fd %d", fh->get_name (), fd);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
select_record *
|
||||||
|
hinfo::select_write (int fd, select_record *s)
|
||||||
|
{
|
||||||
|
if (dtable.not_open (fd))
|
||||||
|
{
|
||||||
|
set_errno (EBADF);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
fhandler_base *fh = dtable[fd];
|
||||||
|
s = fh->select_write (s);
|
||||||
|
s->fd = fd;
|
||||||
|
s->fh = fh;
|
||||||
|
s->saw_error = 0;
|
||||||
|
debug_printf ("%s fd %d", fh->get_name (), fd);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
select_record *
|
||||||
|
hinfo::select_except (int fd, select_record *s)
|
||||||
|
{
|
||||||
|
if (dtable.not_open (fd))
|
||||||
|
{
|
||||||
|
set_errno (EBADF);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
fhandler_base *fh = dtable[fd];
|
||||||
|
s = fh->select_except (s);
|
||||||
|
s->fd = fd;
|
||||||
|
s->fh = fh;
|
||||||
|
s->saw_error = 0;
|
||||||
|
debug_printf ("%s fd %d", fh->get_name (), fd);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function to take an existant hinfo array
|
||||||
|
* and linearize it into a memory buffer.
|
||||||
|
* If memory buffer is NULL, it returns the size
|
||||||
|
* of memory buffer needed to do the linearization.
|
||||||
|
* On error returns -1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
hinfo::linearize_fd_array (unsigned char *in_buf, int buflen)
|
||||||
|
{
|
||||||
|
/* If buf == NULL, just precalculate length */
|
||||||
|
if (in_buf == NULL)
|
||||||
|
{
|
||||||
|
buflen = sizeof (size_t);
|
||||||
|
for (int i = 0, max_used_fd = -1; i < (int)size; i++)
|
||||||
|
if (!not_open (i) && !fds[i]->get_close_on_exec ())
|
||||||
|
{
|
||||||
|
buflen += i - (max_used_fd + 1);
|
||||||
|
buflen += fds[i]->cb + strlen (fds[i]->get_name ()) + 1
|
||||||
|
+ strlen (fds[i]->get_win32_name ()) + 1;
|
||||||
|
max_used_fd = i;
|
||||||
|
}
|
||||||
|
debug_printf ("needed buflen %d", buflen);
|
||||||
|
return buflen;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_printf ("in_buf = %x, buflen = %d", in_buf, buflen);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now linearize each open fd (write a 0xff byte for a closed fd).
|
||||||
|
* Write the name of the open fd first (null terminated). This
|
||||||
|
* allows the de_linearizeing code to determine what kind of fhandler_xxx
|
||||||
|
* to create.
|
||||||
|
*/
|
||||||
|
|
||||||
|
size_t i;
|
||||||
|
int len, total_size;
|
||||||
|
|
||||||
|
total_size = sizeof (size_t);
|
||||||
|
if (total_size > buflen)
|
||||||
|
{
|
||||||
|
system_printf ("FATAL: linearize_fd_array exceeded buffer size");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char *buf = in_buf;
|
||||||
|
buf += sizeof (size_t); /* skip over length which is added later */
|
||||||
|
|
||||||
|
for (i = 0, total_size = sizeof (size_t); total_size < buflen; i++)
|
||||||
|
{
|
||||||
|
if (not_open (i) || fds[i]->get_close_on_exec ())
|
||||||
|
{
|
||||||
|
debug_printf ("linearizing closed fd %d",i);
|
||||||
|
*buf = 0xff; /* place holder */
|
||||||
|
len = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
len = fds[i]->linearize (buf);
|
||||||
|
debug_printf ("fd %d, len %d, name %s, device %p", i, len, buf,
|
||||||
|
fds[i]->get_device ());
|
||||||
|
}
|
||||||
|
|
||||||
|
total_size += len;
|
||||||
|
buf += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
i--;
|
||||||
|
memcpy (in_buf, &i, sizeof (size_t));
|
||||||
|
if (total_size != buflen)
|
||||||
|
system_printf ("out of sync %d != %d", total_size, buflen);
|
||||||
|
return total_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function to take a linearized hinfo array in a memory buffer and
|
||||||
|
* re-create the original hinfo array.
|
||||||
|
*/
|
||||||
|
|
||||||
|
LPBYTE
|
||||||
|
hinfo::de_linearize_fd_array (LPBYTE buf)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
size_t max_used_fd, inc_size;
|
||||||
|
|
||||||
|
debug_printf ("buf %x", buf);
|
||||||
|
|
||||||
|
/* First get the number of fd's - use this to set the dtablesize.
|
||||||
|
NB. This is the only place in the code this should be done !!
|
||||||
|
*/
|
||||||
|
|
||||||
|
memcpy ((char *) &max_used_fd, buf, sizeof (int));
|
||||||
|
buf += sizeof (size_t);
|
||||||
|
|
||||||
|
inc_size = NOFILE_INCR * ((max_used_fd + NOFILE_INCR - 1) / NOFILE_INCR) -
|
||||||
|
size;
|
||||||
|
debug_printf ("max_used_fd %d, inc size %d", max_used_fd, inc_size);
|
||||||
|
if (inc_size > 0 && !extend (inc_size))
|
||||||
|
{
|
||||||
|
system_printf ("out of memory");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i <= max_used_fd; i++)
|
||||||
|
{
|
||||||
|
/* 0xFF means closed */
|
||||||
|
if (*buf == 0xff)
|
||||||
|
{
|
||||||
|
fds[i] = NULL;
|
||||||
|
buf++;
|
||||||
|
debug_printf ("closed fd %d", i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* fd was open - de_linearize it */
|
||||||
|
/* Get the null-terminated name. It is followed by an image of
|
||||||
|
the actual fhandler_* structure. Use the status field from
|
||||||
|
this to build a new fhandler type. */
|
||||||
|
|
||||||
|
DWORD status;
|
||||||
|
LPBYTE obuf = buf;
|
||||||
|
char *win32;
|
||||||
|
win32 = strchr ((char *)obuf, '\0') + 1;
|
||||||
|
buf = (LPBYTE)strchr ((char *)win32, '\0') + 1;
|
||||||
|
memcpy ((char *)&status, buf + FHSTATOFF, sizeof(DWORD));
|
||||||
|
debug_printf ("fd %d, name %s, win32 name %s, status %p",
|
||||||
|
i, obuf, win32, status);
|
||||||
|
len = build_fhandler (i, status, (const char *) NULL)->
|
||||||
|
de_linearize ((char *) buf, (char *) obuf, win32);
|
||||||
|
set_std_handle (i);
|
||||||
|
buf += len;
|
||||||
|
debug_printf ("len %d", buf - obuf);
|
||||||
|
}
|
||||||
|
first_fd_for_open = 0;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hinfo::fixup_after_fork (HANDLE parent)
|
||||||
|
{
|
||||||
|
SetResourceLock(LOCK_FD_LIST,WRITE_LOCK|READ_LOCK,"dup");
|
||||||
|
for (size_t i = 0; i < size; i++)
|
||||||
|
if (!not_open (i))
|
||||||
|
{
|
||||||
|
fhandler_base *fh = fds[i];
|
||||||
|
if (fh->get_close_on_exec () || fh->get_need_fork_fixup ())
|
||||||
|
{
|
||||||
|
debug_printf ("fd %d(%s)", i, fh->get_name ());
|
||||||
|
fh->fixup_after_fork (parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ReleaseResourceLock(LOCK_FD_LIST,WRITE_LOCK|READ_LOCK,"dup");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
hinfo::vfork_child_dup ()
|
||||||
|
{
|
||||||
|
fhandler_base **newtable;
|
||||||
|
newtable = (fhandler_base **) calloc (size, sizeof(fds[0]));
|
||||||
|
int res = 1;
|
||||||
|
|
||||||
|
SetResourceLock(LOCK_FD_LIST,WRITE_LOCK|READ_LOCK,"dup");
|
||||||
|
for (size_t i = 0; i < size; i++)
|
||||||
|
if (not_open (i))
|
||||||
|
continue;
|
||||||
|
else if ((newtable[i] = dup_worker (fds[i])) == NULL)
|
||||||
|
{
|
||||||
|
res = 0;
|
||||||
|
set_errno (EBADF);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
fds_on_hold = fds;
|
||||||
|
fds = newtable;
|
||||||
|
out:
|
||||||
|
ReleaseResourceLock(LOCK_FD_LIST,WRITE_LOCK|READ_LOCK,"dup");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hinfo::vfork_parent_restore ()
|
||||||
|
{
|
||||||
|
SetResourceLock(LOCK_FD_LIST,WRITE_LOCK|READ_LOCK,"dup");
|
||||||
|
|
||||||
|
close_all_files ();
|
||||||
|
fhandler_base **deleteme = fds;
|
||||||
|
fds = fds_on_hold;
|
||||||
|
fds_on_hold = NULL;
|
||||||
|
free (deleteme);
|
||||||
|
|
||||||
|
ReleaseResourceLock(LOCK_FD_LIST,WRITE_LOCK|READ_LOCK,"dup");
|
||||||
|
return;
|
||||||
|
}
|
20
winsup/cygwin/dtable.sgml
Normal file
20
winsup/cygwin/dtable.sgml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
<sect1 id="func-cygwin-attach-handle-to-fd">
|
||||||
|
<title>cygwin_attach_handle_to_fd</title>
|
||||||
|
|
||||||
|
<funcsynopsis>
|
||||||
|
<funcdef>extern "C" int
|
||||||
|
<function>cygwin_attach_handle_to_fd</function></funcdef>
|
||||||
|
<paramdef>char *<parameter>name</parameter></paramdef>
|
||||||
|
<paramdef>int <parameter>fd</parameter></paramdef>
|
||||||
|
<paramdef>HANDLE <parameter>handle</parameter></paramdef>
|
||||||
|
<paramdef>int <parameter>bin</parameter></paramdef>
|
||||||
|
<paramdef>int <parameter>access</parameter></paramdef>
|
||||||
|
</funcsynopsis>
|
||||||
|
|
||||||
|
<para>This function can be used to turn a Win32 "handle" into a
|
||||||
|
posix-style file handle. <parameter>fd</parameter> may be -1 to
|
||||||
|
make cygwin allocate a handle; the actual handle is returned
|
||||||
|
in all cases.</para>
|
||||||
|
|
||||||
|
</sect1>
|
567
winsup/cygwin/environ.cc
Normal file
567
winsup/cygwin/environ.cc
Normal file
@ -0,0 +1,567 @@
|
|||||||
|
/* environ.cc: Cygwin-adopted functions from newlib to manipulate
|
||||||
|
process's environment.
|
||||||
|
|
||||||
|
Copyright 1997, 1998, 1999, 2000 Cygnus Solutions.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include "winsup.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#define environ (*user_data->envptr)
|
||||||
|
|
||||||
|
extern BOOL allow_glob;
|
||||||
|
extern BOOL allow_ntea;
|
||||||
|
extern BOOL strip_title_path;
|
||||||
|
extern DWORD chunksize;
|
||||||
|
extern BOOL oldstack;
|
||||||
|
BOOL threadsafe;
|
||||||
|
BOOL reset_com = TRUE;
|
||||||
|
static BOOL envcache = TRUE;
|
||||||
|
|
||||||
|
/* List of names which are converted from dos to unix
|
||||||
|
* on the way in and back again on the way out.
|
||||||
|
*
|
||||||
|
* PATH needs to be here because CreateProcess uses it and gdb uses
|
||||||
|
* CreateProcess. HOME is here because most shells use it and would be
|
||||||
|
* confused by Windows style path names.
|
||||||
|
*/
|
||||||
|
static int return_MAX_PATH (const char *) {return MAX_PATH;}
|
||||||
|
static win_env conv_envvars[] =
|
||||||
|
{
|
||||||
|
{"PATH=", 5, NULL, NULL, cygwin_win32_to_posix_path_list,
|
||||||
|
cygwin_posix_to_win32_path_list,
|
||||||
|
cygwin_win32_to_posix_path_list_buf_size,
|
||||||
|
cygwin_posix_to_win32_path_list_buf_size},
|
||||||
|
{"HOME=", 5, NULL, NULL, cygwin_conv_to_full_posix_path, cygwin_conv_to_full_win32_path,
|
||||||
|
return_MAX_PATH, return_MAX_PATH},
|
||||||
|
{"LD_LIBRARY_PATH=", 16, NULL, NULL, cygwin_conv_to_full_posix_path,
|
||||||
|
cygwin_conv_to_full_win32_path, return_MAX_PATH, return_MAX_PATH},
|
||||||
|
{NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
win_env::add_cache (const char *in_posix, const char *in_native)
|
||||||
|
{
|
||||||
|
posix = (char *) realloc (posix, strlen (in_posix) + 1);
|
||||||
|
strcpy (posix, in_posix);
|
||||||
|
if (in_native)
|
||||||
|
{
|
||||||
|
native = (char *) realloc (native, namelen + 1 + strlen (in_native));
|
||||||
|
(void) strcpy (native, name);
|
||||||
|
(void) strcpy (native + namelen, in_native);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
native = (char *) realloc (native, namelen + 1 + win32_len (in_posix));
|
||||||
|
(void) strcpy (native, name);
|
||||||
|
towin32 (in_posix, native + namelen);
|
||||||
|
}
|
||||||
|
debug_printf ("posix %s", posix);
|
||||||
|
debug_printf ("native %s", native);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Check for a "special" environment variable name. *env is the pointer
|
||||||
|
* to the beginning of the environment variable name. n is the length
|
||||||
|
* of the name including a mandatory '='. Returns a pointer to the
|
||||||
|
* appropriate conversion structure.
|
||||||
|
*/
|
||||||
|
win_env *
|
||||||
|
getwinenv (const char *env, const char *in_posix)
|
||||||
|
{
|
||||||
|
for (int i = 0; conv_envvars[i].name != NULL; i++)
|
||||||
|
if (strncasematch (env, conv_envvars[i].name, conv_envvars[i].namelen))
|
||||||
|
{
|
||||||
|
win_env *we = conv_envvars + i;
|
||||||
|
const char *val;
|
||||||
|
if (!environ || !(val = in_posix ?: getenv(we->name)))
|
||||||
|
debug_printf ("can't set native for %s since no environ yet",
|
||||||
|
we->name);
|
||||||
|
else if (!envcache || !we->posix || strcmp (val, we->posix))
|
||||||
|
we->add_cache (val);
|
||||||
|
return we;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert windows path specs to POSIX, if appropriate.
|
||||||
|
*/
|
||||||
|
static void __stdcall
|
||||||
|
posify (char **here, const char *value)
|
||||||
|
{
|
||||||
|
char *src = *here;
|
||||||
|
win_env *conv;
|
||||||
|
int len = strcspn (src, "=") + 1;
|
||||||
|
|
||||||
|
if (!(conv = getwinenv (src)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Turn all the items from c:<foo>;<bar> into their
|
||||||
|
mounted equivalents - if there is one. */
|
||||||
|
|
||||||
|
char *outenv = (char *) malloc (1 + len + conv->posix_len (value));
|
||||||
|
memcpy (outenv, src, len);
|
||||||
|
conv->toposix (value, outenv + len);
|
||||||
|
conv->add_cache (outenv + len, value);
|
||||||
|
|
||||||
|
debug_printf ("env var converted to %s", outenv);
|
||||||
|
*here = outenv;
|
||||||
|
free (src);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* my_findenv --
|
||||||
|
* Returns pointer to value associated with name, if any, else NULL.
|
||||||
|
* Sets offset to be the offset of the name/value combination in the
|
||||||
|
* environment array, for use by setenv(3) and unsetenv(3).
|
||||||
|
* Explicitly removes '=' in argument name.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static char * __stdcall
|
||||||
|
my_findenv (const char *name, int *offset)
|
||||||
|
{
|
||||||
|
register int len;
|
||||||
|
register char **p;
|
||||||
|
const char *c;
|
||||||
|
|
||||||
|
c = name;
|
||||||
|
len = 0;
|
||||||
|
while (*c && *c != '=')
|
||||||
|
{
|
||||||
|
c++;
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (p = environ; *p; ++p)
|
||||||
|
if (!strncmp (*p, name, len))
|
||||||
|
if (*(c = *p + len) == '=')
|
||||||
|
{
|
||||||
|
*offset = p - environ;
|
||||||
|
return (char *) (++c);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* getenv --
|
||||||
|
* Returns ptr to value associated with name, if any, else NULL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
char *
|
||||||
|
getenv (const char *name)
|
||||||
|
{
|
||||||
|
int offset;
|
||||||
|
|
||||||
|
return my_findenv (name, &offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* putenv --
|
||||||
|
* Sets an environment variable
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int
|
||||||
|
putenv (const char *str)
|
||||||
|
{
|
||||||
|
register char *p, *equal;
|
||||||
|
int rval;
|
||||||
|
|
||||||
|
if (!(p = strdup (str)))
|
||||||
|
return 1;
|
||||||
|
if (!(equal = index (p, '=')))
|
||||||
|
{
|
||||||
|
(void) free (p);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
*equal = '\0';
|
||||||
|
rval = setenv (p, equal + 1, 1);
|
||||||
|
(void) free (p);
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* setenv --
|
||||||
|
* Set the value of the environment variable "name" to be
|
||||||
|
* "value". If rewrite is set, replace any current value.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int
|
||||||
|
setenv (const char *name, const char *value, int rewrite)
|
||||||
|
{
|
||||||
|
register char *C;
|
||||||
|
unsigned int l_value;
|
||||||
|
int offset;
|
||||||
|
|
||||||
|
if (*value == '=') /* no `=' in value */
|
||||||
|
++value;
|
||||||
|
l_value = strlen (value);
|
||||||
|
if ((C = my_findenv (name, &offset)))
|
||||||
|
{ /* find if already exists */
|
||||||
|
if (!rewrite)
|
||||||
|
return 0;
|
||||||
|
if (strlen (C) >= l_value)
|
||||||
|
{ /* old larger; copy over */
|
||||||
|
while ((*C++ = *value++));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* create new slot */
|
||||||
|
register int cnt;
|
||||||
|
register char **P;
|
||||||
|
|
||||||
|
for (P = environ, cnt = 0; *P; ++P, ++cnt)
|
||||||
|
;
|
||||||
|
__cygwin_environ = environ = (char **) realloc ((char *) environ,
|
||||||
|
(size_t) (sizeof (char *) * (cnt + 2)));
|
||||||
|
if (!environ)
|
||||||
|
return -1;
|
||||||
|
environ[cnt + 1] = NULL;
|
||||||
|
offset = cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (C = (char *) name; *C && *C != '='; ++C); /* no `=' in name */
|
||||||
|
|
||||||
|
if (!(environ[offset] = /* name + `=' + value */
|
||||||
|
(char *) malloc ((size_t) ((int) (C - name) + l_value + 2))))
|
||||||
|
return -1;
|
||||||
|
for (C = environ[offset]; (*C = *name++) && *C != '='; ++C);
|
||||||
|
*C++ = '=';
|
||||||
|
strcpy (C, value);
|
||||||
|
|
||||||
|
win_env *spenv;
|
||||||
|
if ((spenv = getwinenv (environ[offset])))
|
||||||
|
spenv->add_cache (value);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* unsetenv(name) --
|
||||||
|
* Delete environment variable "name".
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
void
|
||||||
|
unsetenv (const char *name)
|
||||||
|
{
|
||||||
|
register char **P;
|
||||||
|
int offset;
|
||||||
|
|
||||||
|
while (my_findenv (name, &offset)) /* if set multiple times */
|
||||||
|
for (P = &environ[offset];; ++P)
|
||||||
|
if (!(*P = *(P + 1)))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Turn environment variable part of a=b string into uppercase. */
|
||||||
|
|
||||||
|
static void __inline
|
||||||
|
ucenv (char *p, char *eq)
|
||||||
|
{
|
||||||
|
/* Amazingly, NT has a case sensitive environment name list,
|
||||||
|
but only sometimes.
|
||||||
|
It's normal to have NT set your "Path" to something.
|
||||||
|
Later, you set "PATH" to something else. This alters "Path".
|
||||||
|
But if you try and do a naive getenv on "PATH" you'll get nothing.
|
||||||
|
|
||||||
|
So we upper case the labels here to prevent confusion later but
|
||||||
|
we only do it for the first process in a session group. */
|
||||||
|
for (; p < eq; p++)
|
||||||
|
if (islower (*p))
|
||||||
|
*p = toupper (*p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse CYGWIN options */
|
||||||
|
|
||||||
|
static NO_COPY BOOL export_settings = FALSE;
|
||||||
|
|
||||||
|
enum settings
|
||||||
|
{
|
||||||
|
justset,
|
||||||
|
isfunc,
|
||||||
|
setbit,
|
||||||
|
set_process_state,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The structure below is used to set up an array which is used to
|
||||||
|
* parse the CYGWIN environment variable or, if enabled, options from
|
||||||
|
* the registry.
|
||||||
|
*/
|
||||||
|
struct parse_thing
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
union parse_setting
|
||||||
|
{
|
||||||
|
BOOL *b;
|
||||||
|
DWORD *x;
|
||||||
|
int *i;
|
||||||
|
void (*func)(const char *);
|
||||||
|
} setting;
|
||||||
|
|
||||||
|
enum settings disposition;
|
||||||
|
char *remember;
|
||||||
|
union parse_values
|
||||||
|
{
|
||||||
|
DWORD i;
|
||||||
|
const char *s;
|
||||||
|
} values[2];
|
||||||
|
} known[] =
|
||||||
|
{
|
||||||
|
{"binmode", {&__fmode}, justset, NULL, {{O_TEXT}, {O_BINARY}}},
|
||||||
|
{"envcache", {&envcache}, justset, NULL, {{TRUE}, {FALSE}}},
|
||||||
|
{"error_start", {func: &error_start_init}, isfunc, NULL, {{0}, {0}}},
|
||||||
|
{"export", {&export_settings}, justset, NULL, {{FALSE}, {TRUE}}},
|
||||||
|
{"forkchunk", {x: &chunksize}, justset, NULL, {{8192}, {0}}},
|
||||||
|
{"glob", {&allow_glob}, justset, NULL, {{FALSE}, {TRUE}}},
|
||||||
|
{"ntea", {&allow_ntea}, justset, NULL, {{FALSE}, {TRUE}}},
|
||||||
|
{"ntsec", {&allow_ntsec}, justset, NULL, {{FALSE}, {TRUE}}},
|
||||||
|
{"oldstack", {&oldstack}, justset, NULL, {{FALSE}, {TRUE}}},
|
||||||
|
{"reset_com", {&reset_com}, justset, NULL, {{FALSE}, {TRUE}}},
|
||||||
|
{"strip_title", {&strip_title_path}, justset, NULL, {{FALSE}, {TRUE}}},
|
||||||
|
{"title", {&display_title}, justset, NULL, {{FALSE}, {TRUE}}},
|
||||||
|
{"tty", {NULL}, set_process_state, NULL, {{0}, {PID_USETTY}}},
|
||||||
|
{"threadsafe", {&threadsafe}, justset, NULL, {{TRUE}, {FALSE}}},
|
||||||
|
{NULL, {0}, justset, 0, {{0}, {0}}}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Parse a string of the form "something=stuff somethingelse=more-stuff",
|
||||||
|
* silently ignoring unknown "somethings".
|
||||||
|
*/
|
||||||
|
static void __stdcall
|
||||||
|
parse_options (char *buf)
|
||||||
|
{
|
||||||
|
int istrue;
|
||||||
|
char *p;
|
||||||
|
parse_thing *k;
|
||||||
|
|
||||||
|
if (buf == NULL)
|
||||||
|
{
|
||||||
|
char newbuf[MAX_PATH + 7] = "CYGWIN";
|
||||||
|
for (k = known; k->name != NULL; k++)
|
||||||
|
if (k->remember)
|
||||||
|
{
|
||||||
|
strcat (strcat (newbuf, " "), k->remember);
|
||||||
|
free (k->remember);
|
||||||
|
k->remember = NULL;
|
||||||
|
}
|
||||||
|
if (!export_settings)
|
||||||
|
return;
|
||||||
|
newbuf[sizeof ("CYGWIN") - 1] = '=';
|
||||||
|
debug_printf ("%s", newbuf);
|
||||||
|
putenv (newbuf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = strcpy ((char *) alloca (strlen (buf) + 1), buf);
|
||||||
|
for (p = strtok (buf, " \t"); p != NULL; p = strtok (NULL, " \t"))
|
||||||
|
{
|
||||||
|
if (!(istrue = !strncasematch (p, "no", 2)))
|
||||||
|
p += 2;
|
||||||
|
else if (!(istrue = *p != '-'))
|
||||||
|
p++;
|
||||||
|
|
||||||
|
char ch, *eq;
|
||||||
|
if ((eq = strchr (p, '=')) != NULL || (eq = strchr (p, ':')) != NULL)
|
||||||
|
ch = *eq, *eq++ = '\0';
|
||||||
|
else
|
||||||
|
ch = 0;
|
||||||
|
|
||||||
|
for (parse_thing *k = known; k->name != NULL; k++)
|
||||||
|
if (strcasematch (p, k->name))
|
||||||
|
{
|
||||||
|
switch (k->disposition)
|
||||||
|
{
|
||||||
|
case isfunc:
|
||||||
|
k->setting.func ((!eq || !istrue) ?
|
||||||
|
k->values[istrue].s : eq);
|
||||||
|
debug_printf ("%s (called func)", k->name);
|
||||||
|
break;
|
||||||
|
case justset:
|
||||||
|
if (!istrue || !eq)
|
||||||
|
*k->setting.x = k->values[istrue].i;
|
||||||
|
else
|
||||||
|
*k->setting.x = strtol (eq, NULL, 0);
|
||||||
|
debug_printf ("%s %d", k->name, *k->setting.x);
|
||||||
|
break;
|
||||||
|
case set_process_state:
|
||||||
|
k->setting.x = &myself->process_state;
|
||||||
|
/* fall through */
|
||||||
|
case setbit:
|
||||||
|
*k->setting.x &= ~k->values[istrue].i;
|
||||||
|
if (istrue || (eq && strtol (eq, NULL, 0)))
|
||||||
|
*k->setting.x |= k->values[istrue].i;
|
||||||
|
debug_printf ("%s %x", k->name, *k->setting.x);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eq)
|
||||||
|
*--eq = ch;
|
||||||
|
|
||||||
|
int n = eq - p;
|
||||||
|
p = strdup (p);
|
||||||
|
if (n > 0)
|
||||||
|
p[n] = ':';
|
||||||
|
k->remember = p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
debug_printf ("returning");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set options from the registry. */
|
||||||
|
|
||||||
|
static void __stdcall
|
||||||
|
regopt (const char *name)
|
||||||
|
{
|
||||||
|
MALLOC_CHECK;
|
||||||
|
/* FIXME: should not be under mount */
|
||||||
|
reg_key r (KEY_READ, CYGWIN_INFO_PROGRAM_OPTIONS_NAME, NULL);
|
||||||
|
char buf[MAX_PATH];
|
||||||
|
char lname[strlen(name) + 1];
|
||||||
|
strlwr (strcpy (lname, name));
|
||||||
|
MALLOC_CHECK;
|
||||||
|
if (r.get_string (lname, buf, sizeof (buf) - 1, "") == ERROR_SUCCESS)
|
||||||
|
parse_options (buf);
|
||||||
|
MALLOC_CHECK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the environ array. Look for the CYGWIN environment
|
||||||
|
* environment variable and set appropriate options from it.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
environ_init (void)
|
||||||
|
{
|
||||||
|
const char * const rawenv = GetEnvironmentStrings ();
|
||||||
|
int envsize, i;
|
||||||
|
char *newp, **envp;
|
||||||
|
const char *p;
|
||||||
|
int sawTERM = 0;
|
||||||
|
|
||||||
|
/* Allocate space for environment + trailing NULL + CYGWIN env. */
|
||||||
|
envp = (char **) malloc ((4 + (envsize = 100)) * sizeof (char *));
|
||||||
|
|
||||||
|
regopt ("default");
|
||||||
|
if (myself->progname[0])
|
||||||
|
regopt (myself->progname);
|
||||||
|
|
||||||
|
#ifdef NTSEC_ON_BY_DEFAULT
|
||||||
|
/* Set ntsec explicit as default, if NT is running */
|
||||||
|
if (os_being_run == winNT)
|
||||||
|
allow_ntsec = TRUE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Current directory information is recorded as variables of the
|
||||||
|
form "=X:=X:\foo\bar; these must be changed into something legal
|
||||||
|
(we could just ignore them but maybe an application will
|
||||||
|
eventually want to use them). */
|
||||||
|
for (i = 0, p = rawenv; *p != '\0'; p = strchr (p, '\0') + 1, i++)
|
||||||
|
{
|
||||||
|
newp = strdup (p);
|
||||||
|
if (i >= envsize)
|
||||||
|
envp = (char **) realloc (envp, (4 + (envsize += 100)) *
|
||||||
|
sizeof (char *));
|
||||||
|
envp[i] = newp;
|
||||||
|
if (*newp == '=')
|
||||||
|
*newp = '!';
|
||||||
|
char *eq;
|
||||||
|
if ((eq = strchr (newp, '=')) == NULL)
|
||||||
|
eq = strchr (newp, '\0');
|
||||||
|
if (!parent_alive)
|
||||||
|
ucenv (newp, eq);
|
||||||
|
if (strncmp (newp, "TERM=", 5) == 0)
|
||||||
|
sawTERM = 1;
|
||||||
|
if (strncmp (newp, "CYGWIN=", sizeof("CYGWIN=") - 1) == 0)
|
||||||
|
parse_options (newp + sizeof("CYGWIN=") - 1);
|
||||||
|
if (*eq)
|
||||||
|
posify (envp + i, *++eq ? eq : --eq);
|
||||||
|
debug_printf ("%s", envp[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sawTERM)
|
||||||
|
envp[i++] = strdup ("TERM=cygwin");
|
||||||
|
envp[i] = NULL;
|
||||||
|
__cygwin_environ = *user_data->envptr = envp;
|
||||||
|
FreeEnvironmentStringsA ((char *) rawenv);
|
||||||
|
parse_options (NULL);
|
||||||
|
MALLOC_CHECK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Function called by qsort to sort environment strings.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
env_sort (const void *a, const void *b)
|
||||||
|
{
|
||||||
|
const char **p = (const char **) a;
|
||||||
|
const char **q = (const char **) b;
|
||||||
|
|
||||||
|
return strcmp (*p, *q);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a Windows-style environment block, i.e. a typical character buffer
|
||||||
|
* filled with null terminated strings, terminated by double null characters.
|
||||||
|
* Converts environment variables noted in conv_envvars into win32 form
|
||||||
|
* prior to placing them in the string.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
winenv (const char * const *envp)
|
||||||
|
{
|
||||||
|
int len, n, tl;
|
||||||
|
const char * const *srcp;
|
||||||
|
const char * *dstp;
|
||||||
|
|
||||||
|
for (n = 0; envp[n]; n++)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const char *newenvp[n + 1];
|
||||||
|
|
||||||
|
for (tl = 0, srcp = envp, dstp = newenvp; *srcp; srcp++, dstp++)
|
||||||
|
{
|
||||||
|
len = strcspn (*srcp, "=") + 1;
|
||||||
|
win_env *conv;
|
||||||
|
|
||||||
|
if ((conv = getwinenv (*srcp, *srcp + len)))
|
||||||
|
*dstp = conv->native;
|
||||||
|
else
|
||||||
|
*dstp = *srcp;
|
||||||
|
tl += strlen (*dstp) + 1;
|
||||||
|
if ((*dstp)[0] == '!' && isalpha((*dstp)[1]) && (*dstp)[2] == ':' &&
|
||||||
|
(*dstp)[3] == '=')
|
||||||
|
{
|
||||||
|
char *p = (char *) alloca (strlen (*dstp) + 1);
|
||||||
|
strcpy (p, *dstp);
|
||||||
|
*p = '=';
|
||||||
|
*dstp = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*dstp = NULL; /* Terminate */
|
||||||
|
|
||||||
|
int envlen = dstp - newenvp;
|
||||||
|
debug_printf ("env count %d, bytes %d", envlen, tl);
|
||||||
|
|
||||||
|
/* Windows programs expect the environment block to be sorted. */
|
||||||
|
qsort (newenvp, envlen, sizeof (char *), env_sort);
|
||||||
|
|
||||||
|
/* Create an environment block suitable for passing to CreateProcess. */
|
||||||
|
char *ptr, *envblock;
|
||||||
|
envblock = (char *) malloc (tl + 2);
|
||||||
|
for (srcp = newenvp, ptr = envblock; *srcp; srcp++)
|
||||||
|
{
|
||||||
|
len = strlen (*srcp);
|
||||||
|
memcpy (ptr, *srcp, len + 1);
|
||||||
|
ptr += len + 1;
|
||||||
|
}
|
||||||
|
*ptr = '\0'; /* Two null bytes at the end */
|
||||||
|
|
||||||
|
return envblock;
|
||||||
|
}
|
669
winsup/cygwin/errno.cc
Normal file
669
winsup/cygwin/errno.cc
Normal file
@ -0,0 +1,669 @@
|
|||||||
|
/* errno.cc: errno-related functions
|
||||||
|
|
||||||
|
Copyright 1996, 1997, 1998, 1999 Cygnus Solutions.
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#define _REENT_ONLY
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "winsup.h"
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
/* Table to map Windows error codes to Errno values. */
|
||||||
|
/* FIXME: Doing things this way is a little slow. It's trivial to change
|
||||||
|
this into a big case statement if necessary. Left as is for now. */
|
||||||
|
|
||||||
|
#define X(w, e) {ERROR_##w, #w, e}
|
||||||
|
|
||||||
|
static const struct
|
||||||
|
{
|
||||||
|
int w; /* windows version of error */
|
||||||
|
const char *s; /* text of windows version */
|
||||||
|
int e; /* errno version of error */
|
||||||
|
}
|
||||||
|
errmap[] =
|
||||||
|
{
|
||||||
|
/* FIXME: Some of these choices are arbitrary! */
|
||||||
|
X (INVALID_FUNCTION, EBADRQC),
|
||||||
|
X (FILE_NOT_FOUND, ENOENT),
|
||||||
|
X (PATH_NOT_FOUND, ENOENT),
|
||||||
|
X (TOO_MANY_OPEN_FILES, EMFILE),
|
||||||
|
X (ACCESS_DENIED, EACCES),
|
||||||
|
X (INVALID_HANDLE, EBADF),
|
||||||
|
X (NOT_ENOUGH_MEMORY, ENOMEM),
|
||||||
|
X (INVALID_DATA, EINVAL),
|
||||||
|
X (OUTOFMEMORY, ENOMEM),
|
||||||
|
X (INVALID_DRIVE, ENODEV),
|
||||||
|
X (NOT_SAME_DEVICE, EXDEV),
|
||||||
|
X (NO_MORE_FILES, ENMFILE),
|
||||||
|
X (WRITE_PROTECT, EROFS),
|
||||||
|
X (BAD_UNIT, ENODEV),
|
||||||
|
X (SHARING_VIOLATION, EACCES),
|
||||||
|
X (LOCK_VIOLATION, EACCES),
|
||||||
|
X (SHARING_BUFFER_EXCEEDED, ENOLCK),
|
||||||
|
X (HANDLE_EOF, ENODATA),
|
||||||
|
X (HANDLE_DISK_FULL, ENOSPC),
|
||||||
|
X (NOT_SUPPORTED, ENOSYS),
|
||||||
|
X (REM_NOT_LIST, ENONET),
|
||||||
|
X (DUP_NAME, ENOTUNIQ),
|
||||||
|
X (BAD_NETPATH, ENXIO),
|
||||||
|
X (FILE_EXISTS, EEXIST),
|
||||||
|
X (CANNOT_MAKE, EPERM),
|
||||||
|
X (INVALID_PARAMETER, EINVAL),
|
||||||
|
X (NO_PROC_SLOTS, EAGAIN),
|
||||||
|
X (BROKEN_PIPE, EPIPE),
|
||||||
|
X (OPEN_FAILED, EIO),
|
||||||
|
X (NO_MORE_SEARCH_HANDLES, ENFILE),
|
||||||
|
X (CALL_NOT_IMPLEMENTED, ENOSYS),
|
||||||
|
X (INVALID_NAME, ENOENT),
|
||||||
|
X (WAIT_NO_CHILDREN, ECHILD),
|
||||||
|
X (CHILD_NOT_COMPLETE, EBUSY),
|
||||||
|
X (DIR_NOT_EMPTY, ENOTEMPTY),
|
||||||
|
X (SIGNAL_REFUSED, EIO),
|
||||||
|
X (BAD_PATHNAME, EINVAL),
|
||||||
|
X (SIGNAL_PENDING, EBUSY),
|
||||||
|
X (MAX_THRDS_REACHED, EAGAIN),
|
||||||
|
X (BUSY, EBUSY),
|
||||||
|
X (ALREADY_EXISTS, EEXIST),
|
||||||
|
X (NO_SIGNAL_SENT, EIO),
|
||||||
|
X (FILENAME_EXCED_RANGE, EINVAL),
|
||||||
|
X (META_EXPANSION_TOO_LONG, EINVAL),
|
||||||
|
X (INVALID_SIGNAL_NUMBER, EINVAL),
|
||||||
|
X (THREAD_1_INACTIVE, EINVAL),
|
||||||
|
X (BAD_PIPE, EINVAL),
|
||||||
|
X (PIPE_BUSY, EBUSY),
|
||||||
|
X (NO_DATA, EPIPE),
|
||||||
|
X (PIPE_NOT_CONNECTED, ECOMM),
|
||||||
|
X (MORE_DATA, EAGAIN),
|
||||||
|
X (DIRECTORY, EISDIR),
|
||||||
|
X (PIPE_CONNECTED, EBUSY),
|
||||||
|
X (PIPE_LISTENING, ECOMM),
|
||||||
|
X (NO_TOKEN, EINVAL),
|
||||||
|
X (PROCESS_ABORTED, EFAULT),
|
||||||
|
X (BAD_DEVICE, ENODEV),
|
||||||
|
X (BAD_USERNAME, EINVAL),
|
||||||
|
X (NOT_CONNECTED, ENOLINK),
|
||||||
|
X (OPEN_FILES, EAGAIN),
|
||||||
|
X (ACTIVE_CONNECTIONS, EAGAIN),
|
||||||
|
X (DEVICE_IN_USE, EAGAIN),
|
||||||
|
X (INVALID_AT_INTERRUPT_TIME, EINTR),
|
||||||
|
X (IO_DEVICE, EIO),
|
||||||
|
X (NOT_OWNER, EPERM),
|
||||||
|
X (END_OF_MEDIA, ENOSPC),
|
||||||
|
X (EOM_OVERFLOW, ENOSPC),
|
||||||
|
X (BEGINNING_OF_MEDIA, ESPIPE),
|
||||||
|
X (SETMARK_DETECTED, ESPIPE),
|
||||||
|
X (NO_DATA_DETECTED, ENOSPC),
|
||||||
|
X (POSSIBLE_DEADLOCK, EDEADLOCK),
|
||||||
|
X (CRC, EIO),
|
||||||
|
X (NEGATIVE_SEEK, EINVAL),
|
||||||
|
X (NOT_READY, ENOMEDIUM),
|
||||||
|
X (DISK_FULL, ENOSPC),
|
||||||
|
{ 0, NULL, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* seterrno_from_win_error: Given a Windows error code, set errno
|
||||||
|
as appropriate. */
|
||||||
|
void
|
||||||
|
seterrno_from_win_error (const char *file, int line, int code)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; errmap[i].w != 0; ++i)
|
||||||
|
if (code == errmap[i].w)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (errmap[i].w != 0)
|
||||||
|
{
|
||||||
|
if (strace_active)
|
||||||
|
strace_printf (_STRACE_SYSCALL, "%s:%d seterrno: %d (%s) -> %d",
|
||||||
|
file, line, code, errmap[i].s, errmap[i].e);
|
||||||
|
set_errno (errmap[i].e);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (strace_active)
|
||||||
|
strace_printf (_STRACE_SYSCALL, "%s:%d seterrno: unknown error %d", file, line, code);
|
||||||
|
set_errno (EACCES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* seterrno: Set `errno' based on GetLastError (). */
|
||||||
|
void
|
||||||
|
seterrno (const char *file, int line)
|
||||||
|
{
|
||||||
|
seterrno_from_win_error (file, line, GetLastError ());
|
||||||
|
}
|
||||||
|
|
||||||
|
extern char *_user_strerror _PARAMS ((int));
|
||||||
|
|
||||||
|
extern const char __declspec(dllexport) * const _sys_errlist[]=
|
||||||
|
{
|
||||||
|
/* NOERROR 0 */ "No error",
|
||||||
|
/* EPERM 1 */ "Not super-user",
|
||||||
|
/* ENOENT 2 */ "No such file or directory",
|
||||||
|
/* ESRCH 3 */ "No such process",
|
||||||
|
/* EINTR 4 */ "Interrupted system call",
|
||||||
|
/* EIO 5 */ "I/O error",
|
||||||
|
/* ENXIO 6 */ "No such device or address",
|
||||||
|
/* E2BIG 7 */ "Arg list too long",
|
||||||
|
/* ENOEXEC 8 */ "Exec format error",
|
||||||
|
/* EBADF 9 */ "Bad file number",
|
||||||
|
/* ECHILD 10 */ "No children",
|
||||||
|
/* EAGAIN 11 */ "Resource temporarily unavailable",
|
||||||
|
/* ENOMEM 12 */ "Not enough core",
|
||||||
|
/* EACCES 13 */ "Permission denied",
|
||||||
|
/* EFAULT 14 */ "Bad address",
|
||||||
|
/* ENOTBLK 15 */ "Block device required",
|
||||||
|
/* EBUSY 16 */ "Mount device busy",
|
||||||
|
/* EEXIST 17 */ "File exists",
|
||||||
|
/* EXDEV 18 */ "Cross-device link",
|
||||||
|
/* ENODEV 19 */ "No such device",
|
||||||
|
/* ENOTDIR 20 */ "Not a directory",
|
||||||
|
/* EISDIR 21 */ "Is a directory",
|
||||||
|
/* EINVAL 22 */ "Invalid argument",
|
||||||
|
/* ENFILE 23 */ "Too many open files in system",
|
||||||
|
/* EMFILE 24 */ "Too many open files",
|
||||||
|
/* ENOTTY 25 */ "Not a typewriter",
|
||||||
|
/* ETXTBSY 26 */ "Text file busy",
|
||||||
|
/* EFBIG 27 */ "File too large",
|
||||||
|
/* ENOSPC 28 */ "No space left on device",
|
||||||
|
/* ESPIPE 29 */ "Illegal seek",
|
||||||
|
/* EROFS 30 */ "Read only file system",
|
||||||
|
/* EMLINK 31 */ "Too many links",
|
||||||
|
/* EPIPE 32 */ "Broken pipe",
|
||||||
|
/* EDOM 33 */ "Math arg out of domain of func",
|
||||||
|
/* ERANGE 34 */ "Math result not representable",
|
||||||
|
/* ENOMSG 35 */ "No message of desired type",
|
||||||
|
/* EIDRM 36 */ "Identifier removed",
|
||||||
|
/* ECHRNG 37 */ "Channel number out of range",
|
||||||
|
/* EL2NSYNC 38 */ "Level 2 not synchronized",
|
||||||
|
/* EL3HLT 39 */ "Level 3 halted",
|
||||||
|
/* EL3RST 40 */ "Level 3 reset",
|
||||||
|
/* ELNRNG 41 */ "Link number out of range",
|
||||||
|
/* EUNATCH 42 */ "Protocol driver not attached",
|
||||||
|
/* ENOCSI 43 */ "No CSI structure available",
|
||||||
|
/* EL2HLT 44 */ "Level 2 halted",
|
||||||
|
/* EDEADLK 45 */ "Deadlock condition",
|
||||||
|
/* ENOLCK 46 */ "No record locks available",
|
||||||
|
"47",
|
||||||
|
"48",
|
||||||
|
"49",
|
||||||
|
/* EBADE 50 */ "Invalid exchange",
|
||||||
|
/* EBADR 51 */ "Invalid request descriptor",
|
||||||
|
/* EXFULL 52 */ "Exchange full",
|
||||||
|
/* ENOANO 53 */ "No anode",
|
||||||
|
/* EBADRQC 54 */ "Invalid request code",
|
||||||
|
/* EBADSLT 55 */ "Invalid slot",
|
||||||
|
/* EDEADLOCK 56 */ "File locking deadlock error",
|
||||||
|
/* EBFONT 57 */ "Bad font file fmt",
|
||||||
|
"58",
|
||||||
|
"59",
|
||||||
|
/* ENOSTR 60 */ "Device not a stream",
|
||||||
|
/* ENODATA 61 */ "No data (for no delay io)",
|
||||||
|
/* ETIME 62 */ "Timer expired",
|
||||||
|
/* ENOSR 63 */ "Out of streams resources",
|
||||||
|
/* ENONET 64 */ "Machine is not on the network",
|
||||||
|
/* ENOPKG 65 */ "Package not installed",
|
||||||
|
/* EREMOTE 66 */ "The object is remote",
|
||||||
|
/* ENOLINK 67 */ "The link has been severed",
|
||||||
|
/* EADV 68 */ "Advertise error",
|
||||||
|
/* ESRMNT 69 */ "Srmount error",
|
||||||
|
/* ECOMM 70 */ "Communication error on send",
|
||||||
|
/* EPROTO 71 */ "Protocol error",
|
||||||
|
"72",
|
||||||
|
"73",
|
||||||
|
/* EMULTIHOP 74 */ "Multihop attempted",
|
||||||
|
/* ELBIN 75 */ "Inode is remote (not really error)",
|
||||||
|
/* EDOTDOT 76 */ "Cross mount point (not really error)",
|
||||||
|
/* EBADMSG 77 */ "Trying to read unreadable message",
|
||||||
|
"78",
|
||||||
|
"79",
|
||||||
|
/* ENOTUNIQ 80 */ "Given log. name not unique",
|
||||||
|
/* EBADFD 81 */ "f.d. invalid for this operation",
|
||||||
|
/* EREMCHG 82 */ "Remote address changed",
|
||||||
|
/* ELIBACC 83 */ "Can't access a needed shared lib",
|
||||||
|
/* ELIBBAD 84 */ "Accessing a corrupted shared lib",
|
||||||
|
/* ELIBSCN 85 */ ".lib section in a.out corrupted",
|
||||||
|
/* ELIBMAX 86 */ "Attempting to link in too many libs",
|
||||||
|
/* ELIBEXEC 87 */ "Attempting to exec a shared library",
|
||||||
|
/* ENOSYS 88 */ "Function not implemented",
|
||||||
|
/* ENMFILE 89 */ "No more files",
|
||||||
|
/* ENOTEMPTY 90 */ "Directory not empty",
|
||||||
|
/* ENAMETOOLONG 91 */ "File or path name too long",
|
||||||
|
/* ELOOP 92 */ "Too many symbolic links",
|
||||||
|
"93",
|
||||||
|
"94",
|
||||||
|
/* EOPNOTSUPP 95 */ "Operation not supported on transport endpoint",
|
||||||
|
/* EPFNOSUPPORT 96 */ "Protocol family not supported",
|
||||||
|
"97",
|
||||||
|
"98",
|
||||||
|
"99",
|
||||||
|
"100",
|
||||||
|
"101",
|
||||||
|
"102",
|
||||||
|
"103",
|
||||||
|
/* ECONNRESET 104 */ "Connection reset by peer",
|
||||||
|
/* ENOBUFS 105 */ "No buffer space available",
|
||||||
|
/* EAFNOSUPPORT 106 */ "Address family not supported by protocol",
|
||||||
|
/* EPROTOTYPE 107 */ "Protocol wrong type for transport endpoint",
|
||||||
|
/* ENOTSOCK 108 */ "Socket operation on non-socket"
|
||||||
|
/* ENOPROTOOPT 109 */ "Protocol not available",
|
||||||
|
/* ESHUTDOWN 110 */ "Cannot send after transport endpoint shutdown",
|
||||||
|
/* ECONNREFUSED 111 */ "Connection refused",
|
||||||
|
/* EADDRINUSE 112 */ "Address already in use"
|
||||||
|
/* ECONNABORTED 113 */ "Connection aborted",
|
||||||
|
/* ENETUNREACH 114 */ "Network is unreachable",
|
||||||
|
/* ENETDOWN 115 */ "Network is down",
|
||||||
|
/* ETIMEDOUT 116 */ "Connection timed out",
|
||||||
|
/* EHOSTDOWN 117 */ "Host is down",
|
||||||
|
/* EHOSTUNREACH 118 */ "No route to host",
|
||||||
|
/* EINPROGRESS 119 */ "Operation now in progress",
|
||||||
|
/* EALREADY 120 */ "Operation already in progress",
|
||||||
|
/* EDESTADDRREQ 121 */ "Destination address required",
|
||||||
|
/* EMSGSIZE 122 */ "Message too long",
|
||||||
|
/* EPROTONOSUPPORT 123 */ "Protocol not supported",
|
||||||
|
/* ESOCKTNOSUPPORT 124 */ "Socket type not supported",
|
||||||
|
/* EADDRNOTAVAIL 125 */ "Cannot assign requested address",
|
||||||
|
/* ENETRESET 126 */ "Network dropped connection because of reset",
|
||||||
|
/* EISCONN 127 */ "Transport endpoint is already connected",
|
||||||
|
/* ENOTCONN 128 */ "Transport endpoint is not connected",
|
||||||
|
/* ETOOMANYREFS 129 */ "Too many references: cannot splice",
|
||||||
|
/* EPROCLIM 130 */ "Process limit exceeded",
|
||||||
|
/* EUSERS 131 */ "Too many users",
|
||||||
|
/* EDQUOT 132 */ "Quota exceeded",
|
||||||
|
/* ESTALE 133 */ "Stale NFS file handle",
|
||||||
|
/* ENOTSUP 134 */ "134",
|
||||||
|
/* ENOMEDIUM 135 */ "no medium"
|
||||||
|
};
|
||||||
|
|
||||||
|
int __declspec(dllexport) _sys_nerr =
|
||||||
|
sizeof (_sys_errlist) / sizeof (_sys_errlist[0]);
|
||||||
|
|
||||||
|
/* FIXME: Why is strerror() a long switch and not just:
|
||||||
|
return sys_errlist[errnum];
|
||||||
|
(or moral equivalent).
|
||||||
|
Some entries in sys_errlist[] don't match the corresponding
|
||||||
|
entries in strerror(). This seems odd.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* CYGWIN internal */
|
||||||
|
/* strerror: convert from errno values to error strings */
|
||||||
|
extern "C" char *
|
||||||
|
strerror (int errnum)
|
||||||
|
{
|
||||||
|
const char *error;
|
||||||
|
switch (errnum)
|
||||||
|
{
|
||||||
|
case EPERM:
|
||||||
|
error = "Not owner";
|
||||||
|
break;
|
||||||
|
case ENOENT:
|
||||||
|
error = "No such file or directory";
|
||||||
|
break;
|
||||||
|
case ESRCH:
|
||||||
|
error = "No such process";
|
||||||
|
break;
|
||||||
|
case EINTR:
|
||||||
|
error = "Interrupted system call";
|
||||||
|
break;
|
||||||
|
case EIO:
|
||||||
|
error = "I/O error";
|
||||||
|
break;
|
||||||
|
case ENXIO:
|
||||||
|
error = "No such device or address";
|
||||||
|
break;
|
||||||
|
case E2BIG:
|
||||||
|
error = "Arg list too long";
|
||||||
|
break;
|
||||||
|
case ENOEXEC:
|
||||||
|
error = "Exec format error";
|
||||||
|
break;
|
||||||
|
case EBADF:
|
||||||
|
error = "Bad file number";
|
||||||
|
break;
|
||||||
|
case ECHILD:
|
||||||
|
error = "No children";
|
||||||
|
break;
|
||||||
|
case EAGAIN:
|
||||||
|
error = "No more processes";
|
||||||
|
break;
|
||||||
|
case ENOMEM:
|
||||||
|
error = "Not enough memory";
|
||||||
|
break;
|
||||||
|
case EACCES:
|
||||||
|
error = "Permission denied";
|
||||||
|
break;
|
||||||
|
case EFAULT:
|
||||||
|
error = "Bad address";
|
||||||
|
break;
|
||||||
|
case ENOTBLK:
|
||||||
|
error = "Block device required";
|
||||||
|
break;
|
||||||
|
case EBUSY:
|
||||||
|
error = "Device or resource busy";
|
||||||
|
break;
|
||||||
|
case EEXIST:
|
||||||
|
error = "File exists";
|
||||||
|
break;
|
||||||
|
case EXDEV:
|
||||||
|
error = "Cross-device link";
|
||||||
|
break;
|
||||||
|
case ENODEV:
|
||||||
|
error = "No such device";
|
||||||
|
break;
|
||||||
|
case ENOTDIR:
|
||||||
|
error = "Not a directory";
|
||||||
|
break;
|
||||||
|
case EISDIR:
|
||||||
|
error = "Is a directory";
|
||||||
|
break;
|
||||||
|
case EINVAL:
|
||||||
|
error = "Invalid argument";
|
||||||
|
break;
|
||||||
|
case ENFILE:
|
||||||
|
error = "Too many open files in system";
|
||||||
|
break;
|
||||||
|
case EMFILE:
|
||||||
|
error = "Too many open files";
|
||||||
|
break;
|
||||||
|
case ENOTTY:
|
||||||
|
error = "Not a character device";
|
||||||
|
break;
|
||||||
|
case ETXTBSY:
|
||||||
|
error = "Text file busy";
|
||||||
|
break;
|
||||||
|
case EFBIG:
|
||||||
|
error = "File too large";
|
||||||
|
break;
|
||||||
|
case ENOSPC:
|
||||||
|
error = "No space left on device";
|
||||||
|
break;
|
||||||
|
case ESPIPE:
|
||||||
|
error = "Illegal seek";
|
||||||
|
break;
|
||||||
|
case EROFS:
|
||||||
|
error = "Read-only file system";
|
||||||
|
break;
|
||||||
|
case EMLINK:
|
||||||
|
error = "Too many links";
|
||||||
|
break;
|
||||||
|
case EPIPE:
|
||||||
|
error = "Broken pipe";
|
||||||
|
break;
|
||||||
|
case EDOM:
|
||||||
|
error = "Math arg out of domain of func";
|
||||||
|
break;
|
||||||
|
case ERANGE:
|
||||||
|
error = "Math result out of range";
|
||||||
|
break;
|
||||||
|
case ENOMSG:
|
||||||
|
error = "No message of desired type";
|
||||||
|
break;
|
||||||
|
case EIDRM:
|
||||||
|
error = "Identifier removed";
|
||||||
|
break;
|
||||||
|
case ECHRNG:
|
||||||
|
error = "Channel number out of range";
|
||||||
|
break;
|
||||||
|
case EL2NSYNC:
|
||||||
|
error = "Level 2 not synchronized";
|
||||||
|
break;
|
||||||
|
case EL3HLT:
|
||||||
|
error = "Level 3 halted";
|
||||||
|
break;
|
||||||
|
case EL3RST:
|
||||||
|
error = "Level 3 reset";
|
||||||
|
break;
|
||||||
|
case ELNRNG:
|
||||||
|
error = "Link number out of range";
|
||||||
|
break;
|
||||||
|
case EUNATCH:
|
||||||
|
error = "Protocol driver not attached";
|
||||||
|
break;
|
||||||
|
case ENOCSI:
|
||||||
|
error = "No CSI structure available";
|
||||||
|
break;
|
||||||
|
case EL2HLT:
|
||||||
|
error = "Level 2 halted";
|
||||||
|
break;
|
||||||
|
case EDEADLK:
|
||||||
|
error = "Deadlock condition";
|
||||||
|
break;
|
||||||
|
case ENOLCK:
|
||||||
|
error = "No lock";
|
||||||
|
break;
|
||||||
|
case EBADE:
|
||||||
|
error = "Invalid exchange";
|
||||||
|
break;
|
||||||
|
case EBADR:
|
||||||
|
error = "Invalid request descriptor";
|
||||||
|
break;
|
||||||
|
case EXFULL:
|
||||||
|
error = "Exchange full";
|
||||||
|
break;
|
||||||
|
case ENOANO:
|
||||||
|
error = "No anode";
|
||||||
|
break;
|
||||||
|
case EBADRQC:
|
||||||
|
error = "Invalid request code";
|
||||||
|
break;
|
||||||
|
case EBADSLT:
|
||||||
|
error = "Invalid slot";
|
||||||
|
break;
|
||||||
|
case EDEADLOCK:
|
||||||
|
error = "File locking deadlock error";
|
||||||
|
break;
|
||||||
|
case EBFONT:
|
||||||
|
error = "Bad font file fmt";
|
||||||
|
break;
|
||||||
|
case ENOSTR:
|
||||||
|
error = "Not a stream";
|
||||||
|
break;
|
||||||
|
case ENODATA:
|
||||||
|
error = "No data (for no delay io)";
|
||||||
|
break;
|
||||||
|
case ETIME:
|
||||||
|
error = "Stream ioctl timeout";
|
||||||
|
break;
|
||||||
|
case ENOSR:
|
||||||
|
error = "No stream resources";
|
||||||
|
break;
|
||||||
|
case ENONET:
|
||||||
|
error = "Machine is not on the network";
|
||||||
|
break;
|
||||||
|
case ENOPKG:
|
||||||
|
error = "No package";
|
||||||
|
break;
|
||||||
|
case EREMOTE:
|
||||||
|
error = "Resource is remote";
|
||||||
|
break;
|
||||||
|
case ENOLINK:
|
||||||
|
error = "Virtual circuit is gone";
|
||||||
|
break;
|
||||||
|
case EADV:
|
||||||
|
error = "Advertise error";
|
||||||
|
break;
|
||||||
|
case ESRMNT:
|
||||||
|
error = "Srmount error";
|
||||||
|
break;
|
||||||
|
case ECOMM:
|
||||||
|
error = "Communication error";
|
||||||
|
break;
|
||||||
|
case EPROTO:
|
||||||
|
error = "Protocol error";
|
||||||
|
break;
|
||||||
|
case EMULTIHOP:
|
||||||
|
error = "Multihop attempted";
|
||||||
|
break;
|
||||||
|
case ELBIN:
|
||||||
|
error = "Inode is remote (not really error)";
|
||||||
|
break;
|
||||||
|
case EDOTDOT:
|
||||||
|
error = "Cross mount point (not really error)";
|
||||||
|
break;
|
||||||
|
case EBADMSG:
|
||||||
|
error = "Bad message";
|
||||||
|
break;
|
||||||
|
case ENOTUNIQ:
|
||||||
|
error = "Given log. name not unique";
|
||||||
|
break;
|
||||||
|
case EBADFD:
|
||||||
|
error = "f.d. invalid for this operation";
|
||||||
|
break;
|
||||||
|
case EREMCHG:
|
||||||
|
error = "Remote address changed";
|
||||||
|
break;
|
||||||
|
case ELIBACC:
|
||||||
|
error = "Cannot access a needed shared library";
|
||||||
|
break;
|
||||||
|
case ELIBBAD:
|
||||||
|
error = "Accessing a corrupted shared library";
|
||||||
|
break;
|
||||||
|
case ELIBSCN:
|
||||||
|
error = ".lib section in a.out corrupted";
|
||||||
|
break;
|
||||||
|
case ELIBMAX:
|
||||||
|
error = "Attempting to link in more shared libraries than system limit";
|
||||||
|
break;
|
||||||
|
case ELIBEXEC:
|
||||||
|
error = "Cannot exec a shared library directly";
|
||||||
|
break;
|
||||||
|
case ENOSYS:
|
||||||
|
error = "Function not implemented";
|
||||||
|
break;
|
||||||
|
case ENMFILE:
|
||||||
|
error = "No more files";
|
||||||
|
break;
|
||||||
|
case ENOTEMPTY:
|
||||||
|
error = "Directory not empty";
|
||||||
|
break;
|
||||||
|
case ENAMETOOLONG:
|
||||||
|
error = "File or path name too long";
|
||||||
|
break;
|
||||||
|
case ELOOP:
|
||||||
|
error = "Too many symbolic links";
|
||||||
|
break;
|
||||||
|
case EOPNOTSUPP:
|
||||||
|
error = "Operation not supported on transport endpoint";
|
||||||
|
break;
|
||||||
|
case EPFNOSUPPORT:
|
||||||
|
error = "Protocol family not supported";
|
||||||
|
break;
|
||||||
|
case ECONNRESET:
|
||||||
|
error = "Connection reset by peer";
|
||||||
|
break;
|
||||||
|
case ENOBUFS:
|
||||||
|
error = "No buffer space available; the socket cannot be connected";
|
||||||
|
break;
|
||||||
|
case EAFNOSUPPORT:
|
||||||
|
error = "Addresses in the specified family cannot be used with this socket";
|
||||||
|
break;
|
||||||
|
case EPROTOTYPE:
|
||||||
|
error = "errno EPROTOTYPE triggered";
|
||||||
|
break;
|
||||||
|
case ENOTSOCK:
|
||||||
|
error = "The descriptor is a file, not a socket";
|
||||||
|
break;
|
||||||
|
case ENOPROTOOPT:
|
||||||
|
error = "This option is unsupported";
|
||||||
|
break;
|
||||||
|
case ESHUTDOWN:
|
||||||
|
error = "errno ESHUTDOWN triggered";
|
||||||
|
break;
|
||||||
|
case ECONNREFUSED:
|
||||||
|
error = "Connection refused";
|
||||||
|
break;
|
||||||
|
case EADDRINUSE:
|
||||||
|
error = "Address already in use";
|
||||||
|
break;
|
||||||
|
case ECONNABORTED:
|
||||||
|
error = "The connection was aborted";
|
||||||
|
break;
|
||||||
|
case ENETUNREACH:
|
||||||
|
error ="The network can't be reached from this host at this time";
|
||||||
|
break;
|
||||||
|
case ENETDOWN:
|
||||||
|
error = "Network failed.";
|
||||||
|
break;
|
||||||
|
case ETIMEDOUT:
|
||||||
|
error = "Attempt to connect timed out without establishing a connection";
|
||||||
|
break;
|
||||||
|
case EHOSTDOWN:
|
||||||
|
error = "errno EHOSTDOWN triggered";
|
||||||
|
break;
|
||||||
|
case EHOSTUNREACH:
|
||||||
|
error = "errno EHOSTUNREACH triggered";
|
||||||
|
break;
|
||||||
|
case EINPROGRESS:
|
||||||
|
error = "errno EINPROGRESS triggered";
|
||||||
|
break;
|
||||||
|
case EALREADY:
|
||||||
|
error = "errno EALREADY triggered";
|
||||||
|
break;
|
||||||
|
case EDESTADDRREQ:
|
||||||
|
error = "errno EDESTADDRREQ triggered";
|
||||||
|
break;
|
||||||
|
case EMSGSIZE:
|
||||||
|
error = "errno EMSGSIZE triggered";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EPROTONOSUPPORT:
|
||||||
|
error = "errno EPROTONOSUPPORT triggered";
|
||||||
|
break;
|
||||||
|
case ESOCKTNOSUPPORT:
|
||||||
|
error = "errno ESOCKTNOSUPPORT triggered";
|
||||||
|
break;
|
||||||
|
case EADDRNOTAVAIL:
|
||||||
|
error = "errno EADDRNOTAVAIL triggered";
|
||||||
|
break;
|
||||||
|
case ENETRESET:
|
||||||
|
error = "errno ENETRESET triggered";
|
||||||
|
break;
|
||||||
|
case EISCONN:
|
||||||
|
error = "The socket is already connected";
|
||||||
|
break;
|
||||||
|
case ENOTCONN:
|
||||||
|
error = "The socket is not connected";
|
||||||
|
break;
|
||||||
|
case ETOOMANYREFS:
|
||||||
|
error = "errno ETOOMANYREFS triggered";
|
||||||
|
break;
|
||||||
|
case EPROCLIM:
|
||||||
|
error = "errno EPROCLIM triggered";
|
||||||
|
break;
|
||||||
|
case EUSERS:
|
||||||
|
error = "errno EUSERS triggered";
|
||||||
|
break;
|
||||||
|
case EDQUOT:
|
||||||
|
error = "errno EDQUOT triggered";
|
||||||
|
break;
|
||||||
|
case ESTALE:
|
||||||
|
error = "errno ESTALE triggered";
|
||||||
|
break;
|
||||||
|
case ENOTSUP:
|
||||||
|
error = "errno ENOTSUP triggered";
|
||||||
|
break;
|
||||||
|
case ENOMEDIUM:
|
||||||
|
error = "no medium";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
#ifdef _MT_SAFE
|
||||||
|
char *buf= _reent_winsup()->_strerror_buf;
|
||||||
|
#else
|
||||||
|
static NO_COPY char buf[20];
|
||||||
|
#endif
|
||||||
|
__small_sprintf (buf, "error %d", errnum);
|
||||||
|
error = buf;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: strerror should really be const in the appropriate newlib
|
||||||
|
include files. */
|
||||||
|
return (char *) error;
|
||||||
|
}
|
||||||
|
|
1066
winsup/cygwin/exceptions.cc
Normal file
1066
winsup/cygwin/exceptions.cc
Normal file
File diff suppressed because it is too large
Load Diff
204
winsup/cygwin/exec.cc
Normal file
204
winsup/cygwin/exec.cc
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
/* exec.cc: exec system call support.
|
||||||
|
|
||||||
|
Copyright 1996, 1997, 1998, 2000 Cygnus Solutions.
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <process.h>
|
||||||
|
#include "winsup.h"
|
||||||
|
|
||||||
|
/* This is called _execve and not execve because the real execve is defined
|
||||||
|
in libc/posix/execve.c. It calls us. */
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
pid_t
|
||||||
|
_execve (const char *path, const char *const argv[], const char *const envp[])
|
||||||
|
{
|
||||||
|
static char *const empty_env[] = { 0 };
|
||||||
|
MALLOC_CHECK;
|
||||||
|
if (!envp)
|
||||||
|
envp = empty_env;
|
||||||
|
return _spawnve (NULL, _P_OVERLAY, path, argv, envp);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int
|
||||||
|
execl (const char *path, const char *arg0, ...)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
va_list args;
|
||||||
|
const char *argv[1024];
|
||||||
|
|
||||||
|
va_start (args, arg0);
|
||||||
|
argv[0] = arg0;
|
||||||
|
i = 1;
|
||||||
|
do
|
||||||
|
argv[i] = va_arg (args, const char *);
|
||||||
|
while (argv[i++] != NULL);
|
||||||
|
va_end (args);
|
||||||
|
MALLOC_CHECK;
|
||||||
|
return _execve (path, (char * const *) argv, *user_data->envptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int
|
||||||
|
execv (const char *path, char * const *argv)
|
||||||
|
{
|
||||||
|
MALLOC_CHECK;
|
||||||
|
return _execve (path, (char * const *) argv, *user_data->envptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the same as a standard exec() calls family, but with NT security support */
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
pid_t
|
||||||
|
sexecve (HANDLE hToken, const char *path, const char *const argv[],
|
||||||
|
const char *const envp[])
|
||||||
|
{
|
||||||
|
_spawnve (hToken, _P_OVERLAY, path, argv, envp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int
|
||||||
|
sexecl (HANDLE hToken, const char *path, const char *arg0, ...)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
va_list args;
|
||||||
|
const char *argv[1024];
|
||||||
|
|
||||||
|
va_start (args, arg0);
|
||||||
|
argv[0] = arg0;
|
||||||
|
i = 1;
|
||||||
|
|
||||||
|
do
|
||||||
|
argv[i] = va_arg (args, const char *);
|
||||||
|
while (argv[i++] != NULL);
|
||||||
|
|
||||||
|
va_end (args);
|
||||||
|
|
||||||
|
MALLOC_CHECK;
|
||||||
|
return sexecve (hToken, path, (char * const *) argv, *user_data->envptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int
|
||||||
|
sexecle (HANDLE hToken, const char *path, const char *arg0, ...)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
va_list args;
|
||||||
|
const char * const *envp;
|
||||||
|
const char *argv[1024];
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
MALLOC_CHECK;
|
||||||
|
return sexecve(hToken, path, (char * const *) argv, (char * const *) envp);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int
|
||||||
|
sexeclp (HANDLE hToken, const char *path, const char *arg0, ...)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
va_list args;
|
||||||
|
const char *argv[1024];
|
||||||
|
|
||||||
|
va_start (args, arg0);
|
||||||
|
argv[0] = arg0;
|
||||||
|
i = 1;
|
||||||
|
|
||||||
|
do
|
||||||
|
argv[i] = va_arg (args, const char *);
|
||||||
|
while (argv[i++] != NULL);
|
||||||
|
|
||||||
|
va_end (args);
|
||||||
|
|
||||||
|
MALLOC_CHECK;
|
||||||
|
return sexecvpe (hToken, path, (const char * const *) argv,
|
||||||
|
*user_data->envptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int
|
||||||
|
sexeclpe (HANDLE hToken, const char *path, const char *arg0, ...)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
va_list args;
|
||||||
|
const char * const *envp;
|
||||||
|
const char *argv[1024];
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
MALLOC_CHECK;
|
||||||
|
return sexecvpe (hToken, path, argv, envp);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int
|
||||||
|
sexecv (HANDLE hToken, const char *path, const char * const *argv)
|
||||||
|
{
|
||||||
|
MALLOC_CHECK;
|
||||||
|
return sexecve (hToken, path, argv, *user_data->envptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int
|
||||||
|
sexecp (HANDLE hToken, const char *path, const char * const *argv)
|
||||||
|
{
|
||||||
|
MALLOC_CHECK;
|
||||||
|
return sexecvpe (hToken, path, argv, *user_data->envptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy string, until c or <nul> is encountered.
|
||||||
|
* NUL-terminate the destination string (s1).
|
||||||
|
* Return pointer to terminating byte in dst string.
|
||||||
|
*/
|
||||||
|
|
||||||
|
char * __stdcall
|
||||||
|
strccpy (char *s1, const char **s2, char c)
|
||||||
|
{
|
||||||
|
while (**s2 && **s2 != c)
|
||||||
|
*s1++ = *((*s2)++);
|
||||||
|
*s1 = 0;
|
||||||
|
|
||||||
|
MALLOC_CHECK;
|
||||||
|
return s1;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int
|
||||||
|
sexecvpe (HANDLE hToken, const char *file, const char * const *argv,
|
||||||
|
const char *const *envp)
|
||||||
|
{
|
||||||
|
char buf[MAXNAMLEN];
|
||||||
|
MALLOC_CHECK;
|
||||||
|
return sexecve (hToken, find_exec (file, buf), argv, envp);
|
||||||
|
}
|
107
winsup/cygwin/external.cc
Normal file
107
winsup/cygwin/external.cc
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/* external.cc: Interface to Cygwin internals from external programs.
|
||||||
|
|
||||||
|
Copyright 1997, 1998, 1999 Cygnus Solutions.
|
||||||
|
|
||||||
|
Written by Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include "winsup.h"
|
||||||
|
#include "external.h"
|
||||||
|
|
||||||
|
static external_pinfo *
|
||||||
|
fillout_pinfo (DWORD pid)
|
||||||
|
{
|
||||||
|
BOOL nextpid;
|
||||||
|
pinfo *p = NULL;
|
||||||
|
int i;
|
||||||
|
static external_pinfo ep;
|
||||||
|
|
||||||
|
if ((nextpid = !!(pid & CW_NEXTPID)))
|
||||||
|
pid ^= CW_NEXTPID;
|
||||||
|
for (i = 0; i < cygwin_shared->p.size(); i++, p = NULL)
|
||||||
|
{
|
||||||
|
p = cygwin_shared->p.vec + i;
|
||||||
|
if (!pid || (DWORD) p->pid == pid)
|
||||||
|
{
|
||||||
|
if (nextpid && pid)
|
||||||
|
{
|
||||||
|
pid = 0;
|
||||||
|
nextpid = 0;
|
||||||
|
}
|
||||||
|
else if (p->pid && NOTSTATE(p, PID_CLEAR))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
memset (&ep, 0, sizeof ep);
|
||||||
|
ep.ctty = tty_attached (p) ? p->ctty : -1;
|
||||||
|
ep.pid = p->pid;
|
||||||
|
ep.ppid = p->ppid;
|
||||||
|
ep.hProcess = p->hProcess;
|
||||||
|
ep.dwProcessId = p->dwProcessId;
|
||||||
|
//ep.dwSpawnedProcessId = p->dwSpawnedProcessId;
|
||||||
|
ep.uid = p->uid;
|
||||||
|
ep.gid = p->gid;
|
||||||
|
ep.pgid = p->pgid;
|
||||||
|
ep.sid = p->sid;
|
||||||
|
ep.umask = p->umask;
|
||||||
|
ep.start_time = p->start_time;
|
||||||
|
ep.rusage_self = p->rusage_self;
|
||||||
|
ep.rusage_children = p->rusage_children;
|
||||||
|
strcpy (ep.progname, p->progname);
|
||||||
|
ep.strace_mask = 0;
|
||||||
|
ep.strace_file = 0;
|
||||||
|
|
||||||
|
ep.process_state = p->process_state;
|
||||||
|
return &ep;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" DWORD
|
||||||
|
cygwin_internal (cygwin_getinfo_types t, ...)
|
||||||
|
{
|
||||||
|
va_list arg;
|
||||||
|
va_start (arg, t);
|
||||||
|
|
||||||
|
switch (t)
|
||||||
|
{
|
||||||
|
case CW_LOCK_PINFO:
|
||||||
|
return lock_pinfo_for_update (va_arg (arg, DWORD));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CW_UNLOCK_PINFO:
|
||||||
|
unlock_pinfo ();
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case CW_GETTHREADNAME:
|
||||||
|
return (DWORD) threadname (va_arg (arg, DWORD));
|
||||||
|
|
||||||
|
case CW_SETTHREADNAME:
|
||||||
|
{
|
||||||
|
char *name = va_arg (arg, char *);
|
||||||
|
regthread (name, va_arg (arg, DWORD));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
case CW_GETPINFO:
|
||||||
|
return (DWORD) fillout_pinfo (va_arg (arg, DWORD));
|
||||||
|
|
||||||
|
case CW_GETVERSIONINFO:
|
||||||
|
return (DWORD) cygwin_version_strings;
|
||||||
|
|
||||||
|
case CW_READ_V1_MOUNT_TABLES:
|
||||||
|
/* Upgrade old v1 registry mounts to new location. */
|
||||||
|
cygwin_shared->mount.import_v1_mounts ();
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return (DWORD) -1;
|
||||||
|
}
|
||||||
|
}
|
16
winsup/cygwin/external.sgml
Normal file
16
winsup/cygwin/external.sgml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
<sect1 id="func-cygwin-internal">
|
||||||
|
<title>cygwin_internal</title>
|
||||||
|
|
||||||
|
<funcsynopsis>
|
||||||
|
<funcdef>extern "C" DWORD
|
||||||
|
<function>cygwin_internal</function></funcdef>
|
||||||
|
<paramdef>cygwin_getinfo_types <parameter>t</parameter></paramdef>
|
||||||
|
<paramdef><parameter>...</parameter></paramdef>
|
||||||
|
</funcsynopsis>
|
||||||
|
|
||||||
|
<para>This function gives you access to various internal data and functions.
|
||||||
|
Stay away unless you know what you're doing.</para>
|
||||||
|
|
||||||
|
</sect1>
|
||||||
|
|
106
winsup/cygwin/fcntl.cc
Normal file
106
winsup/cygwin/fcntl.cc
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/* fcntl.cc: fcntl syscall
|
||||||
|
|
||||||
|
Copyright 1996, 1997, 1998 Cygnus Solutions.
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "winsup.h"
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int
|
||||||
|
_fcntl (int fd, int cmd,...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
int arg = 0;
|
||||||
|
int res;
|
||||||
|
SetResourceLock(LOCK_FD_LIST,WRITE_LOCK|READ_LOCK, "_fcntl");
|
||||||
|
|
||||||
|
if (dtable.not_open (fd))
|
||||||
|
{
|
||||||
|
set_errno (EBADF);
|
||||||
|
res = -1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case F_DUPFD:
|
||||||
|
va_start (args, cmd);
|
||||||
|
arg = va_arg (args,int);
|
||||||
|
va_end (args);
|
||||||
|
res = dup2 (fd, dtable.find_unused_handle (arg));
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
case F_GETFD:
|
||||||
|
res = dtable[fd]->get_close_on_exec () ? FD_CLOEXEC : 0;
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
case F_SETFD:
|
||||||
|
va_start (args, cmd);
|
||||||
|
arg = va_arg (args, int);
|
||||||
|
va_end (args);
|
||||||
|
dtable[fd]->set_close_on_exec (arg);
|
||||||
|
res = 0;
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
case F_GETFL:
|
||||||
|
{
|
||||||
|
res = dtable[fd]->get_flags ();
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
case F_SETFL:
|
||||||
|
{
|
||||||
|
int temp = 0;
|
||||||
|
|
||||||
|
va_start (args, cmd);
|
||||||
|
arg = va_arg (args, int);
|
||||||
|
va_end (args);
|
||||||
|
|
||||||
|
if (arg & O_RDONLY)
|
||||||
|
temp |= GENERIC_READ;
|
||||||
|
if (arg & O_WRONLY)
|
||||||
|
temp |= GENERIC_WRITE;
|
||||||
|
|
||||||
|
syscall_printf ("fcntl (%d, F_SETFL, %d)", arg);
|
||||||
|
|
||||||
|
dtable[fd]->set_access (temp);
|
||||||
|
dtable[fd]->set_flags (arg);
|
||||||
|
|
||||||
|
res = 0;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
case F_GETLK:
|
||||||
|
case F_SETLK:
|
||||||
|
case F_SETLKW:
|
||||||
|
{
|
||||||
|
struct flock *fl;
|
||||||
|
va_start (args, cmd);
|
||||||
|
fl = va_arg (args,struct flock *);
|
||||||
|
va_end (args);
|
||||||
|
res = dtable[fd]->lock (cmd, fl);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
set_errno (EINVAL);
|
||||||
|
res = -1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_errno (ENOSYS);
|
||||||
|
res = -1;
|
||||||
|
|
||||||
|
done:
|
||||||
|
ReleaseResourceLock(LOCK_FD_LIST,WRITE_LOCK|READ_LOCK,"_fcntl");
|
||||||
|
|
||||||
|
syscall_printf ("%d = fcntl (%d, %d, %d)", res, fd, cmd, arg);
|
||||||
|
return res;
|
||||||
|
}
|
1501
winsup/cygwin/fhandler.cc
Normal file
1501
winsup/cygwin/fhandler.cc
Normal file
File diff suppressed because it is too large
Load Diff
804
winsup/cygwin/fhandler.h
Normal file
804
winsup/cygwin/fhandler.h
Normal file
@ -0,0 +1,804 @@
|
|||||||
|
/* fhandler.h
|
||||||
|
|
||||||
|
Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions.
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#ifndef _FHANDLER_H_
|
||||||
|
#define _FHANDLER_H_
|
||||||
|
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
|
/* Classes
|
||||||
|
|
||||||
|
Code is located in fhandler.cc unless another file name is given.
|
||||||
|
|
||||||
|
fhandler_base normal I/O
|
||||||
|
|
||||||
|
fhandler_disk_file
|
||||||
|
fhandler_serial Adds vmin and vtime.
|
||||||
|
fhandler_dev_null Not really I/O
|
||||||
|
fhandler_dev_zero Faked
|
||||||
|
|
||||||
|
fhandler_dev_raw (fhandler_raw.cc)
|
||||||
|
fhandler_dev_floppy (fhandler_floppy.cc)
|
||||||
|
fhandler_dev_tape (fhandler_tape.cc)
|
||||||
|
|
||||||
|
fhandler_pipe
|
||||||
|
fhandler_socket (net.cc)
|
||||||
|
|
||||||
|
fhandler_tty_slave (tty.cc)
|
||||||
|
fhandler_pty_master (tty.cc)
|
||||||
|
fhandler_tty_master (tty.cc)
|
||||||
|
|
||||||
|
fhandler_console Out with ansi control. (console.cc)
|
||||||
|
|
||||||
|
fhandler_windows Windows messages I/O (fhandler_windows.cc)
|
||||||
|
|
||||||
|
fhandler_proc Interesting possibility, not implemented yet
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
FH_RBINARY = 0x00001000, /* binary read mode */
|
||||||
|
FH_WBINARY = 0x00002000, /* binary write mode */
|
||||||
|
FH_CLOEXEC = 0x00004000, /* close-on-exec */
|
||||||
|
FH_RBINSET = 0x00008000, /* binary read mode has been explicitly set */
|
||||||
|
FH_WBINSET = 0x00010000, /* binary write mode has been explicitly set */
|
||||||
|
FH_APPEND = 0x00020000, /* always append */
|
||||||
|
FH_ASYNC = 0x00040000, /* async I/O */
|
||||||
|
FH_HADEOF = 0x00080000, /* EOF seen */
|
||||||
|
|
||||||
|
FH_SYMLINK = 0x00100000, /* is a symlink */
|
||||||
|
FH_EXECABL = 0x00200000, /* file looked like it would run:
|
||||||
|
* ends in .exe or .bat or begins with #! */
|
||||||
|
FH_W95LSBUG= 0x00400000, /* set when lseek is called as a flag that
|
||||||
|
* _write should check if we've moved beyond
|
||||||
|
* EOF, zero filling if so. */
|
||||||
|
FH_NOFRNAME= 0x00800000, /* Set if shouldn't free unix_path_name_ and
|
||||||
|
windows_path_name_ on destruction. */
|
||||||
|
FH_NOEINTR = 0x01000000, /* Set if I/O should be uninterruptible. */
|
||||||
|
FH_FFIXUP = 0x02000000, /* Set if need to fixup after fork. */
|
||||||
|
FH_LOCAL = 0x04000000, /* File is unix domain socket */
|
||||||
|
FH_FIFO = 0x08000000, /* File is FIFO */
|
||||||
|
FH_HASACLS = 0x40000000, /* True if fs of file has ACLS */
|
||||||
|
|
||||||
|
/* Device flags */
|
||||||
|
|
||||||
|
/* Slow devices */
|
||||||
|
FH_CONSOLE = 0x00000001, /* is a console */
|
||||||
|
FH_CONIN = 0x00000002, /* console input */
|
||||||
|
FH_CONOUT = 0x00000003, /* console output */
|
||||||
|
FH_TTYM = 0x00000004, /* is a tty master */
|
||||||
|
FH_TTYS = 0x00000005, /* is a tty slave */
|
||||||
|
FH_PTYM = 0x00000006, /* is a pty master */
|
||||||
|
FH_SERIAL = 0x00000007, /* is a serial port */
|
||||||
|
FH_PIPE = 0x00000008, /* is a pipe */
|
||||||
|
FH_PIPER = 0x00000009, /* read end of a pipe */
|
||||||
|
FH_PIPEW = 0x0000000a, /* write end of a pipe */
|
||||||
|
FH_SOCKET = 0x0000000b, /* is a socket */
|
||||||
|
FH_WINDOWS = 0x0000000c, /* is a window */
|
||||||
|
|
||||||
|
FH_SLOW = 0x00000010, /* "slow" device if below this */
|
||||||
|
|
||||||
|
/* Fast devices */
|
||||||
|
FH_DISK = 0x00000010, /* is a disk */
|
||||||
|
FH_FLOPPY = 0x00000011, /* is a floppy */
|
||||||
|
FH_TAPE = 0x00000012, /* is a tape */
|
||||||
|
FH_NULL = 0x00000013, /* is the null device */
|
||||||
|
FH_ZERO = 0x00000014, /* is the zero device */
|
||||||
|
|
||||||
|
FH_NDEV = 0x00000015, /* Maximum number of devices */
|
||||||
|
FH_DEVMASK = 0x00000fff, /* devices live here */
|
||||||
|
FH_BAD = 0xffffffff
|
||||||
|
};
|
||||||
|
|
||||||
|
#define FHDEVN(n) ((n) & FH_DEVMASK)
|
||||||
|
#define FHISSETF(x) __ISSETF (this, x, FH)
|
||||||
|
#define FHSETF(x) __SETF (this, x, FH)
|
||||||
|
#define FHCLEARF(x) __CLEARF (this, x, FH)
|
||||||
|
#define FHCONDSETF(n, x) __CONDSETF(n, this, x, FH)
|
||||||
|
|
||||||
|
#define FHSTATOFF 0
|
||||||
|
|
||||||
|
extern const char *windows_device_names[];
|
||||||
|
#define __fmode (*(user_data->fmode_ptr))
|
||||||
|
|
||||||
|
class select_record;
|
||||||
|
class path_conv;
|
||||||
|
class fhandler_disk_file;
|
||||||
|
|
||||||
|
class fhandler_base
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
DWORD status;
|
||||||
|
public:
|
||||||
|
int cb;
|
||||||
|
private:
|
||||||
|
int access_;
|
||||||
|
HANDLE io_handle;
|
||||||
|
|
||||||
|
int rpos_; /* Used in text reading */
|
||||||
|
int rsize_;
|
||||||
|
|
||||||
|
unsigned long namehash_; /* hashed filename, used as inode num */
|
||||||
|
|
||||||
|
/* Full unix path name of this file */
|
||||||
|
/* File open flags from open () and fcntl () calls */
|
||||||
|
int openflags_;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
char *rabuf; /* used for crlf conversion in text files */
|
||||||
|
size_t ralen;
|
||||||
|
size_t raixget;
|
||||||
|
size_t raixput;
|
||||||
|
size_t rabuflen;
|
||||||
|
|
||||||
|
char *unix_path_name_;
|
||||||
|
char *win32_path_name_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void set_name (const char *unix, const char *win32 = NULL, int unit = 0);
|
||||||
|
|
||||||
|
virtual fhandler_base& operator =(fhandler_base &x)
|
||||||
|
{
|
||||||
|
memcpy (this, &x, sizeof *this);
|
||||||
|
unix_path_name_ = x.unix_path_name_ ? strdup (x.unix_path_name_) : NULL;
|
||||||
|
win32_path_name_ = x.win32_path_name_ ? strdup (x.win32_path_name_) : NULL;
|
||||||
|
return *this;
|
||||||
|
};
|
||||||
|
fhandler_base (DWORD dev, const char *name = 0, int unit = 0);
|
||||||
|
virtual ~fhandler_base ();
|
||||||
|
|
||||||
|
/* Non-virtual simple accessor functions. */
|
||||||
|
void set_io_handle (HANDLE);
|
||||||
|
|
||||||
|
void set_cb (size_t size) { cb = size; }
|
||||||
|
DWORD get_device () { return status & FH_DEVMASK; }
|
||||||
|
virtual int get_unit () { return 0; }
|
||||||
|
virtual BOOL is_slow () { return get_device () < FH_SLOW; }
|
||||||
|
|
||||||
|
int get_access () { return access_; }
|
||||||
|
void set_access (int x) { access_ = x; }
|
||||||
|
|
||||||
|
int get_async () { return FHISSETF (ASYNC); }
|
||||||
|
void set_async (int x) { FHCONDSETF (x, ASYNC); }
|
||||||
|
|
||||||
|
int get_flags () { return openflags_; }
|
||||||
|
void set_flags (int x) { openflags_ = x; }
|
||||||
|
|
||||||
|
int get_w_binary () { return FHISSETF (WBINARY); }
|
||||||
|
int get_r_binary () { return FHISSETF (RBINARY); }
|
||||||
|
|
||||||
|
int get_w_binset () { return FHISSETF (WBINSET); }
|
||||||
|
int get_r_binset () { return FHISSETF (RBINSET); }
|
||||||
|
|
||||||
|
void set_w_binary (int b) { FHCONDSETF (b, WBINARY); FHSETF (WBINSET); }
|
||||||
|
void set_r_binary (int b) { FHCONDSETF (b, RBINARY); FHSETF (RBINSET); }
|
||||||
|
|
||||||
|
int get_r_no_interrupt () { return FHISSETF (NOEINTR); }
|
||||||
|
void set_r_no_interrupt (int b) { FHCONDSETF (b, NOEINTR); }
|
||||||
|
|
||||||
|
int get_close_on_exec () { return FHISSETF (CLOEXEC); }
|
||||||
|
int set_close_on_exec_flag (int b) { return FHCONDSETF (b, CLOEXEC); }
|
||||||
|
|
||||||
|
void set_check_win95_lseek_bug (int b = 1) { FHCONDSETF (b, W95LSBUG); }
|
||||||
|
int get_check_win95_lseek_bug () { return FHISSETF (W95LSBUG); }
|
||||||
|
|
||||||
|
int get_need_fork_fixup () { return FHISSETF (FFIXUP); }
|
||||||
|
void set_need_fork_fixup () { FHSETF (FFIXUP); }
|
||||||
|
|
||||||
|
virtual void set_close_on_exec (int val);
|
||||||
|
virtual void fixup_after_fork (HANDLE parent);
|
||||||
|
|
||||||
|
int get_symlink_p () { return FHISSETF (SYMLINK); }
|
||||||
|
void set_symlink_p (int val) { FHCONDSETF (val, SYMLINK); }
|
||||||
|
void set_symlink_p () { FHSETF (SYMLINK); }
|
||||||
|
|
||||||
|
int get_socket_p () { return FHISSETF (LOCAL); }
|
||||||
|
void set_socket_p (int val) { FHCONDSETF (val, LOCAL); }
|
||||||
|
void set_socket_p () { FHSETF (LOCAL); }
|
||||||
|
|
||||||
|
int get_execable_p () { return FHISSETF (EXECABL); }
|
||||||
|
void set_execable_p (int val) { FHCONDSETF (val, EXECABL); }
|
||||||
|
void set_execable_p () { FHSETF (EXECABL); }
|
||||||
|
|
||||||
|
int get_append_p () { return FHISSETF (APPEND); }
|
||||||
|
void set_append_p (int val) { FHCONDSETF (val, APPEND); }
|
||||||
|
void set_append_p () { FHSETF (APPEND); }
|
||||||
|
|
||||||
|
int get_readahead_valid () { return raixget < ralen; }
|
||||||
|
int puts_readahead (const char *s, size_t len = (size_t) -1);
|
||||||
|
int put_readahead (char value);
|
||||||
|
|
||||||
|
int get_readahead ();
|
||||||
|
int peek_readahead (int queryput = 0);
|
||||||
|
|
||||||
|
int eat_readahead (int n);
|
||||||
|
|
||||||
|
void set_readahead_valid (int val, int ch = -1);
|
||||||
|
|
||||||
|
int has_acls () { return FHISSETF (HASACLS); }
|
||||||
|
void set_has_acls (int val) { FHCONDSETF (val, HASACLS); }
|
||||||
|
|
||||||
|
int no_free_names () { return FHISSETF (NOFRNAME); }
|
||||||
|
void set_no_free_names (int val) { FHCONDSETF (val, NOFRNAME); }
|
||||||
|
void set_no_free_names () { FHSETF (NOFRNAME); }
|
||||||
|
|
||||||
|
const char *get_name () { return unix_path_name_; }
|
||||||
|
const char *get_win32_name () { return win32_path_name_; }
|
||||||
|
unsigned long get_namehash () { return namehash_; }
|
||||||
|
|
||||||
|
|
||||||
|
/* fixup fd possibly non-inherited handles after fork */
|
||||||
|
void fork_fixup (HANDLE parent, HANDLE &h, const char *name);
|
||||||
|
|
||||||
|
/* Potentially overridden virtual functions. */
|
||||||
|
virtual int open (const char *, int flags, mode_t mode = 0)
|
||||||
|
{
|
||||||
|
return open (flags, mode);
|
||||||
|
}
|
||||||
|
virtual int open (int flags, mode_t mode = 0);
|
||||||
|
virtual int close ();
|
||||||
|
virtual int fstat (struct stat *buf);
|
||||||
|
virtual int ioctl (unsigned int cmd, void *);
|
||||||
|
virtual char const * ttyname () { return get_name(); }
|
||||||
|
virtual int read (void *ptr, size_t len);
|
||||||
|
virtual int write (const void *ptr, size_t len);
|
||||||
|
virtual off_t lseek (off_t offset, int whence);
|
||||||
|
virtual int lock (int, struct flock *);
|
||||||
|
virtual void dump ();
|
||||||
|
virtual int dup (fhandler_base *child);
|
||||||
|
|
||||||
|
void *operator new (size_t, void *p) {return p;}
|
||||||
|
|
||||||
|
virtual void init (HANDLE, DWORD, mode_t);
|
||||||
|
|
||||||
|
virtual int tcflush (int);
|
||||||
|
virtual int tcsendbreak (int);
|
||||||
|
virtual int tcdrain ();
|
||||||
|
virtual int tcflow (int);
|
||||||
|
virtual int tcsetattr (int a, const struct termios *t);
|
||||||
|
virtual int tcgetattr (struct termios *t);
|
||||||
|
virtual int tcsetpgrp (const pid_t pid);
|
||||||
|
virtual int tcgetpgrp ();
|
||||||
|
virtual int is_tty () { return 0; }
|
||||||
|
virtual BOOL is_device () { return TRUE; }
|
||||||
|
virtual char *ptsname () { return NULL;}
|
||||||
|
virtual class fhandler_socket *is_socket () { return 0; }
|
||||||
|
virtual class fhandler_console *is_console () { return 0; }
|
||||||
|
virtual int is_windows () {return 0; }
|
||||||
|
|
||||||
|
virtual int raw_read (void *ptr, size_t ulen);
|
||||||
|
virtual int raw_write (const void *ptr, size_t ulen);
|
||||||
|
|
||||||
|
/* Function to save state of a fhandler_base into memory. */
|
||||||
|
virtual int linearize (unsigned char *);
|
||||||
|
/* Function to de-linearize into a fd */
|
||||||
|
virtual int de_linearize (const char *, const char *, const char *);
|
||||||
|
|
||||||
|
/* Virtual accessor functions to hide the fact
|
||||||
|
that some fd's have two handles. */
|
||||||
|
virtual HANDLE get_handle () const { return io_handle; }
|
||||||
|
virtual HANDLE get_io_handle () const { return io_handle; }
|
||||||
|
virtual HANDLE get_output_handle () const { return io_handle; }
|
||||||
|
virtual BOOL hit_eof () {return FALSE;}
|
||||||
|
virtual select_record *select_read (select_record *s);
|
||||||
|
virtual select_record *select_write (select_record *s);
|
||||||
|
virtual select_record *select_except (select_record *s);
|
||||||
|
virtual int ready_for_read (int fd, DWORD howlong, int ignra);
|
||||||
|
virtual const char * get_native_name ()
|
||||||
|
{
|
||||||
|
return windows_device_names[FHDEVN (status)];
|
||||||
|
}
|
||||||
|
virtual int bg_check (int, int x = 0) {return 1;}
|
||||||
|
};
|
||||||
|
|
||||||
|
class fhandler_socket: public fhandler_base
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
int addr_family;
|
||||||
|
public:
|
||||||
|
fhandler_socket (const char *name = 0);
|
||||||
|
fhandler_socket (unsigned int, const char *name = 0);
|
||||||
|
~fhandler_socket ();
|
||||||
|
int get_socket () const { return (int) get_handle(); }
|
||||||
|
fhandler_socket * is_socket () { return this; }
|
||||||
|
int write (const void *ptr, size_t len);
|
||||||
|
int read (void *ptr, size_t len);
|
||||||
|
int ioctl (unsigned int cmd, void *);
|
||||||
|
off_t lseek (off_t offset, int whence) { return 0; }
|
||||||
|
int close ();
|
||||||
|
|
||||||
|
select_record *select_read (select_record *s);
|
||||||
|
select_record *select_write (select_record *s);
|
||||||
|
select_record *select_except (select_record *s);
|
||||||
|
int ready_for_read (int fd, DWORD howlong, int ignra);
|
||||||
|
int get_addr_family () {return addr_family;}
|
||||||
|
void set_addr_family (int af) {addr_family = af;}
|
||||||
|
};
|
||||||
|
|
||||||
|
class fhandler_pipe: public fhandler_base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
fhandler_pipe (const char *name = 0);
|
||||||
|
off_t lseek (off_t offset, int whence);
|
||||||
|
/* This strange test is due to the fact that we can't rely on
|
||||||
|
Windows shells to "do the right thing" with pipes. Apparently
|
||||||
|
the can keep one end of the pipe open when it shouldn't be. */
|
||||||
|
BOOL is_slow () {return os_being_run == winNT;}
|
||||||
|
select_record *select_read (select_record *s);
|
||||||
|
select_record *select_write (select_record *s);
|
||||||
|
select_record *select_except (select_record *s);
|
||||||
|
int ready_for_read (int fd, DWORD howlong, int ignra);
|
||||||
|
};
|
||||||
|
|
||||||
|
class fhandler_dev_raw: public fhandler_base
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
char *devbuf;
|
||||||
|
size_t devbufsiz;
|
||||||
|
size_t devbufstart;
|
||||||
|
size_t devbufend;
|
||||||
|
int eom_detected : 1;
|
||||||
|
int eof_detected : 1;
|
||||||
|
int lastblk_to_read : 1;
|
||||||
|
int is_writing : 1;
|
||||||
|
int has_written : 1;
|
||||||
|
int unit;
|
||||||
|
|
||||||
|
virtual void clear (void);
|
||||||
|
virtual int writebuf (void);
|
||||||
|
|
||||||
|
/* returns not null, if `win_error' determines an end of media condition */
|
||||||
|
virtual int is_eom(int win_error) = 0;
|
||||||
|
/* returns not null, if `win_error' determines an end of file condition */
|
||||||
|
virtual int is_eof(int win_error) = 0;
|
||||||
|
|
||||||
|
fhandler_dev_raw (DWORD dev, const char *name, int unit);
|
||||||
|
|
||||||
|
public:
|
||||||
|
~fhandler_dev_raw (void);
|
||||||
|
|
||||||
|
/* Function to de-linearize into a fd */
|
||||||
|
int de_linearize (const char *, const char *, const char *);
|
||||||
|
|
||||||
|
int open (const char *path, int flags, mode_t mode = 0);
|
||||||
|
int close (void);
|
||||||
|
|
||||||
|
int raw_read (void *ptr, size_t ulen);
|
||||||
|
int raw_write (const void *ptr, size_t ulen);
|
||||||
|
|
||||||
|
int fstat (struct stat *buf);
|
||||||
|
|
||||||
|
int dup (fhandler_base *child);
|
||||||
|
|
||||||
|
int ioctl (unsigned int cmd, void *buf);
|
||||||
|
};
|
||||||
|
|
||||||
|
class fhandler_dev_floppy: public fhandler_dev_raw
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
virtual int is_eom (int win_error);
|
||||||
|
virtual int is_eof (int win_error);
|
||||||
|
|
||||||
|
public:
|
||||||
|
fhandler_dev_floppy (const char *name, int unit);
|
||||||
|
|
||||||
|
virtual int open (const char *path, int flags, mode_t mode = 0);
|
||||||
|
virtual int close (void);
|
||||||
|
|
||||||
|
virtual off_t lseek (off_t offset, int whence);
|
||||||
|
|
||||||
|
virtual int ioctl (unsigned int cmd, void *buf);
|
||||||
|
};
|
||||||
|
|
||||||
|
class fhandler_dev_tape: public fhandler_dev_raw
|
||||||
|
{
|
||||||
|
int norewind;
|
||||||
|
int lasterr;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void clear (void);
|
||||||
|
|
||||||
|
virtual int is_eom (int win_error);
|
||||||
|
virtual int is_eof (int win_error);
|
||||||
|
|
||||||
|
public:
|
||||||
|
fhandler_dev_tape (const char *name, int unit);
|
||||||
|
|
||||||
|
virtual int open (const char *path, int flags, mode_t mode = 0);
|
||||||
|
virtual int close (void);
|
||||||
|
|
||||||
|
virtual off_t lseek (off_t offset, int whence);
|
||||||
|
|
||||||
|
virtual int fstat (struct stat *buf);
|
||||||
|
|
||||||
|
virtual int dup (fhandler_base *child);
|
||||||
|
|
||||||
|
virtual int ioctl (unsigned int cmd, void *buf);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int tape_write_marks (int marktype, DWORD len);
|
||||||
|
int tape_get_pos (unsigned long *ret);
|
||||||
|
int tape_set_pos (int mode, long count, BOOLEAN sfm_func = FALSE);
|
||||||
|
int tape_erase (int mode);
|
||||||
|
int tape_prepare (int action);
|
||||||
|
BOOLEAN tape_get_feature (DWORD parm);
|
||||||
|
int tape_get_blocksize (long *min, long *def, long *max, long *cur);
|
||||||
|
int tape_set_blocksize (long count);
|
||||||
|
int tape_status (struct mtget *get);
|
||||||
|
int tape_compression (long count);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Standard disk file */
|
||||||
|
|
||||||
|
class fhandler_disk_file: public fhandler_base
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
int check_execable_p (const char *path);
|
||||||
|
|
||||||
|
public:
|
||||||
|
fhandler_disk_file (const char *name);
|
||||||
|
|
||||||
|
int open (const char *path, int flags, mode_t mode = 0);
|
||||||
|
int open (path_conv& real_path, int flags, mode_t mode);
|
||||||
|
int close ();
|
||||||
|
int lock (int, struct flock *);
|
||||||
|
BOOL is_device () { return FALSE; }
|
||||||
|
int fstat (struct stat *buf);
|
||||||
|
};
|
||||||
|
|
||||||
|
class fhandler_serial: public fhandler_base
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
unsigned int vmin_; /* from termios */
|
||||||
|
unsigned int vtime_; /* from termios */
|
||||||
|
pid_t pgrp_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
int overlapped_armed;
|
||||||
|
OVERLAPPED io_status;
|
||||||
|
|
||||||
|
/* Constructor */
|
||||||
|
fhandler_serial (const char *name, DWORD devtype = FH_SERIAL, int unit = 0);
|
||||||
|
|
||||||
|
int open (const char *path, int flags, mode_t mode);
|
||||||
|
int close ();
|
||||||
|
void init (HANDLE h, DWORD a, mode_t flags);
|
||||||
|
void overlapped_setup ();
|
||||||
|
int dup (fhandler_base *child);
|
||||||
|
int raw_read (void *ptr, size_t ulen);
|
||||||
|
int raw_write (const void *ptr, size_t ulen);
|
||||||
|
int tcsendbreak (int);
|
||||||
|
int tcdrain ();
|
||||||
|
int tcflow (int);
|
||||||
|
int tcsetattr (int a, const struct termios *t);
|
||||||
|
int tcgetattr (struct termios *t);
|
||||||
|
off_t lseek (off_t offset, int whence) { return 0; }
|
||||||
|
int tcflush (int);
|
||||||
|
void dump ();
|
||||||
|
int is_tty () { return 1; }
|
||||||
|
void fixup_after_fork (HANDLE parent);
|
||||||
|
int de_linearize (const char *, const char *, const char *);
|
||||||
|
|
||||||
|
/* We maintain a pgrp so that tcsetpgrp and tcgetpgrp work, but we
|
||||||
|
don't use it for permissions checking. fhandler_tty_slave does
|
||||||
|
permission checking on pgrps. */
|
||||||
|
virtual int tcgetpgrp () { return pgrp_; }
|
||||||
|
virtual int tcsetpgrp (const pid_t pid) { pgrp_ = pid; return 0; }
|
||||||
|
select_record *select_read (select_record *s);
|
||||||
|
select_record *select_write (select_record *s);
|
||||||
|
select_record *select_except (select_record *s);
|
||||||
|
int ready_for_read (int fd, DWORD howlong, int ignra);
|
||||||
|
};
|
||||||
|
|
||||||
|
class fhandler_termios: public fhandler_base
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
HANDLE output_handle;
|
||||||
|
virtual void doecho (const void *str, DWORD len) {};
|
||||||
|
virtual int accept_input () {return 1;};
|
||||||
|
public:
|
||||||
|
tty_min *tc;
|
||||||
|
fhandler_termios (DWORD dev, const char *name = 0, int unit = 0) :
|
||||||
|
fhandler_base (dev, name, unit)
|
||||||
|
{
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
|
HANDLE restart_output_event;
|
||||||
|
HANDLE get_output_handle () const { return output_handle; }
|
||||||
|
int line_edit (const char *rptr, int nread, int always_accept = 0);
|
||||||
|
void set_output_handle (HANDLE h) { output_handle = h; }
|
||||||
|
void tcinit (tty_min *this_tc, int force = FALSE);
|
||||||
|
virtual int is_tty () { return 1; }
|
||||||
|
int tcgetpgrp ();
|
||||||
|
int tcsetpgrp (int pid);
|
||||||
|
void set_ctty (int ttynum, int flags);
|
||||||
|
int bg_check (int sig, int blocksigs = 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This is a input and output console handle */
|
||||||
|
class fhandler_console: public fhandler_termios
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
/* Output state */
|
||||||
|
|
||||||
|
// enum {normal, gotesc, gotsquare, gotarg1, gotcommand} state;
|
||||||
|
#define normal 1
|
||||||
|
#define gotesc 2
|
||||||
|
#define gotsquare 3
|
||||||
|
#define gotarg1 4
|
||||||
|
#define gotrsquare 5
|
||||||
|
#define gotcommand 6
|
||||||
|
#define gettitle 7
|
||||||
|
#define eattitle 8
|
||||||
|
#define MAXARGS 10
|
||||||
|
int state_;
|
||||||
|
int args_[MAXARGS];
|
||||||
|
int nargs_;
|
||||||
|
|
||||||
|
DWORD default_color;
|
||||||
|
|
||||||
|
/* Output calls */
|
||||||
|
|
||||||
|
BOOL fillin_info ();
|
||||||
|
void clear_screen (int, int, int, int);
|
||||||
|
void scroll_screen (int, int, int, int, int, int);
|
||||||
|
void cursor_set (BOOL, int, int);
|
||||||
|
void cursor_get (int *, int *);
|
||||||
|
void cursor_rel (int, int);
|
||||||
|
const unsigned char * write_normal (unsigned const char*, unsigned const char *);
|
||||||
|
void char_command (char);
|
||||||
|
int output_tcsetattr (int a, const struct termios *t);
|
||||||
|
|
||||||
|
/* Input calls */
|
||||||
|
int igncr_enabled ();
|
||||||
|
int input_tcsetattr (int a, const struct termios *t);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
fhandler_console (const char *name);
|
||||||
|
|
||||||
|
fhandler_console* is_console () { return this; }
|
||||||
|
|
||||||
|
int open (const char *path, int flags, mode_t mode = 0);
|
||||||
|
|
||||||
|
int write (const void *ptr, size_t len);
|
||||||
|
void doecho (const void *str, DWORD len) { (void) write (str, len); }
|
||||||
|
int read (void *ptr, size_t len);
|
||||||
|
int close ();
|
||||||
|
|
||||||
|
int tcflush (int);
|
||||||
|
int tcsetattr (int a, const struct termios *t);
|
||||||
|
int tcgetattr (struct termios *t);
|
||||||
|
|
||||||
|
int tcsetpgrp (const pid_t pid) { tc->pgid = pid; return 0; }
|
||||||
|
|
||||||
|
/* Special dup as we must dup two handles */
|
||||||
|
int dup (fhandler_base *child);
|
||||||
|
|
||||||
|
int ioctl (unsigned int cmd, void *);
|
||||||
|
void init (HANDLE, DWORD, mode_t);
|
||||||
|
|
||||||
|
select_record *select_read (select_record *s);
|
||||||
|
select_record *select_write (select_record *s);
|
||||||
|
select_record *select_except (select_record *s);
|
||||||
|
int ready_for_read (int fd, DWORD howlong, int ignra);
|
||||||
|
int de_linearize (const char *, const char *, const char *);
|
||||||
|
void set_close_on_exec (int val);
|
||||||
|
void fixup_after_fork (HANDLE parent);
|
||||||
|
void set_input_state ()
|
||||||
|
{
|
||||||
|
if (TTYISSETF (RSTCONS))
|
||||||
|
input_tcsetattr (0, &tc->ti);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class fhandler_tty_common: public fhandler_termios
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
fhandler_tty_common (DWORD dev, const char *name = 0, int unit = 0) :
|
||||||
|
fhandler_termios (dev, name, unit),
|
||||||
|
ttynum (unit)
|
||||||
|
{
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
|
HANDLE output_done_event; // Raised by master when tty's output buffer
|
||||||
|
// written. Write status in tty::write_retval.
|
||||||
|
HANDLE ioctl_request_event; // Raised by slave to perform ioctl() request.
|
||||||
|
// Ioctl() request in tty::cmd/arg.
|
||||||
|
HANDLE ioctl_done_event; // Raised by master on ioctl() completion.
|
||||||
|
// Ioctl() status in tty::ioctl_retval.
|
||||||
|
HANDLE output_mutex;
|
||||||
|
HANDLE inuse; // used to indicate that a tty is in use
|
||||||
|
|
||||||
|
|
||||||
|
DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms);
|
||||||
|
void __release_output_mutex (const char *fn, int ln);
|
||||||
|
|
||||||
|
int ttynum; // Master tty num.
|
||||||
|
virtual int dup (fhandler_base *child);
|
||||||
|
|
||||||
|
tty *get_ttyp () { return (tty *)tc; }
|
||||||
|
int get_unit () { return ttynum; }
|
||||||
|
|
||||||
|
int close ();
|
||||||
|
void set_close_on_exec (int val);
|
||||||
|
void fixup_after_fork (HANDLE parent);
|
||||||
|
select_record *select_read (select_record *s);
|
||||||
|
select_record *select_write (select_record *s);
|
||||||
|
select_record *select_except (select_record *s);
|
||||||
|
int ready_for_read (int fd, DWORD howlong, int ignra);
|
||||||
|
};
|
||||||
|
|
||||||
|
class fhandler_tty_slave: public fhandler_tty_common
|
||||||
|
{
|
||||||
|
void send_ioctl_request ();
|
||||||
|
|
||||||
|
public:
|
||||||
|
/* Constructor */
|
||||||
|
fhandler_tty_slave (const char *name);
|
||||||
|
fhandler_tty_slave (int, const char *name);
|
||||||
|
|
||||||
|
int open (const char *path, int flags, mode_t mode = 0);
|
||||||
|
int write (const void *ptr, size_t len);
|
||||||
|
int read (void *ptr, size_t len);
|
||||||
|
void init (HANDLE, DWORD, mode_t);
|
||||||
|
|
||||||
|
int tcsetattr (int a, const struct termios *t);
|
||||||
|
int tcgetattr (struct termios *t);
|
||||||
|
int tcflush (int);
|
||||||
|
int ioctl (unsigned int cmd, void *);
|
||||||
|
|
||||||
|
off_t lseek (off_t offset, int whence) { return 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class fhandler_pty_master: public fhandler_tty_common
|
||||||
|
{
|
||||||
|
int pktmode; // non-zero if pty in a packet mode.
|
||||||
|
public:
|
||||||
|
int neednl_; // Next read should start with \n
|
||||||
|
|
||||||
|
/* Constructor */
|
||||||
|
fhandler_pty_master (const char *name, DWORD devtype = FH_PTYM, int unit = -1);
|
||||||
|
|
||||||
|
int process_slave_output (char *buf, size_t len);
|
||||||
|
void doecho (const void *str, DWORD len);
|
||||||
|
int accept_input ();
|
||||||
|
int open (const char *path, int flags, mode_t mode = 0);
|
||||||
|
int write (const void *ptr, size_t len);
|
||||||
|
int read (void *ptr, size_t len);
|
||||||
|
int close ();
|
||||||
|
|
||||||
|
int tcsetattr (int a, const struct termios *t);
|
||||||
|
int tcgetattr (struct termios *t);
|
||||||
|
int tcflush (int);
|
||||||
|
int ioctl (unsigned int cmd, void *);
|
||||||
|
|
||||||
|
off_t lseek (off_t offset, int whence) { return 0; }
|
||||||
|
char *ptsname ();
|
||||||
|
|
||||||
|
void set_close_on_exec (int val);
|
||||||
|
void fixup_after_fork (HANDLE parent);
|
||||||
|
BOOL hit_eof ();
|
||||||
|
};
|
||||||
|
|
||||||
|
class fhandler_tty_master: public fhandler_pty_master
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/* Constructor */
|
||||||
|
fhandler_tty_master (const char *name, int unit);
|
||||||
|
fhandler_console *console; // device handler to perform real i/o.
|
||||||
|
HANDLE hThread; // process_output thread handle.
|
||||||
|
|
||||||
|
int init (int);
|
||||||
|
int init_console ();
|
||||||
|
void fixup_after_fork (HANDLE parent);
|
||||||
|
int de_linearize (const char *, const char *, const char *);
|
||||||
|
};
|
||||||
|
|
||||||
|
class fhandler_dev_null: public fhandler_base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
fhandler_dev_null (const char *name);
|
||||||
|
|
||||||
|
void dump ();
|
||||||
|
select_record *select_read (select_record *s);
|
||||||
|
select_record *select_write (select_record *s);
|
||||||
|
select_record *select_except (select_record *s);
|
||||||
|
};
|
||||||
|
|
||||||
|
class fhandler_dev_zero: public fhandler_base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
fhandler_dev_zero (const char *name);
|
||||||
|
int open (const char *path, int flags, mode_t mode = 0);
|
||||||
|
int write (const void *ptr, size_t len);
|
||||||
|
int read (void *ptr, size_t len);
|
||||||
|
off_t lseek (off_t offset, int whence);
|
||||||
|
int close (void);
|
||||||
|
|
||||||
|
void dump ();
|
||||||
|
};
|
||||||
|
|
||||||
|
class fhandler_windows: public fhandler_base
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
HWND hWnd_; // the window whose messages are to be retrieved by read() call
|
||||||
|
int method_; // write method (Post or Send)
|
||||||
|
public:
|
||||||
|
fhandler_windows (const char *name = 0);
|
||||||
|
int is_windows (void) { return 1; }
|
||||||
|
int open (const char *path, int flags, mode_t mode = 0);
|
||||||
|
int write (const void *ptr, size_t len);
|
||||||
|
int read (void *ptr, size_t len);
|
||||||
|
int ioctl (unsigned int cmd, void *);
|
||||||
|
off_t lseek (off_t offset, int whence) { return 0; }
|
||||||
|
int close (void) { return 0; }
|
||||||
|
|
||||||
|
void set_close_on_exec (int val);
|
||||||
|
void fixup_after_fork (HANDLE parent);
|
||||||
|
select_record *select_read (select_record *s);
|
||||||
|
select_record *select_write (select_record *s);
|
||||||
|
select_record *select_except (select_record *s);
|
||||||
|
int ready_for_read (int fd, DWORD howlong, int ignra);
|
||||||
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* You can't do this */
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
fhandler_normal normal;
|
||||||
|
fhandler_dev_null dev_null;
|
||||||
|
fhandler bare;
|
||||||
|
fhandler_serial tty;
|
||||||
|
} fhandler_union;
|
||||||
|
#else
|
||||||
|
#define fhandler_union fhandler_console
|
||||||
|
#endif
|
||||||
|
struct select_record
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
HANDLE h;
|
||||||
|
fhandler_base *fh;
|
||||||
|
BOOL saw_error;
|
||||||
|
BOOL windows_handle;
|
||||||
|
BOOL read_ready, write_ready, except_ready;
|
||||||
|
BOOL read_selected, write_selected, except_selected;
|
||||||
|
select_record (fhandler_base *in_fh = NULL) {memset (this, 0, sizeof(select_record)); fh = in_fh;}
|
||||||
|
int (*startup) (select_record *me, class select_stuff *stuff);
|
||||||
|
int (*poll) (select_record *me, fd_set *readfds, fd_set *writefds,
|
||||||
|
fd_set *exceptfds);
|
||||||
|
int (*verify) (select_record *me, fd_set *readfds, fd_set *writefds,
|
||||||
|
fd_set *exceptfds);
|
||||||
|
void (*cleanup) (select_record *me, class select_stuff *stuff);
|
||||||
|
struct select_record *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
class select_stuff
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~select_stuff ();
|
||||||
|
BOOL always_ready, windows_used;
|
||||||
|
int total;
|
||||||
|
select_record start;
|
||||||
|
void *device_specific[FH_NDEV];
|
||||||
|
|
||||||
|
int test_and_set (int i, fd_set *readfds, fd_set *writefds,
|
||||||
|
fd_set *exceptfds);
|
||||||
|
int poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds);
|
||||||
|
int wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds, DWORD ms);
|
||||||
|
};
|
||||||
|
|
||||||
|
uid_t __stdcall get_file_owner (int, const char *);
|
||||||
|
gid_t __stdcall get_file_group (int, const char *);
|
||||||
|
|
||||||
|
void __stdcall set_inheritance (HANDLE &h, int val, const char *name = NULL);
|
||||||
|
|
||||||
|
#endif /* _FHANDLER_H_ */
|
1387
winsup/cygwin/fhandler_console.cc
Normal file
1387
winsup/cygwin/fhandler_console.cc
Normal file
File diff suppressed because it is too large
Load Diff
90
winsup/cygwin/fhandler_floppy.cc
Normal file
90
winsup/cygwin/fhandler_floppy.cc
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/* fhandler_floppy.cc. See fhandler.h for a description of the
|
||||||
|
fhandler classes.
|
||||||
|
|
||||||
|
Copyright 1999 Cygnus Solutions.
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include <sys/termios.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "winsup.h"
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/* fhandler_dev_floppy */
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_floppy::is_eom (int win_error)
|
||||||
|
{
|
||||||
|
int ret = (win_error == ERROR_INVALID_PARAMETER);
|
||||||
|
if (ret)
|
||||||
|
debug_printf ("end of medium");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_floppy::is_eof (int win_error)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
if (ret)
|
||||||
|
debug_printf ("end of file");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
fhandler_dev_floppy::fhandler_dev_floppy (const char *name, int unit) : fhandler_dev_raw (FH_FLOPPY, name, unit)
|
||||||
|
{
|
||||||
|
set_cb (sizeof *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_floppy::open (const char *path, int flags, mode_t)
|
||||||
|
{
|
||||||
|
/* The correct size of the buffer would be 512 bytes,
|
||||||
|
* which is the atomic size, supported by WinNT.
|
||||||
|
* Unfortunately, the performance is worse than
|
||||||
|
* access to file system on same device!
|
||||||
|
* Setting buffer size to a relatively big value
|
||||||
|
* increases performance by means.
|
||||||
|
* The new ioctl call with 'rdevio.h' header file
|
||||||
|
* supports changing this value.
|
||||||
|
*
|
||||||
|
* Let's be smart: Let's take a multiplier of typical tar
|
||||||
|
* and cpio buffer sizes by default!
|
||||||
|
*/
|
||||||
|
devbufsiz = 61440L; /* 512L; */
|
||||||
|
return fhandler_dev_raw::open (path, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_floppy::close (void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = writebuf ();
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
fhandler_dev_raw::close ();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return fhandler_dev_raw::close ();
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t
|
||||||
|
fhandler_dev_floppy::lseek (off_t offset, int whence)
|
||||||
|
{
|
||||||
|
/* FIXME: Need to implement better. */
|
||||||
|
offset = (offset / 512) * 512;
|
||||||
|
return fhandler_base::lseek (offset, whence);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_floppy::ioctl (unsigned int cmd, void *buf)
|
||||||
|
{
|
||||||
|
return fhandler_dev_raw::ioctl (cmd, buf);
|
||||||
|
}
|
||||||
|
|
495
winsup/cygwin/fhandler_raw.cc
Normal file
495
winsup/cygwin/fhandler_raw.cc
Normal file
@ -0,0 +1,495 @@
|
|||||||
|
/* fhandler_raw.cc. See fhandler.h for a description of the fhandler classes.
|
||||||
|
|
||||||
|
Copyright 1999, 2000 Cygnus Solutions.
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include <sys/termios.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "winsup.h"
|
||||||
|
|
||||||
|
#include <cygwin/rdevio.h>
|
||||||
|
#include <sys/mtio.h>
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/* fhandler_dev_raw */
|
||||||
|
|
||||||
|
void
|
||||||
|
fhandler_dev_raw::clear (void)
|
||||||
|
{
|
||||||
|
devbuf = NULL;
|
||||||
|
devbufsiz = 0;
|
||||||
|
devbufstart = 0;
|
||||||
|
devbufend = 0;
|
||||||
|
eom_detected = 0;
|
||||||
|
eof_detected = 0;
|
||||||
|
lastblk_to_read = 0;
|
||||||
|
unit = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_raw::writebuf (void)
|
||||||
|
{
|
||||||
|
DWORD written;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (is_writing && devbuf && devbufend)
|
||||||
|
{
|
||||||
|
memset (devbuf + devbufend, 0, devbufsiz - devbufend);
|
||||||
|
DWORD to_write = ((devbufend - 1) / 512 + 1) * 512;
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
if (!WriteFile (get_handle (), devbuf, to_write, &written, 0))
|
||||||
|
{
|
||||||
|
ret = GetLastError ();
|
||||||
|
if (is_eom (ret))
|
||||||
|
eom_detected = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (written)
|
||||||
|
has_written = 1;
|
||||||
|
|
||||||
|
syscall_printf ("%d = WriteFile(%d, %d, write %d, written %d, 0)\n",
|
||||||
|
ret, get_handle (), devbuf, to_write, written);
|
||||||
|
devbufstart = devbufend = 0;
|
||||||
|
}
|
||||||
|
is_writing = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
fhandler_dev_raw::fhandler_dev_raw (DWORD devtype, const char *name, int unit) : fhandler_base (devtype, name)
|
||||||
|
{
|
||||||
|
clear ();
|
||||||
|
this->unit = unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
fhandler_dev_raw::~fhandler_dev_raw (void)
|
||||||
|
{
|
||||||
|
delete[]devbuf;
|
||||||
|
clear ();
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_raw::de_linearize (const char *buf, const char *unix_name,
|
||||||
|
const char *win32_name)
|
||||||
|
{
|
||||||
|
int ret = fhandler_base::de_linearize (buf, unix_name, win32_name);
|
||||||
|
if (devbufsiz > 1L)
|
||||||
|
{
|
||||||
|
devbuf = new char[devbufsiz];
|
||||||
|
devbufstart = devbufend = 0;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_raw::open (const char *path, int flags, mode_t)
|
||||||
|
{
|
||||||
|
path_conv real_path (path, SYMLINK_IGNORE);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
set_name (path, real_path.get_win32 ());
|
||||||
|
|
||||||
|
/* Always open a raw device existing */
|
||||||
|
ret = fhandler_base::open (path, flags & ~(O_CREAT | O_TRUNC));
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
if (devbufsiz > 1L)
|
||||||
|
{
|
||||||
|
devbuf = new char[devbufsiz];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
devbufsiz = 0;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_raw::close (void)
|
||||||
|
{
|
||||||
|
return fhandler_base::close ();
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_raw::fstat (struct stat *buf)
|
||||||
|
{
|
||||||
|
if (!buf)
|
||||||
|
{
|
||||||
|
set_errno (EINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (buf, 0, sizeof *buf);
|
||||||
|
buf->st_mode = S_IFCHR |
|
||||||
|
S_IRUSR | S_IWUSR |
|
||||||
|
S_IRGRP | S_IWGRP |
|
||||||
|
S_IROTH | S_IWOTH;
|
||||||
|
buf->st_nlink = 1;
|
||||||
|
buf->st_blksize = devbuf ? devbufsiz : 1;
|
||||||
|
buf->st_dev = buf->st_rdev = get_device () << 8 | (unit & 0xff);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_raw::raw_read (void *ptr, size_t ulen)
|
||||||
|
{
|
||||||
|
DWORD bytes_read = 0;
|
||||||
|
DWORD read2;
|
||||||
|
DWORD bytes_to_read;
|
||||||
|
int ret;
|
||||||
|
size_t len = ulen;
|
||||||
|
char *tgt;
|
||||||
|
|
||||||
|
/* In mode O_RDWR the buffer has to be written to device first */
|
||||||
|
ret = writebuf ();
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
set_errno (is_eom (ret) ? ENOSPC : EACCES);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Checking a previous end of file */
|
||||||
|
if (eof_detected && !lastblk_to_read)
|
||||||
|
{
|
||||||
|
eof_detected = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Checking a previous end of media */
|
||||||
|
if (eom_detected && !lastblk_to_read)
|
||||||
|
{
|
||||||
|
set_errno (ENOSPC);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (devbuf)
|
||||||
|
{
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
if (devbufstart < devbufend)
|
||||||
|
{
|
||||||
|
bytes_to_read = min (len, devbufend - devbufstart);
|
||||||
|
debug_printf ("read %d bytes from buffer (rest %d)\n",
|
||||||
|
bytes_to_read, devbufstart - devbufend);
|
||||||
|
memcpy (ptr, devbuf + devbufstart, bytes_to_read);
|
||||||
|
len -= bytes_to_read;
|
||||||
|
ptr = (void *) ((char *) ptr + bytes_to_read);
|
||||||
|
bytes_read += bytes_to_read;
|
||||||
|
devbufstart += bytes_to_read;
|
||||||
|
|
||||||
|
if (lastblk_to_read)
|
||||||
|
{
|
||||||
|
lastblk_to_read = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (len > 0)
|
||||||
|
{
|
||||||
|
if (len >= devbufsiz)
|
||||||
|
{
|
||||||
|
bytes_to_read = (len / 512) * 512;
|
||||||
|
tgt = (char *) ptr;
|
||||||
|
debug_printf ("read %d bytes direct from file\n",
|
||||||
|
bytes_to_read);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bytes_to_read = devbufsiz;
|
||||||
|
tgt = devbuf;
|
||||||
|
debug_printf ("read %d bytes from file into buffer\n",
|
||||||
|
bytes_to_read);
|
||||||
|
}
|
||||||
|
if (!ReadFile (get_handle (), tgt, bytes_to_read, &read2, 0))
|
||||||
|
{
|
||||||
|
ret = GetLastError ();
|
||||||
|
syscall_printf ("ReadFile %s failed with error %d\n",
|
||||||
|
get_name (), ret);
|
||||||
|
if (!is_eof (ret) && !is_eom (ret))
|
||||||
|
{
|
||||||
|
debug_printf ("return -1, set errno to EACCES");
|
||||||
|
set_errno (EACCES);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_eof (ret))
|
||||||
|
eof_detected = 1;
|
||||||
|
else
|
||||||
|
eom_detected = 1;
|
||||||
|
|
||||||
|
if (!read2)
|
||||||
|
{
|
||||||
|
if (!bytes_read && is_eom (ret))
|
||||||
|
{
|
||||||
|
debug_printf ("return -1, set errno to ENOSPC");
|
||||||
|
set_errno (ENOSPC);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lastblk_to_read = 1;
|
||||||
|
}
|
||||||
|
if (! read2)
|
||||||
|
break;
|
||||||
|
if (tgt == devbuf)
|
||||||
|
{
|
||||||
|
devbufstart = 0;
|
||||||
|
devbufend = read2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
len -= bytes_to_read;
|
||||||
|
ptr = (void *) ((char *) ptr + bytes_to_read);
|
||||||
|
bytes_read += bytes_to_read;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!ReadFile (get_handle (), ptr, len, &bytes_read, 0))
|
||||||
|
{
|
||||||
|
ret = GetLastError ();
|
||||||
|
syscall_printf ("ReadFile %s failed with error %d\n",
|
||||||
|
get_name (), ret);
|
||||||
|
if (!is_eof (ret) && !is_eom (ret))
|
||||||
|
{
|
||||||
|
debug_printf ("return -1, set errno to EACCES");
|
||||||
|
set_errno (EACCES);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (bytes_read)
|
||||||
|
{
|
||||||
|
if (is_eof (ret))
|
||||||
|
eof_detected = 1;
|
||||||
|
else
|
||||||
|
eom_detected = 1;
|
||||||
|
}
|
||||||
|
else if (is_eom (ret))
|
||||||
|
{
|
||||||
|
debug_printf ("return -1, set errno to ENOSPC");
|
||||||
|
set_errno (ENOSPC);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_raw::raw_write (const void *ptr, size_t len)
|
||||||
|
{
|
||||||
|
DWORD bytes_written = 0;
|
||||||
|
DWORD bytes_to_write;
|
||||||
|
DWORD written;
|
||||||
|
char *p = (char *) ptr;
|
||||||
|
char *tgt;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Checking a previous end of media on tape */
|
||||||
|
if (eom_detected)
|
||||||
|
{
|
||||||
|
set_errno (ENOSPC);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_writing)
|
||||||
|
devbufstart = devbufend = 0;
|
||||||
|
is_writing = 1;
|
||||||
|
|
||||||
|
if (devbuf)
|
||||||
|
{
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
if ((len < devbufsiz || devbufend > 0) && devbufend < devbufsiz)
|
||||||
|
{
|
||||||
|
bytes_to_write = min (len, devbufsiz - devbufend);
|
||||||
|
memcpy (devbuf + devbufend, p, bytes_to_write);
|
||||||
|
bytes_written += bytes_to_write;
|
||||||
|
devbufend += bytes_to_write;
|
||||||
|
p += bytes_to_write;
|
||||||
|
len -= bytes_to_write;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (devbufend == devbufsiz)
|
||||||
|
{
|
||||||
|
bytes_to_write = devbufsiz;
|
||||||
|
tgt = devbuf;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bytes_to_write = (len / devbufsiz) * devbufsiz;
|
||||||
|
tgt = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
if (!WriteFile (get_handle (), tgt, bytes_to_write, &written, 0))
|
||||||
|
ret = GetLastError ();
|
||||||
|
syscall_printf ("%d = WriteFile(%d, %d, write %d, written %d, 0)\n",
|
||||||
|
ret, get_handle (), tgt, bytes_to_write, written);
|
||||||
|
if (written)
|
||||||
|
has_written = 1;
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
if (!is_eom (ret))
|
||||||
|
{
|
||||||
|
__seterrno ();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
eom_detected = 1;
|
||||||
|
|
||||||
|
if (!written && !bytes_written)
|
||||||
|
{
|
||||||
|
set_errno (ENOSPC);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tgt == p)
|
||||||
|
bytes_written += written;
|
||||||
|
|
||||||
|
break; // from while (len > 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tgt == devbuf)
|
||||||
|
{
|
||||||
|
if (written != devbufsiz)
|
||||||
|
memmove (devbuf, devbuf + written, devbufsiz - written);
|
||||||
|
devbufend = devbufsiz - written;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
len -= written;
|
||||||
|
p += written;
|
||||||
|
bytes_written += written;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (len > 0)
|
||||||
|
{
|
||||||
|
if (!WriteFile (get_handle (), ptr, len, &bytes_written, 0))
|
||||||
|
{
|
||||||
|
ret = GetLastError ();
|
||||||
|
syscall_printf ("WriteFile %s failed with error %d\n",
|
||||||
|
get_name (), ret);
|
||||||
|
if (bytes_written)
|
||||||
|
has_written = 1;
|
||||||
|
if (!is_eom (ret))
|
||||||
|
{
|
||||||
|
set_errno (EACCES);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
eom_detected = 1;
|
||||||
|
if (!bytes_written)
|
||||||
|
{
|
||||||
|
set_errno (ENOSPC);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
has_written = 1;
|
||||||
|
}
|
||||||
|
return bytes_written;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_raw::dup (fhandler_base *child)
|
||||||
|
{
|
||||||
|
int ret = fhandler_base::dup (child);
|
||||||
|
|
||||||
|
if (! ret)
|
||||||
|
{
|
||||||
|
fhandler_dev_raw *fhc = (fhandler_dev_raw *) child;
|
||||||
|
|
||||||
|
fhc->devbufsiz = devbufsiz;
|
||||||
|
if (devbufsiz > 1L)
|
||||||
|
{
|
||||||
|
fhc->devbuf = new char[devbufsiz];
|
||||||
|
memcpy (fhc->devbuf, devbuf, devbufend);
|
||||||
|
}
|
||||||
|
fhc->devbufstart = devbufstart;
|
||||||
|
fhc->devbufend = devbufend;
|
||||||
|
fhc->eom_detected = eom_detected;
|
||||||
|
fhc->eof_detected = eof_detected;
|
||||||
|
fhc->lastblk_to_read = lastblk_to_read;
|
||||||
|
fhc->unit = unit;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_raw::ioctl (unsigned int cmd, void *buf)
|
||||||
|
{
|
||||||
|
int ret = NO_ERROR;
|
||||||
|
|
||||||
|
if (cmd == RDIOCDOP)
|
||||||
|
{
|
||||||
|
struct rdop *op = (struct rdop *) buf;
|
||||||
|
|
||||||
|
if (!op)
|
||||||
|
ret = ERROR_INVALID_PARAMETER;
|
||||||
|
else
|
||||||
|
switch (op->rd_op)
|
||||||
|
{
|
||||||
|
case RDSETBLK:
|
||||||
|
if (get_device () == FH_TAPE)
|
||||||
|
{
|
||||||
|
struct mtop mop;
|
||||||
|
|
||||||
|
mop.mt_op = MTSETBLK;
|
||||||
|
mop.mt_count = op->rd_parm;
|
||||||
|
ret = ioctl (MTIOCTOP, &mop);
|
||||||
|
}
|
||||||
|
else if (op->rd_parm % 512)
|
||||||
|
ret = ERROR_INVALID_PARAMETER;
|
||||||
|
else if (devbuf && op->rd_parm < devbufend - devbufstart)
|
||||||
|
ret = ERROR_INVALID_PARAMETER;
|
||||||
|
else if (!devbuf || op->rd_parm != devbufsiz)
|
||||||
|
{
|
||||||
|
char *buf = new char[op->rd_parm];
|
||||||
|
if (devbuf)
|
||||||
|
{
|
||||||
|
memcpy (buf, devbuf + devbufstart, devbufend - devbufstart);
|
||||||
|
devbufend -= devbufstart;
|
||||||
|
delete[]devbuf;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
devbufend = 0;
|
||||||
|
|
||||||
|
devbufstart = 0;
|
||||||
|
devbuf = buf;
|
||||||
|
devbufsiz = op->rd_parm;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (cmd == RDIOCGET)
|
||||||
|
{
|
||||||
|
struct rdget *get = (struct rdget *) buf;
|
||||||
|
|
||||||
|
if (!get)
|
||||||
|
ret = ERROR_INVALID_PARAMETER;
|
||||||
|
else
|
||||||
|
get->bufsiz = devbufsiz ? devbufsiz : 1L;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return fhandler_base::ioctl (cmd, buf);
|
||||||
|
|
||||||
|
if (ret != NO_ERROR)
|
||||||
|
{
|
||||||
|
SetLastError (ret);
|
||||||
|
__seterrno ();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
883
winsup/cygwin/fhandler_serial.cc
Normal file
883
winsup/cygwin/fhandler_serial.cc
Normal file
@ -0,0 +1,883 @@
|
|||||||
|
/* fhandler_serial.cc
|
||||||
|
|
||||||
|
Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions.
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "winsup.h"
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/* fhandler_serial */
|
||||||
|
|
||||||
|
fhandler_serial::fhandler_serial (const char *name, DWORD devtype, int unit) :
|
||||||
|
fhandler_base (devtype, name, unit)
|
||||||
|
{
|
||||||
|
set_cb (sizeof *this);
|
||||||
|
vmin_ = 0;
|
||||||
|
vtime_ = 0;
|
||||||
|
pgrp_ = myself->pgid;
|
||||||
|
set_need_fork_fixup ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fhandler_serial::overlapped_setup ()
|
||||||
|
{
|
||||||
|
memset (&io_status, 0, sizeof (io_status));
|
||||||
|
io_status.hEvent = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
|
||||||
|
ProtectHandle (io_status.hEvent);
|
||||||
|
overlapped_armed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_serial::raw_read (void *ptr, size_t ulen)
|
||||||
|
{
|
||||||
|
int tot;
|
||||||
|
DWORD n;
|
||||||
|
HANDLE w4[2];
|
||||||
|
DWORD minchars = vmin_ ?: ulen;
|
||||||
|
|
||||||
|
w4[0] = io_status.hEvent;
|
||||||
|
w4[1] = signal_arrived;
|
||||||
|
|
||||||
|
debug_printf ("ulen %d, vmin_ %d, vtime_ %d, hEvent %p", ulen, vmin_, vtime_,
|
||||||
|
io_status.hEvent);
|
||||||
|
if (!overlapped_armed)
|
||||||
|
{
|
||||||
|
(void) SetCommMask (get_handle (), EV_RXCHAR);
|
||||||
|
ResetEvent (io_status.hEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (n = 0, tot = 0; ulen; ulen -= n, ptr = (char *)ptr + n)
|
||||||
|
{
|
||||||
|
DWORD ev;
|
||||||
|
COMSTAT st;
|
||||||
|
DWORD inq = 1;
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
if (!vtime_ && !vmin_)
|
||||||
|
inq = ulen;
|
||||||
|
else if (vtime_)
|
||||||
|
{
|
||||||
|
inq = ulen; // non-interruptible -- have to use kernel timeouts
|
||||||
|
// also note that this is not strictly correct.
|
||||||
|
// if vmin > ulen then things won't work right.
|
||||||
|
overlapped_armed = -1;
|
||||||
|
}
|
||||||
|
if (!overlapped_armed)
|
||||||
|
{
|
||||||
|
if (!ClearCommError (get_handle (), &ev, &st))
|
||||||
|
goto err;
|
||||||
|
else if (ev)
|
||||||
|
termios_printf ("error detected %x", ev);
|
||||||
|
else if (st.cbInQue)
|
||||||
|
inq = st.cbInQue;
|
||||||
|
else if ((size_t)tot >= minchars)
|
||||||
|
break;
|
||||||
|
else if (WaitCommEvent (get_handle (), &ev, &io_status))
|
||||||
|
{
|
||||||
|
debug_printf ("WaitCommEvent succeeded: ev %x", ev);
|
||||||
|
if (!ev)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (GetLastError () != ERROR_IO_PENDING)
|
||||||
|
goto err;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
overlapped_armed = 1;
|
||||||
|
switch (WaitForMultipleObjects (2, w4, FALSE, INFINITE))
|
||||||
|
{
|
||||||
|
case WAIT_OBJECT_0:
|
||||||
|
if (!GetOverlappedResult (get_handle (), &io_status, &n, FALSE))
|
||||||
|
goto err;
|
||||||
|
debug_printf ("n %d, ev %x", n, ev);
|
||||||
|
break;
|
||||||
|
case WAIT_OBJECT_0 + 1:
|
||||||
|
tot = -1;
|
||||||
|
PurgeComm (get_handle (), PURGE_RXABORT);
|
||||||
|
overlapped_armed = 0;
|
||||||
|
set_sig_errno (EINTR);
|
||||||
|
goto out;
|
||||||
|
default:
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
overlapped_armed = 0;
|
||||||
|
ResetEvent (io_status.hEvent);
|
||||||
|
if (inq > ulen)
|
||||||
|
inq = ulen;
|
||||||
|
debug_printf ("inq %d", inq);
|
||||||
|
if (ReadFile (get_handle(), ptr, min (inq, ulen), &n, &io_status))
|
||||||
|
/* Got something */;
|
||||||
|
else if (GetLastError () != ERROR_IO_PENDING)
|
||||||
|
goto err;
|
||||||
|
else if (!GetOverlappedResult (get_handle (), &io_status, &n, TRUE))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
tot += n;
|
||||||
|
debug_printf ("vtime_ %d, vmin_ %d, n %d, tot %d", vtime_, vmin_, n, tot);
|
||||||
|
if (vtime_ || !vmin_ || !n)
|
||||||
|
break;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
err:
|
||||||
|
PurgeComm (get_handle (), PURGE_RXABORT);
|
||||||
|
debug_printf ("err %E");
|
||||||
|
if (GetLastError () == ERROR_OPERATION_ABORTED)
|
||||||
|
n = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tot = -1;
|
||||||
|
__seterrno ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
return tot;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cover function to WriteFile to provide Posix interface and semantics
|
||||||
|
(as much as possible). */
|
||||||
|
int
|
||||||
|
fhandler_serial::raw_write (const void *ptr, size_t len)
|
||||||
|
{
|
||||||
|
DWORD bytes_written;
|
||||||
|
|
||||||
|
if (overlapped_armed)
|
||||||
|
PurgeComm (get_handle (), PURGE_TXABORT | PURGE_RXABORT);
|
||||||
|
ResetEvent (io_status.hEvent);
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
overlapped_armed = TRUE;
|
||||||
|
if (WriteFile (get_handle(), ptr, len, &bytes_written, &io_status))
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch (GetLastError ())
|
||||||
|
{
|
||||||
|
case ERROR_OPERATION_ABORTED:
|
||||||
|
continue;
|
||||||
|
case ERROR_IO_PENDING:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetOverlappedResult (get_handle (), &io_status, &bytes_written, TRUE))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
overlapped_armed = FALSE;
|
||||||
|
return bytes_written;
|
||||||
|
|
||||||
|
err:
|
||||||
|
__seterrno ();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fhandler_serial::dump (void)
|
||||||
|
{
|
||||||
|
paranoid_printf ("here");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fhandler_serial::init (HANDLE f, DWORD flags, mode_t bin)
|
||||||
|
{
|
||||||
|
fhandler_base::init (f, flags, bin);
|
||||||
|
(void) open (NULL, flags, bin ? O_BINARY : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_serial::open (const char *name, int flags, mode_t mode)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
COMMTIMEOUTS to;
|
||||||
|
extern BOOL reset_com;
|
||||||
|
|
||||||
|
syscall_printf ("fhandler_serial::open (%s, %p, %p)",
|
||||||
|
get_name (), flags, mode);
|
||||||
|
|
||||||
|
if (name && !(res = this->fhandler_base::open (flags, mode)))
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
res = 1;
|
||||||
|
|
||||||
|
(void) SetCommMask (get_handle (), EV_RXCHAR);
|
||||||
|
|
||||||
|
set_r_no_interrupt (1); // Handled explicitly in read code
|
||||||
|
|
||||||
|
overlapped_setup ();
|
||||||
|
|
||||||
|
memset (&to, 0, sizeof (to));
|
||||||
|
(void) SetCommTimeouts (get_handle (), &to);
|
||||||
|
|
||||||
|
/* Reset serial port to known state of 9600-8-1-no flow control
|
||||||
|
on open for better behavior under Win 95.
|
||||||
|
|
||||||
|
FIXME: This should only be done when explicitly opening the com
|
||||||
|
port. It should not be reset if an fd is inherited.
|
||||||
|
Using __progname in this way, to determine how far along in the
|
||||||
|
initialization we are, is really a terrible kludge and should
|
||||||
|
be fixed ASAP.
|
||||||
|
*/
|
||||||
|
extern char *__progname;
|
||||||
|
if (reset_com && __progname)
|
||||||
|
{
|
||||||
|
DCB state;
|
||||||
|
GetCommState (get_handle (), &state);
|
||||||
|
syscall_printf ("setting initial state on %s (reset_com %d)",
|
||||||
|
get_name (), reset_com);
|
||||||
|
state.BaudRate = CBR_9600;
|
||||||
|
state.ByteSize = 8;
|
||||||
|
state.StopBits = ONESTOPBIT;
|
||||||
|
state.Parity = NOPARITY; /* FIXME: correct default? */
|
||||||
|
state.fBinary = TRUE; /* binary xfer */
|
||||||
|
state.EofChar = 0; /* no end-of-data in binary mode */
|
||||||
|
state.fNull = FALSE; /* don't discard nulls in binary mode */
|
||||||
|
state.fParity = FALSE; /* ignore parity errors */
|
||||||
|
state.fErrorChar = FALSE;
|
||||||
|
state.fTXContinueOnXoff = TRUE; /* separate TX and RX flow control */
|
||||||
|
state.fOutX = FALSE; /* disable transmission flow control */
|
||||||
|
state.fInX = FALSE; /* disable reception flow control */
|
||||||
|
state.XonChar = 0x11;
|
||||||
|
state.XoffChar = 0x13;
|
||||||
|
state.fOutxDsrFlow = FALSE; /* disable DSR flow control */
|
||||||
|
state.fRtsControl = RTS_CONTROL_ENABLE; /* ignore lead control except
|
||||||
|
DTR */
|
||||||
|
state.fOutxCtsFlow = FALSE; /* disable output flow control */
|
||||||
|
state.fDtrControl = DTR_CONTROL_ENABLE; /* assert DTR */
|
||||||
|
state.fDsrSensitivity = FALSE; /* don't assert DSR */
|
||||||
|
state.fAbortOnError = TRUE;
|
||||||
|
if (!SetCommState (get_handle (), &state))
|
||||||
|
system_printf ("couldn't set initial state for %s, %E", get_name ());
|
||||||
|
}
|
||||||
|
|
||||||
|
SetCommMask (get_handle (), EV_RXCHAR);
|
||||||
|
syscall_printf ("%p = fhandler_serial::open (%s, %p, %p)",
|
||||||
|
res, get_name (), flags, mode);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_serial::close ()
|
||||||
|
{
|
||||||
|
(void) ForceCloseHandle (io_status.hEvent);
|
||||||
|
return fhandler_base::close ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tcsendbreak: POSIX 7.2.2.1 */
|
||||||
|
/* Break for 250-500 milliseconds if duration == 0 */
|
||||||
|
/* Otherwise, units for duration are undefined */
|
||||||
|
int
|
||||||
|
fhandler_serial::tcsendbreak (int duration)
|
||||||
|
{
|
||||||
|
unsigned int sleeptime = 300;
|
||||||
|
|
||||||
|
if (duration > 0)
|
||||||
|
sleeptime *= duration;
|
||||||
|
|
||||||
|
if (SetCommBreak (get_handle ()) == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* FIXME: need to send zero bits during duration */
|
||||||
|
usleep (sleeptime);
|
||||||
|
|
||||||
|
if (ClearCommBreak (get_handle ()) == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
syscall_printf ("0 = fhandler_serial:tcsendbreak (%d)", duration);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tcdrain: POSIX 7.2.2.1 */
|
||||||
|
int
|
||||||
|
fhandler_serial::tcdrain (void)
|
||||||
|
{
|
||||||
|
if (FlushFileBuffers (get_handle ()) == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tcflow: POSIX 7.2.2.1 */
|
||||||
|
int
|
||||||
|
fhandler_serial::tcflow (int action)
|
||||||
|
{
|
||||||
|
DWORD win32action = 0;
|
||||||
|
DCB dcb;
|
||||||
|
char xchar;
|
||||||
|
|
||||||
|
termios_printf ("action %d", action);
|
||||||
|
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
case TCOOFF:
|
||||||
|
win32action = SETXOFF;
|
||||||
|
break;
|
||||||
|
case TCOON:
|
||||||
|
win32action = SETXON;
|
||||||
|
break;
|
||||||
|
case TCION:
|
||||||
|
case TCIOFF:
|
||||||
|
if (GetCommState (get_handle (), &dcb) == 0)
|
||||||
|
return -1;
|
||||||
|
if (action == TCION)
|
||||||
|
xchar = (dcb.XonChar ? dcb.XonChar : 0x11);
|
||||||
|
else
|
||||||
|
xchar = (dcb.XoffChar ? dcb.XoffChar : 0x13);
|
||||||
|
if (TransmitCommChar (get_handle (), xchar) == 0)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EscapeCommFunction (get_handle (), win32action) == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tcflush: POSIX 7.2.2.1 */
|
||||||
|
int
|
||||||
|
fhandler_serial::tcflush (int queue)
|
||||||
|
{
|
||||||
|
if (queue == TCOFLUSH || queue == TCIOFLUSH)
|
||||||
|
PurgeComm (get_handle (), PURGE_TXABORT | PURGE_TXCLEAR);
|
||||||
|
|
||||||
|
if (queue == TCIFLUSH | queue == TCIOFLUSH)
|
||||||
|
/* Input flushing by polling until nothing turns up
|
||||||
|
(we stop after 1000 chars anyway) */
|
||||||
|
for (int max = 1000; max > 0; max--)
|
||||||
|
{
|
||||||
|
DWORD ev;
|
||||||
|
COMSTAT st;
|
||||||
|
if (!PurgeComm (get_handle (), PURGE_RXABORT | PURGE_RXCLEAR))
|
||||||
|
break;
|
||||||
|
Sleep (100);
|
||||||
|
if (!ClearCommError (get_handle (), &ev, &st) || !st.cbInQue)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tcsetattr: POSIX 7.2.1.1 */
|
||||||
|
int
|
||||||
|
fhandler_serial::tcsetattr (int action, const struct termios *t)
|
||||||
|
{
|
||||||
|
/* Possible actions:
|
||||||
|
TCSANOW: immediately change attributes.
|
||||||
|
TCSADRAIN: flush output, then change attributes.
|
||||||
|
TCSAFLUSH: flush output and discard input, then change attributes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
BOOL dropDTR = FALSE;
|
||||||
|
COMMTIMEOUTS to;
|
||||||
|
DCB ostate, state;
|
||||||
|
unsigned int ovtime = vtime_, ovmin = vmin_;
|
||||||
|
|
||||||
|
termios_printf ("action %d", action);
|
||||||
|
if ((action == TCSADRAIN) || (action == TCSAFLUSH))
|
||||||
|
{
|
||||||
|
FlushFileBuffers (get_handle ());
|
||||||
|
termios_printf ("flushed file buffers");
|
||||||
|
}
|
||||||
|
if (action == TCSAFLUSH)
|
||||||
|
PurgeComm (get_handle (), (PURGE_RXABORT | PURGE_RXCLEAR));
|
||||||
|
|
||||||
|
/* get default/last comm state */
|
||||||
|
if (!GetCommState (get_handle (), &ostate))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
state = ostate;
|
||||||
|
|
||||||
|
/* -------------- Set baud rate ------------------ */
|
||||||
|
/* FIXME: WIN32 also has 14400, 56000, 128000, and 256000.
|
||||||
|
Unix also has 230400. */
|
||||||
|
|
||||||
|
switch (t->c_ospeed)
|
||||||
|
{
|
||||||
|
case B0: /* drop DTR */
|
||||||
|
dropDTR = TRUE;
|
||||||
|
state.BaudRate = 0;
|
||||||
|
break;
|
||||||
|
case B110:
|
||||||
|
state.BaudRate = CBR_110;
|
||||||
|
break;
|
||||||
|
case B300:
|
||||||
|
state.BaudRate = CBR_300;
|
||||||
|
break;
|
||||||
|
case B600:
|
||||||
|
state.BaudRate = CBR_600;
|
||||||
|
break;
|
||||||
|
case B1200:
|
||||||
|
state.BaudRate = CBR_1200;
|
||||||
|
break;
|
||||||
|
case B2400:
|
||||||
|
state.BaudRate = CBR_2400;
|
||||||
|
break;
|
||||||
|
case B4800:
|
||||||
|
state.BaudRate = CBR_4800;
|
||||||
|
break;
|
||||||
|
case B9600:
|
||||||
|
state.BaudRate = CBR_9600;
|
||||||
|
break;
|
||||||
|
case B19200:
|
||||||
|
state.BaudRate = CBR_19200;
|
||||||
|
break;
|
||||||
|
case B38400:
|
||||||
|
state.BaudRate = CBR_38400;
|
||||||
|
break;
|
||||||
|
case B57600:
|
||||||
|
state.BaudRate = CBR_57600;
|
||||||
|
break;
|
||||||
|
case B115200:
|
||||||
|
state.BaudRate = CBR_115200;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Unsupported baud rate! */
|
||||||
|
termios_printf ("Invalid t->c_ospeed %d", t->c_ospeed);
|
||||||
|
set_errno (EINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------- Set byte size ------------------ */
|
||||||
|
|
||||||
|
switch (t->c_cflag & CSIZE)
|
||||||
|
{
|
||||||
|
case CS5:
|
||||||
|
state.ByteSize = 5;
|
||||||
|
break;
|
||||||
|
case CS6:
|
||||||
|
state.ByteSize = 6;
|
||||||
|
break;
|
||||||
|
case CS7:
|
||||||
|
state.ByteSize = 7;
|
||||||
|
break;
|
||||||
|
case CS8:
|
||||||
|
state.ByteSize = 8;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Unsupported byte size! */
|
||||||
|
termios_printf ("Invalid t->c_cflag byte size %d",
|
||||||
|
t->c_cflag & CSIZE);
|
||||||
|
set_errno (EINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------- Set stop bits ------------------ */
|
||||||
|
|
||||||
|
if (t->c_cflag & CSTOPB)
|
||||||
|
state.StopBits = TWOSTOPBITS;
|
||||||
|
else
|
||||||
|
state.StopBits = ONESTOPBIT;
|
||||||
|
|
||||||
|
/* -------------- Set parity ------------------ */
|
||||||
|
|
||||||
|
if (t->c_cflag & PARENB)
|
||||||
|
state.Parity = (t->c_cflag & PARODD) ? ODDPARITY : EVENPARITY;
|
||||||
|
else
|
||||||
|
state.Parity = NOPARITY;
|
||||||
|
|
||||||
|
state.fBinary = TRUE; /* Binary transfer */
|
||||||
|
state.EofChar = 0; /* No end-of-data in binary mode */
|
||||||
|
state.fNull = FALSE; /* Don't discard nulls in binary mode */
|
||||||
|
|
||||||
|
/* -------------- Parity errors ------------------ */
|
||||||
|
/* fParity combines the function of INPCK and NOT IGNPAR */
|
||||||
|
|
||||||
|
if ((t->c_iflag & INPCK) && !(t->c_iflag & IGNPAR))
|
||||||
|
state.fParity = TRUE; /* detect parity errors */
|
||||||
|
else
|
||||||
|
state.fParity = FALSE; /* ignore parity errors */
|
||||||
|
|
||||||
|
/* Only present in Win32, Unix has no equivalent */
|
||||||
|
state.fErrorChar = FALSE;
|
||||||
|
state.ErrorChar = 0;
|
||||||
|
|
||||||
|
/* -------------- Set software flow control ------------------ */
|
||||||
|
/* Set fTXContinueOnXoff to FALSE. This prevents the triggering of a
|
||||||
|
premature XON when the remote device interprets a received character
|
||||||
|
as XON (same as IXANY on the remote side). Otherwise, a TRUE
|
||||||
|
value separates the TX and RX functions. */
|
||||||
|
|
||||||
|
state.fTXContinueOnXoff = TRUE; /* separate TX and RX flow control */
|
||||||
|
|
||||||
|
/* Transmission flow control */
|
||||||
|
if (t->c_iflag & IXON)
|
||||||
|
state.fOutX = TRUE; /* enable */
|
||||||
|
else
|
||||||
|
state.fOutX = FALSE; /* disable */
|
||||||
|
|
||||||
|
/* Reception flow control */
|
||||||
|
if (t->c_iflag & IXOFF)
|
||||||
|
state.fInX = TRUE; /* enable */
|
||||||
|
else
|
||||||
|
state.fInX = FALSE; /* disable */
|
||||||
|
|
||||||
|
/* XoffLim and XonLim are left at default values */
|
||||||
|
|
||||||
|
state.XonChar = (t->c_cc[VSTART] ? t->c_cc[VSTART] : 0x11);
|
||||||
|
state.XoffChar = (t->c_cc[VSTOP] ? t->c_cc[VSTOP] : 0x13);
|
||||||
|
|
||||||
|
/* -------------- Set hardware flow control ------------------ */
|
||||||
|
|
||||||
|
/* Disable DSR flow control */
|
||||||
|
state.fOutxDsrFlow = FALSE;
|
||||||
|
|
||||||
|
/* Some old flavors of Unix automatically enabled hardware flow
|
||||||
|
control when software flow control was not enabled. Since newer
|
||||||
|
Unices tend to require explicit setting of hardware flow-control,
|
||||||
|
this is what we do. */
|
||||||
|
|
||||||
|
/* RTS/CTS flow control */
|
||||||
|
if (t->c_cflag & CRTSCTS)
|
||||||
|
{ /* enable */
|
||||||
|
state.fOutxCtsFlow = TRUE;
|
||||||
|
state.fRtsControl = RTS_CONTROL_HANDSHAKE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* disable */
|
||||||
|
state.fRtsControl = RTS_CONTROL_ENABLE;
|
||||||
|
state.fOutxCtsFlow = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t->c_cflag & CRTSXOFF)
|
||||||
|
state.fRtsControl = RTS_CONTROL_HANDSHAKE;
|
||||||
|
|
||||||
|
/* -------------- DTR ------------------ */
|
||||||
|
/* Assert DTR on device open */
|
||||||
|
|
||||||
|
state.fDtrControl = DTR_CONTROL_ENABLE;
|
||||||
|
|
||||||
|
/* -------------- DSR ------------------ */
|
||||||
|
/* Assert DSR at the device? */
|
||||||
|
|
||||||
|
if (t->c_cflag & CLOCAL)
|
||||||
|
state.fDsrSensitivity = FALSE; /* no */
|
||||||
|
else
|
||||||
|
state.fDsrSensitivity = TRUE; /* yes */
|
||||||
|
|
||||||
|
/* -------------- Error handling ------------------ */
|
||||||
|
/* Since read/write operations terminate upon error, we
|
||||||
|
will use ClearCommError() to resume. */
|
||||||
|
|
||||||
|
state.fAbortOnError = TRUE;
|
||||||
|
|
||||||
|
/* -------------- Set state and exit ------------------ */
|
||||||
|
if (memcmp (&ostate, &state, sizeof (state)) != 0)
|
||||||
|
SetCommState (get_handle (), &state);
|
||||||
|
|
||||||
|
set_r_binary ((t->c_iflag & IGNCR) ? 0 : 1);
|
||||||
|
set_w_binary ((t->c_oflag & ONLCR) ? 0 : 1);
|
||||||
|
|
||||||
|
if (dropDTR == TRUE)
|
||||||
|
EscapeCommFunction (get_handle (), CLRDTR);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* FIXME: Sometimes when CLRDTR is set, setting
|
||||||
|
state.fDtrControl = DTR_CONTROL_ENABLE will fail. This
|
||||||
|
is a problem since a program might want to change some
|
||||||
|
parameters while DTR is still down. */
|
||||||
|
|
||||||
|
EscapeCommFunction (get_handle (), SETDTR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
The following documentation on was taken from "Linux Serial Programming
|
||||||
|
HOWTO". It explains how MIN (t->c_cc[VMIN] || vmin_) and TIME
|
||||||
|
(t->c_cc[VTIME] || vtime_) is to be used.
|
||||||
|
|
||||||
|
In non-canonical input processing mode, input is not assembled into
|
||||||
|
lines and input processing (erase, kill, delete, etc.) does not
|
||||||
|
occur. Two parameters control the behavior of this mode: c_cc[VTIME]
|
||||||
|
sets the character timer, and c_cc[VMIN] sets the minimum number of
|
||||||
|
characters to receive before satisfying the read.
|
||||||
|
|
||||||
|
If MIN > 0 and TIME = 0, MIN sets the number of characters to receive
|
||||||
|
before the read is satisfied. As TIME is zero, the timer is not used.
|
||||||
|
|
||||||
|
If MIN = 0 and TIME > 0, TIME serves as a timeout value. The read will
|
||||||
|
be satisfied if a single character is read, or TIME is exceeded (t =
|
||||||
|
TIME *0.1 s). If TIME is exceeded, no character will be returned.
|
||||||
|
|
||||||
|
If MIN > 0 and TIME > 0, TIME serves as an inter-character timer. The
|
||||||
|
read will be satisfied if MIN characters are received, or the time
|
||||||
|
between two characters exceeds TIME. The timer is restarted every time
|
||||||
|
a character is received and only becomes active after the first
|
||||||
|
character has been received.
|
||||||
|
|
||||||
|
If MIN = 0 and TIME = 0, read will be satisfied immediately. The
|
||||||
|
number of characters currently available, or the number of characters
|
||||||
|
requested will be returned. According to Antonino (see contributions),
|
||||||
|
you could issue a fcntl(fd, F_SETFL, FNDELAY); before reading to get
|
||||||
|
the same result.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (t->c_lflag & ICANON)
|
||||||
|
{
|
||||||
|
vmin_ = MAXDWORD;
|
||||||
|
vtime_ = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vtime_ = t->c_cc[VTIME] * 100;
|
||||||
|
vmin_ = t->c_cc[VMIN];
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_printf ("vtime %d, vmin %d\n", vtime_, vmin_);
|
||||||
|
|
||||||
|
if (ovmin == vmin_ && ovtime == vtime_)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
memset (&to, 0, sizeof (to));
|
||||||
|
|
||||||
|
if ((vmin_ > 0) && (vtime_ == 0))
|
||||||
|
{
|
||||||
|
/* Returns immediately with whatever is in buffer on a ReadFile();
|
||||||
|
or blocks if nothing found. We will keep calling ReadFile(); until
|
||||||
|
vmin_ characters are read */
|
||||||
|
to.ReadIntervalTimeout = to.ReadTotalTimeoutMultiplier = MAXDWORD;
|
||||||
|
to.ReadTotalTimeoutConstant = MAXDWORD - 1;
|
||||||
|
}
|
||||||
|
else if ((vmin_ == 0) && (vtime_ > 0))
|
||||||
|
{
|
||||||
|
/* set timeoout constant appropriately and we will only try to
|
||||||
|
read one character in ReadFile() */
|
||||||
|
to.ReadTotalTimeoutConstant = vtime_;
|
||||||
|
to.ReadIntervalTimeout = to.ReadTotalTimeoutMultiplier = MAXDWORD;
|
||||||
|
}
|
||||||
|
else if ((vmin_ > 0) && (vtime_ > 0))
|
||||||
|
{
|
||||||
|
/* time applies to the interval time for this case */
|
||||||
|
to.ReadIntervalTimeout = vtime_;
|
||||||
|
}
|
||||||
|
else if ((vmin_ == 0) && (vtime_ == 0))
|
||||||
|
{
|
||||||
|
/* returns immediately with whatever is in buffer as per
|
||||||
|
Time-Outs docs in Win32 SDK API docs */
|
||||||
|
to.ReadIntervalTimeout = MAXDWORD;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_printf ("ReadTotalTimeoutConstant %d, ReadIntervalTimeout %d, ReadTotalTimeoutMultiplier %d",
|
||||||
|
to.ReadTotalTimeoutConstant, to.ReadIntervalTimeout, to.ReadTotalTimeoutMultiplier);
|
||||||
|
int res = SetCommTimeouts (get_handle (), &to);
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
system_printf ("SetCommTimeout failed, %E");
|
||||||
|
__seterrno ();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tcgetattr: POSIX 7.2.1.1 */
|
||||||
|
int
|
||||||
|
fhandler_serial::tcgetattr (struct termios *t)
|
||||||
|
{
|
||||||
|
DCB state;
|
||||||
|
|
||||||
|
/* Get current Win32 comm state */
|
||||||
|
if (GetCommState (get_handle (), &state) == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* for safety */
|
||||||
|
memset (t, 0, sizeof (*t));
|
||||||
|
|
||||||
|
/* -------------- Baud rate ------------------ */
|
||||||
|
|
||||||
|
switch (state.BaudRate)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
/* FIXME: need to drop DTR */
|
||||||
|
t->c_cflag = t->c_ospeed = t->c_ispeed = B0;
|
||||||
|
break;
|
||||||
|
case CBR_110:
|
||||||
|
t->c_cflag = t->c_ospeed = t->c_ispeed = B110;
|
||||||
|
break;
|
||||||
|
case CBR_300:
|
||||||
|
t->c_cflag = t->c_ospeed = t->c_ispeed = B300;
|
||||||
|
break;
|
||||||
|
case CBR_600:
|
||||||
|
t->c_cflag = t->c_ospeed = t->c_ispeed = B600;
|
||||||
|
break;
|
||||||
|
case CBR_1200:
|
||||||
|
t->c_cflag = t->c_ospeed = t->c_ispeed = B1200;
|
||||||
|
break;
|
||||||
|
case CBR_2400:
|
||||||
|
t->c_cflag = t->c_ospeed = t->c_ispeed = B2400;
|
||||||
|
break;
|
||||||
|
case CBR_4800:
|
||||||
|
t->c_cflag = t->c_ospeed = t->c_ispeed = B4800;
|
||||||
|
break;
|
||||||
|
case CBR_9600:
|
||||||
|
t->c_cflag = t->c_ospeed = t->c_ispeed = B9600;
|
||||||
|
break;
|
||||||
|
case CBR_19200:
|
||||||
|
t->c_cflag = t->c_ospeed = t->c_ispeed = B19200;
|
||||||
|
break;
|
||||||
|
case CBR_38400:
|
||||||
|
t->c_cflag = t->c_ospeed = t->c_ispeed = B38400;
|
||||||
|
break;
|
||||||
|
case CBR_57600:
|
||||||
|
t->c_cflag = t->c_ospeed = t->c_ispeed = B57600;
|
||||||
|
break;
|
||||||
|
case CBR_115200:
|
||||||
|
t->c_cflag = t->c_ospeed = t->c_ispeed = B115200;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Unsupported baud rate! */
|
||||||
|
termios_printf ("Invalid baud rate %d", state.BaudRate);
|
||||||
|
set_errno (EINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------- Byte size ------------------ */
|
||||||
|
|
||||||
|
switch (state.ByteSize)
|
||||||
|
{
|
||||||
|
case 5:
|
||||||
|
t->c_cflag |= CS5;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
t->c_cflag |= CS6;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
t->c_cflag |= CS7;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
t->c_cflag |= CS8;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Unsupported byte size! */
|
||||||
|
termios_printf ("Invalid byte size %d", state.ByteSize);
|
||||||
|
set_errno (EINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------- Stop bits ------------------ */
|
||||||
|
|
||||||
|
if (state.StopBits == TWOSTOPBITS)
|
||||||
|
t->c_cflag |= CSTOPB;
|
||||||
|
|
||||||
|
/* -------------- Parity ------------------ */
|
||||||
|
|
||||||
|
if (state.Parity == ODDPARITY)
|
||||||
|
t->c_cflag |= (PARENB | PARODD);
|
||||||
|
if (state.Parity == EVENPARITY)
|
||||||
|
t->c_cflag |= PARENB;
|
||||||
|
|
||||||
|
/* -------------- Parity errors ------------------ */
|
||||||
|
|
||||||
|
/* fParity combines the function of INPCK and NOT IGNPAR */
|
||||||
|
if (state.fParity == TRUE)
|
||||||
|
t->c_iflag |= INPCK;
|
||||||
|
else
|
||||||
|
t->c_iflag |= IGNPAR; /* not necessarily! */
|
||||||
|
|
||||||
|
/* -------------- Software flow control ------------------ */
|
||||||
|
|
||||||
|
/* transmission flow control */
|
||||||
|
if (state.fOutX)
|
||||||
|
t->c_iflag |= IXON;
|
||||||
|
|
||||||
|
/* reception flow control */
|
||||||
|
if (state.fInX)
|
||||||
|
t->c_iflag |= IXOFF;
|
||||||
|
|
||||||
|
t->c_cc[VSTART] = (state.XonChar ? state.XonChar : 0x11);
|
||||||
|
t->c_cc[VSTOP] = (state.XoffChar ? state.XoffChar : 0x13);
|
||||||
|
|
||||||
|
/* -------------- Hardware flow control ------------------ */
|
||||||
|
/* Some old flavors of Unix automatically enabled hardware flow
|
||||||
|
control when software flow control was not enabled. Since newer
|
||||||
|
Unices tend to require explicit setting of hardware flow-control,
|
||||||
|
this is what we do. */
|
||||||
|
|
||||||
|
/* Input flow-control */
|
||||||
|
if ((state.fRtsControl == RTS_CONTROL_HANDSHAKE) &&
|
||||||
|
(state.fOutxCtsFlow == TRUE))
|
||||||
|
t->c_cflag |= CRTSCTS;
|
||||||
|
if (state.fRtsControl == RTS_CONTROL_HANDSHAKE)
|
||||||
|
t->c_cflag |= CRTSXOFF;
|
||||||
|
|
||||||
|
/* -------------- CLOCAL --------------- */
|
||||||
|
/* DSR is only lead toggled only by CLOCAL. Check it to see if
|
||||||
|
CLOCAL was called. */
|
||||||
|
/* FIXME: If tcsetattr() hasn't been called previously, this may
|
||||||
|
give a false CLOCAL. */
|
||||||
|
|
||||||
|
if (state.fDsrSensitivity == FALSE)
|
||||||
|
t->c_cflag |= CLOCAL;
|
||||||
|
|
||||||
|
/* FIXME: need to handle IGNCR */
|
||||||
|
#if 0
|
||||||
|
if (!get_r_binary ())
|
||||||
|
t->c_iflag |= IGNCR;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!get_w_binary ())
|
||||||
|
t->c_oflag |= ONLCR;
|
||||||
|
|
||||||
|
debug_printf ("vmin_ %d, vtime_ %d", vmin_, vtime_);
|
||||||
|
if (vmin_ == MAXDWORD)
|
||||||
|
{
|
||||||
|
t->c_lflag |= ICANON;
|
||||||
|
t->c_cc[VTIME] = t->c_cc[VMIN] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
t->c_cc[VTIME] = vtime_ / 100;
|
||||||
|
t->c_cc[VMIN] = vmin_;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fhandler_serial::fixup_after_fork (HANDLE parent)
|
||||||
|
{
|
||||||
|
if (get_close_on_exec ())
|
||||||
|
this->fhandler_base::fixup_after_fork (parent);
|
||||||
|
overlapped_setup ();
|
||||||
|
debug_printf ("io_status.hEvent %p", io_status.hEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_serial::de_linearize (const char *buf, const char *unix_name,
|
||||||
|
const char *win32_name)
|
||||||
|
{
|
||||||
|
int res = fhandler_base::de_linearize (buf, unix_name, win32_name);
|
||||||
|
overlapped_setup ();
|
||||||
|
debug_printf ("io_status.hEvent %p", io_status.hEvent);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_serial::dup (fhandler_base *child)
|
||||||
|
{
|
||||||
|
fhandler_serial *fhc = (fhandler_serial *) child;
|
||||||
|
overlapped_setup ();
|
||||||
|
fhc->vmin_ = vmin_;
|
||||||
|
fhc->vtime_ = vtime_;
|
||||||
|
return fhandler_base::dup (child);
|
||||||
|
}
|
829
winsup/cygwin/fhandler_tape.cc
Normal file
829
winsup/cygwin/fhandler_tape.cc
Normal file
@ -0,0 +1,829 @@
|
|||||||
|
/* fhandler_tape.cc. See fhandler.h for a description of the fhandler
|
||||||
|
classes.
|
||||||
|
|
||||||
|
Copyright 1999, 2000 Cygnus Solutions.
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include <sys/termios.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "winsup.h"
|
||||||
|
|
||||||
|
#include <sys/mtio.h>
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/* fhandler_dev_tape */
|
||||||
|
|
||||||
|
void
|
||||||
|
fhandler_dev_tape::clear (void)
|
||||||
|
{
|
||||||
|
norewind = 0;
|
||||||
|
lasterr = 0;
|
||||||
|
fhandler_dev_raw::clear ();
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_tape::is_eom (int win_error)
|
||||||
|
{
|
||||||
|
int ret = ((win_error == ERROR_END_OF_MEDIA)
|
||||||
|
|| (win_error == ERROR_EOM_OVERFLOW)
|
||||||
|
|| (win_error == ERROR_NO_DATA_DETECTED));
|
||||||
|
if (ret)
|
||||||
|
debug_printf ("end of medium");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_tape::is_eof (int win_error)
|
||||||
|
{
|
||||||
|
int ret = ((win_error == ERROR_FILEMARK_DETECTED)
|
||||||
|
|| (win_error == ERROR_SETMARK_DETECTED));
|
||||||
|
if (ret)
|
||||||
|
debug_printf ("end of file");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
fhandler_dev_tape::fhandler_dev_tape (const char *name, int unit) : fhandler_dev_raw (FH_TAPE, name, unit)
|
||||||
|
{
|
||||||
|
set_cb (sizeof *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_tape::open (const char *path, int flags, mode_t)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int minor;
|
||||||
|
|
||||||
|
if (get_device_number (path, minor) != FH_TAPE)
|
||||||
|
{
|
||||||
|
set_errno (EINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
norewind = (minor >= 128);
|
||||||
|
devbufsiz = 1L;
|
||||||
|
|
||||||
|
ret = fhandler_dev_raw::open (path, flags);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
struct mtget get;
|
||||||
|
struct mtop op;
|
||||||
|
struct mtpos pos;
|
||||||
|
|
||||||
|
if (! ioctl (MTIOCGET, &get))
|
||||||
|
{
|
||||||
|
devbufsiz = get.mt_dsreg;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (devbufsiz > 1L)
|
||||||
|
{
|
||||||
|
devbuf = new char [ devbufsiz ];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following rewind in position 0 solves a problem which appears
|
||||||
|
* in case of multi volume archives: The last ReadFile on first medium
|
||||||
|
* returns ERROR_NO_DATA_DETECTED. After media change, all subsequent
|
||||||
|
* ReadFile calls return ERROR_NO_DATA_DETECTED, too!
|
||||||
|
* The call to tape_set_pos seems to reset some internal flags!
|
||||||
|
*/
|
||||||
|
if ((! ioctl (MTIOCPOS, &pos)) && (! pos.mt_blkno))
|
||||||
|
{
|
||||||
|
op.mt_op = MTREW;
|
||||||
|
ioctl (MTIOCTOP, &op);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & O_APPEND)
|
||||||
|
{
|
||||||
|
/* In append mode, seek to beginning of next filemark */
|
||||||
|
op.mt_op = MTFSFM;
|
||||||
|
op.mt_count = 1;
|
||||||
|
ioctl (MTIOCTOP, &op);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_tape::close (void)
|
||||||
|
{
|
||||||
|
struct mtop op;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (is_writing)
|
||||||
|
{
|
||||||
|
ret = writebuf ();
|
||||||
|
if ((has_written) && (! eom_detected))
|
||||||
|
{
|
||||||
|
/* if last operation was writing, write a filemark */
|
||||||
|
debug_printf ("writing filemark\n");
|
||||||
|
op.mt_op = MTWEOF;
|
||||||
|
op.mt_count = 1;
|
||||||
|
ioctl (MTIOCTOP, &op);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// To protected reads on signaling (e.g. Ctrl-C)
|
||||||
|
eof_detected = 1;
|
||||||
|
|
||||||
|
if (! norewind)
|
||||||
|
{
|
||||||
|
debug_printf ("rewinding\n");
|
||||||
|
op.mt_op = MTREW;
|
||||||
|
ioctl (MTIOCTOP, &op);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
fhandler_dev_raw::close ();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fhandler_dev_raw::close ();
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_tape::fstat (struct stat *buf)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (! (ret = fhandler_dev_raw::fstat (buf)))
|
||||||
|
{
|
||||||
|
struct mtget get;
|
||||||
|
|
||||||
|
if (! ioctl (MTIOCGET, &get))
|
||||||
|
{
|
||||||
|
buf->st_blocks = get.mt_capacity / buf->st_blksize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t
|
||||||
|
fhandler_dev_tape::lseek (off_t offset, int whence)
|
||||||
|
{
|
||||||
|
struct mtop op;
|
||||||
|
struct mtpos pos;
|
||||||
|
|
||||||
|
debug_printf ("lseek (%s, %d, %d)\n", get_name (), offset, whence);
|
||||||
|
|
||||||
|
writebuf ();
|
||||||
|
eom_detected = eof_detected = 0;
|
||||||
|
lastblk_to_read = 0;
|
||||||
|
devbufstart = devbufend = 0;
|
||||||
|
|
||||||
|
if (ioctl (MTIOCPOS, &pos))
|
||||||
|
{
|
||||||
|
return (off_t) -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (whence)
|
||||||
|
{
|
||||||
|
case SEEK_END:
|
||||||
|
op.mt_op = MTFSF;
|
||||||
|
op.mt_count = 1;
|
||||||
|
if (ioctl (MTIOCTOP, &op))
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
case SEEK_SET:
|
||||||
|
if (whence == SEEK_SET && offset < 0)
|
||||||
|
{
|
||||||
|
set_errno (EINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SEEK_CUR:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
set_errno (EINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
op.mt_op = MTFSR;
|
||||||
|
op.mt_count = offset / devbufsiz
|
||||||
|
- (whence == SEEK_SET ? pos.mt_blkno : 0);
|
||||||
|
|
||||||
|
if (op.mt_count < 0)
|
||||||
|
{
|
||||||
|
op.mt_op = MTBSR;
|
||||||
|
op.mt_count = -op.mt_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ioctl (MTIOCTOP, &op) || ioctl (MTIOCPOS, &pos))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return (pos.mt_blkno * devbufsiz);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_tape::dup (fhandler_base *child)
|
||||||
|
{
|
||||||
|
fhandler_dev_tape *fhc = (fhandler_dev_tape *) child;
|
||||||
|
|
||||||
|
fhc->norewind = norewind;
|
||||||
|
fhc->lasterr = lasterr;
|
||||||
|
return fhandler_dev_raw::dup (child);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_tape::ioctl (unsigned int cmd, void *buf)
|
||||||
|
{
|
||||||
|
int ret = NO_ERROR;
|
||||||
|
unsigned long block;
|
||||||
|
|
||||||
|
if (cmd == MTIOCTOP)
|
||||||
|
{
|
||||||
|
struct mtop *op = (struct mtop *) buf;
|
||||||
|
|
||||||
|
if (! op)
|
||||||
|
ret = ERROR_INVALID_PARAMETER;
|
||||||
|
else
|
||||||
|
switch (op->mt_op)
|
||||||
|
{
|
||||||
|
case MTRESET:
|
||||||
|
break;
|
||||||
|
case MTFSF:
|
||||||
|
ret = tape_set_pos (TAPE_SPACE_FILEMARKS, op->mt_count);
|
||||||
|
break;
|
||||||
|
case MTBSF:
|
||||||
|
ret = tape_set_pos (TAPE_SPACE_FILEMARKS, -op->mt_count);
|
||||||
|
break;
|
||||||
|
case MTFSR:
|
||||||
|
ret = tape_set_pos (TAPE_SPACE_RELATIVE_BLOCKS, op->mt_count);
|
||||||
|
break;
|
||||||
|
case MTBSR:
|
||||||
|
ret = tape_set_pos (TAPE_SPACE_RELATIVE_BLOCKS, -op->mt_count);
|
||||||
|
break;
|
||||||
|
case MTWEOF:
|
||||||
|
ret = tape_write_marks (TAPE_FILEMARKS, op->mt_count);
|
||||||
|
break;
|
||||||
|
case MTREW:
|
||||||
|
ret = tape_set_pos (TAPE_REWIND, 0);
|
||||||
|
break;
|
||||||
|
case MTOFFL:
|
||||||
|
ret = tape_prepare (TAPE_UNLOAD);
|
||||||
|
break;
|
||||||
|
case MTNOP:
|
||||||
|
break;
|
||||||
|
case MTRETEN:
|
||||||
|
if (! tape_get_feature (TAPE_DRIVE_END_OF_DATA))
|
||||||
|
{
|
||||||
|
ret = ERROR_INVALID_PARAMETER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (! (ret = tape_set_pos (TAPE_REWIND, 0, FALSE)))
|
||||||
|
{
|
||||||
|
ret = tape_prepare (TAPE_TENSION);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MTBSFM:
|
||||||
|
ret = tape_set_pos (TAPE_SPACE_FILEMARKS, -op->mt_count, TRUE);
|
||||||
|
break;
|
||||||
|
case MTFSFM:
|
||||||
|
ret = tape_set_pos (TAPE_SPACE_FILEMARKS, op->mt_count, TRUE);
|
||||||
|
break;
|
||||||
|
case MTEOM:
|
||||||
|
if (tape_get_feature (TAPE_DRIVE_END_OF_DATA))
|
||||||
|
{
|
||||||
|
ret = tape_set_pos (TAPE_SPACE_END_OF_DATA, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = tape_set_pos (TAPE_SPACE_FILEMARKS, 32767);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MTERASE:
|
||||||
|
ret = tape_erase (TAPE_ERASE_SHORT);
|
||||||
|
break;
|
||||||
|
case MTRAS1:
|
||||||
|
case MTRAS2:
|
||||||
|
case MTRAS3:
|
||||||
|
ret = ERROR_INVALID_PARAMETER;
|
||||||
|
break;
|
||||||
|
case MTSETBLK:
|
||||||
|
{
|
||||||
|
long min, max;
|
||||||
|
|
||||||
|
if (! tape_get_feature (TAPE_DRIVE_SET_BLOCK_SIZE))
|
||||||
|
{
|
||||||
|
ret = ERROR_INVALID_PARAMETER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ret = tape_get_blocksize (&min, NULL, &max, NULL);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (op->mt_count < min || op->mt_count > max)
|
||||||
|
{
|
||||||
|
ret = ERROR_INVALID_PARAMETER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (devbuf && (size_t) op->mt_count == devbufsiz)
|
||||||
|
{
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (devbuf && (size_t) op->mt_count < devbufend - devbufstart)
|
||||||
|
{
|
||||||
|
ret = ERROR_INVALID_PARAMETER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (! (ret = tape_set_blocksize (op->mt_count)))
|
||||||
|
{
|
||||||
|
char *buf = new char [ op->mt_count ];
|
||||||
|
if (devbuf)
|
||||||
|
{
|
||||||
|
memcpy(buf,devbuf + devbufstart, devbufend - devbufstart);
|
||||||
|
devbufend -= devbufstart;
|
||||||
|
delete [] devbuf;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
devbufend = 0;
|
||||||
|
}
|
||||||
|
devbufstart = 0;
|
||||||
|
devbuf = buf;
|
||||||
|
devbufsiz = op->mt_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MTSETDENSITY:
|
||||||
|
ret = ERROR_INVALID_PARAMETER;
|
||||||
|
break;
|
||||||
|
case MTSEEK:
|
||||||
|
if (tape_get_feature (TAPE_DRIVE_ABSOLUTE_BLK))
|
||||||
|
{
|
||||||
|
ret = tape_set_pos (TAPE_ABSOLUTE_BLOCK, op->mt_count);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (! (ret = tape_get_pos (&block)))
|
||||||
|
{
|
||||||
|
ret = tape_set_pos (TAPE_SPACE_RELATIVE_BLOCKS,
|
||||||
|
op->mt_count - block);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MTTELL:
|
||||||
|
if (! (ret = tape_get_pos (&block)))
|
||||||
|
op->mt_count = block;
|
||||||
|
break;
|
||||||
|
case MTSETDRVBUFFER:
|
||||||
|
ret = ERROR_INVALID_PARAMETER;
|
||||||
|
break;
|
||||||
|
case MTFSS:
|
||||||
|
ret = tape_set_pos (TAPE_SPACE_SETMARKS, op->mt_count);
|
||||||
|
break;
|
||||||
|
case MTBSS:
|
||||||
|
ret = tape_set_pos (TAPE_SPACE_SETMARKS, -op->mt_count);
|
||||||
|
break;
|
||||||
|
case MTWSM:
|
||||||
|
ret = tape_write_marks (TAPE_SETMARKS, op->mt_count);
|
||||||
|
break;
|
||||||
|
case MTLOCK:
|
||||||
|
ret = tape_prepare (TAPE_LOCK);
|
||||||
|
break;
|
||||||
|
case MTUNLOCK:
|
||||||
|
ret = tape_prepare (TAPE_UNLOCK);
|
||||||
|
break;
|
||||||
|
case MTLOAD:
|
||||||
|
ret = tape_prepare (TAPE_LOAD);
|
||||||
|
break;
|
||||||
|
case MTUNLOAD:
|
||||||
|
ret = tape_prepare (TAPE_UNLOAD);
|
||||||
|
break;
|
||||||
|
case MTCOMPRESSION:
|
||||||
|
ret = tape_compression (op->mt_count);
|
||||||
|
break;
|
||||||
|
case MTSETPART:
|
||||||
|
case MTMKPART:
|
||||||
|
default:
|
||||||
|
ret = ERROR_INVALID_PARAMETER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (cmd == MTIOCGET)
|
||||||
|
ret = tape_status ((struct mtget *) buf);
|
||||||
|
else if (cmd == MTIOCPOS)
|
||||||
|
{
|
||||||
|
ret = ERROR_INVALID_PARAMETER;
|
||||||
|
if (buf && (ret = tape_get_pos (&block)))
|
||||||
|
((struct mtpos *) buf)->mt_blkno = block;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return fhandler_dev_raw::ioctl (cmd, buf);
|
||||||
|
|
||||||
|
if (ret != NO_ERROR)
|
||||||
|
{
|
||||||
|
SetLastError (ret);
|
||||||
|
__seterrno ();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Private functions used by `ioctl' */
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
static int
|
||||||
|
tape_error (DWORD lasterr, const char *txt)
|
||||||
|
{
|
||||||
|
if (lasterr)
|
||||||
|
debug_printf ("%s: error: %d\n", txt, lasterr);
|
||||||
|
|
||||||
|
return lasterr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_tape::tape_write_marks (int marktype, DWORD len)
|
||||||
|
{
|
||||||
|
syscall_printf ("write_tapemark\n");
|
||||||
|
while (((lasterr = WriteTapemark (get_handle (),
|
||||||
|
marktype,
|
||||||
|
len,
|
||||||
|
FALSE)) == ERROR_MEDIA_CHANGED)
|
||||||
|
|| (lasterr == ERROR_BUS_RESET))
|
||||||
|
;
|
||||||
|
|
||||||
|
return tape_error (lasterr, "tape_write_marks");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_tape::tape_get_pos (unsigned long *ret)
|
||||||
|
{
|
||||||
|
DWORD part, low, high;
|
||||||
|
|
||||||
|
while (((lasterr = GetTapePosition (get_handle (),
|
||||||
|
TAPE_ABSOLUTE_POSITION,
|
||||||
|
&part,
|
||||||
|
&low,
|
||||||
|
&high)) == ERROR_MEDIA_CHANGED)
|
||||||
|
|| (lasterr == ERROR_BUS_RESET))
|
||||||
|
;
|
||||||
|
if (! tape_error (lasterr, "tape_get_pos") && ret)
|
||||||
|
*ret = low;
|
||||||
|
|
||||||
|
return lasterr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _tape_set_pos (HANDLE hTape, int mode, long count)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
while (((err = SetTapePosition (hTape,
|
||||||
|
mode,
|
||||||
|
1,
|
||||||
|
count,
|
||||||
|
count < 0 ? -1 : 0,
|
||||||
|
FALSE)) == ERROR_MEDIA_CHANGED)
|
||||||
|
|| (err == ERROR_BUS_RESET))
|
||||||
|
;
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_tape::tape_set_pos (int mode, long count, BOOLEAN sfm_func)
|
||||||
|
{
|
||||||
|
unsigned long pos, tgtpos;
|
||||||
|
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case TAPE_SPACE_RELATIVE_BLOCKS:
|
||||||
|
lasterr = tape_get_pos (&pos);
|
||||||
|
|
||||||
|
if (lasterr)
|
||||||
|
return lasterr;
|
||||||
|
|
||||||
|
tgtpos = pos + count;
|
||||||
|
|
||||||
|
while (((lasterr = _tape_set_pos (get_handle (),
|
||||||
|
mode,
|
||||||
|
count)) == ERROR_FILEMARK_DETECTED)
|
||||||
|
|| (lasterr == ERROR_SETMARK_DETECTED))
|
||||||
|
{
|
||||||
|
lasterr = tape_get_pos (&pos);
|
||||||
|
if (lasterr)
|
||||||
|
return lasterr;
|
||||||
|
count = tgtpos - pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lasterr == ERROR_BEGINNING_OF_MEDIA && ! tgtpos)
|
||||||
|
lasterr = NO_ERROR;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case TAPE_SPACE_FILEMARKS:
|
||||||
|
if (count < 0)
|
||||||
|
{
|
||||||
|
if (pos > 0)
|
||||||
|
{
|
||||||
|
if ((! _tape_set_pos (get_handle (),
|
||||||
|
TAPE_SPACE_RELATIVE_BLOCKS,
|
||||||
|
-1))
|
||||||
|
|| (sfm_func))
|
||||||
|
++count;
|
||||||
|
_tape_set_pos (get_handle (), TAPE_SPACE_RELATIVE_BLOCKS, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (! (lasterr = _tape_set_pos (get_handle (), mode, -1))
|
||||||
|
&& count++ < 0)
|
||||||
|
;
|
||||||
|
|
||||||
|
if (lasterr == ERROR_BEGINNING_OF_MEDIA)
|
||||||
|
{
|
||||||
|
if (! count)
|
||||||
|
lasterr = NO_ERROR;
|
||||||
|
}
|
||||||
|
else if (! sfm_func)
|
||||||
|
lasterr = _tape_set_pos (get_handle (), mode, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (sfm_func)
|
||||||
|
{
|
||||||
|
if (_tape_set_pos (get_handle (),
|
||||||
|
TAPE_SPACE_RELATIVE_BLOCKS,
|
||||||
|
1) == ERROR_FILEMARK_DETECTED)
|
||||||
|
++count;
|
||||||
|
_tape_set_pos (get_handle (), TAPE_SPACE_RELATIVE_BLOCKS, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! (lasterr = _tape_set_pos (get_handle (), mode, count))
|
||||||
|
&& sfm_func)
|
||||||
|
lasterr = _tape_set_pos (get_handle (), mode, -1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TAPE_SPACE_SETMARKS:
|
||||||
|
case TAPE_ABSOLUTE_BLOCK:
|
||||||
|
case TAPE_SPACE_END_OF_DATA:
|
||||||
|
case TAPE_REWIND:
|
||||||
|
lasterr = _tape_set_pos (get_handle (), mode, count);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tape_error (lasterr, "tape_set_pos");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_tape::tape_erase (int mode)
|
||||||
|
{
|
||||||
|
DWORD varlen;
|
||||||
|
TAPE_GET_DRIVE_PARAMETERS dp;
|
||||||
|
|
||||||
|
while (((lasterr = GetTapeParameters (get_handle (),
|
||||||
|
GET_TAPE_DRIVE_INFORMATION,
|
||||||
|
(varlen = sizeof dp, &varlen),
|
||||||
|
&dp)) == ERROR_MEDIA_CHANGED)
|
||||||
|
|| (lasterr == ERROR_BUS_RESET))
|
||||||
|
;
|
||||||
|
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case TAPE_ERASE_SHORT:
|
||||||
|
if (! lasterr && ! (dp.FeaturesLow & TAPE_DRIVE_ERASE_SHORT))
|
||||||
|
mode = TAPE_ERASE_LONG;
|
||||||
|
break;
|
||||||
|
case TAPE_ERASE_LONG:
|
||||||
|
if (! lasterr && ! (dp.FeaturesLow & TAPE_DRIVE_ERASE_LONG))
|
||||||
|
mode = TAPE_ERASE_SHORT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tape_error (EraseTape (get_handle (), mode, FALSE), "tape_erase");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_tape::tape_prepare (int action)
|
||||||
|
{
|
||||||
|
while (((lasterr = PrepareTape (get_handle (),
|
||||||
|
action,
|
||||||
|
FALSE)) == ERROR_MEDIA_CHANGED)
|
||||||
|
|| (lasterr == ERROR_BUS_RESET))
|
||||||
|
;
|
||||||
|
return tape_error (lasterr, "tape_prepare");
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
fhandler_dev_tape::tape_get_feature (DWORD parm)
|
||||||
|
{
|
||||||
|
DWORD varlen;
|
||||||
|
TAPE_GET_DRIVE_PARAMETERS dp;
|
||||||
|
|
||||||
|
while (((lasterr = GetTapeParameters (get_handle (),
|
||||||
|
GET_TAPE_DRIVE_INFORMATION,
|
||||||
|
(varlen = sizeof dp, &varlen),
|
||||||
|
&dp)) == ERROR_MEDIA_CHANGED)
|
||||||
|
|| (lasterr == ERROR_BUS_RESET))
|
||||||
|
;
|
||||||
|
|
||||||
|
if (lasterr)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return ((parm & TAPE_DRIVE_HIGH_FEATURES)
|
||||||
|
? ((dp.FeaturesHigh & parm) != 0)
|
||||||
|
: ((dp.FeaturesLow & parm) != 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_tape::tape_get_blocksize (long *min, long *def, long *max, long *cur)
|
||||||
|
{
|
||||||
|
DWORD varlen;
|
||||||
|
TAPE_GET_DRIVE_PARAMETERS dp;
|
||||||
|
TAPE_GET_MEDIA_PARAMETERS mp;
|
||||||
|
|
||||||
|
while (((lasterr = GetTapeParameters (get_handle (),
|
||||||
|
GET_TAPE_DRIVE_INFORMATION,
|
||||||
|
(varlen = sizeof dp, &varlen),
|
||||||
|
&dp)) == ERROR_MEDIA_CHANGED)
|
||||||
|
|| (lasterr == ERROR_BUS_RESET))
|
||||||
|
;
|
||||||
|
|
||||||
|
if (lasterr)
|
||||||
|
return tape_error (lasterr, "tape_get_blocksize");
|
||||||
|
|
||||||
|
while (((lasterr = GetTapeParameters (get_handle (),
|
||||||
|
GET_TAPE_MEDIA_INFORMATION,
|
||||||
|
(varlen = sizeof mp, &varlen),
|
||||||
|
&mp)) == ERROR_MEDIA_CHANGED)
|
||||||
|
|| (lasterr == ERROR_BUS_RESET))
|
||||||
|
;
|
||||||
|
|
||||||
|
if (lasterr)
|
||||||
|
return tape_error (lasterr, "tape_get_blocksize");
|
||||||
|
|
||||||
|
if (min)
|
||||||
|
*min = (long) dp.MinimumBlockSize;
|
||||||
|
if (def)
|
||||||
|
*def = (long) dp.DefaultBlockSize;
|
||||||
|
if (max)
|
||||||
|
*max = (long) dp.MaximumBlockSize;
|
||||||
|
if (cur)
|
||||||
|
*cur = (long) mp.BlockSize;
|
||||||
|
|
||||||
|
return tape_error (lasterr, "tape_get_blocksize");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_tape::tape_set_blocksize (long count)
|
||||||
|
{
|
||||||
|
long min, max;
|
||||||
|
TAPE_SET_MEDIA_PARAMETERS mp;
|
||||||
|
|
||||||
|
lasterr = tape_get_blocksize (&min, NULL, &max, NULL);
|
||||||
|
|
||||||
|
if (lasterr)
|
||||||
|
return lasterr;
|
||||||
|
|
||||||
|
if (count < min || count > max)
|
||||||
|
return tape_error (ERROR_INVALID_PARAMETER, "tape_set_blocksize");
|
||||||
|
|
||||||
|
mp.BlockSize = count;
|
||||||
|
|
||||||
|
return tape_error (SetTapeParameters (get_handle (),
|
||||||
|
SET_TAPE_MEDIA_INFORMATION,
|
||||||
|
&mp),
|
||||||
|
"tape_set_blocksize");
|
||||||
|
}
|
||||||
|
|
||||||
|
static long long
|
||||||
|
get_ll (PLARGE_INTEGER i)
|
||||||
|
{
|
||||||
|
long long l = 0;
|
||||||
|
|
||||||
|
l = i->HighPart;
|
||||||
|
l <<= 32;
|
||||||
|
l |= i->LowPart;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_tape::tape_status (struct mtget *get)
|
||||||
|
{
|
||||||
|
DWORD varlen;
|
||||||
|
TAPE_GET_DRIVE_PARAMETERS dp;
|
||||||
|
TAPE_GET_MEDIA_PARAMETERS mp;
|
||||||
|
int notape = 0;
|
||||||
|
|
||||||
|
if (! get)
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
while (((lasterr = GetTapeParameters (get_handle (),
|
||||||
|
GET_TAPE_DRIVE_INFORMATION,
|
||||||
|
(varlen = sizeof dp, &varlen),
|
||||||
|
&dp)) == ERROR_MEDIA_CHANGED)
|
||||||
|
|| (lasterr == ERROR_BUS_RESET))
|
||||||
|
;
|
||||||
|
|
||||||
|
if ((lasterr) || (lasterr = GetTapeParameters (get_handle (),
|
||||||
|
GET_TAPE_MEDIA_INFORMATION,
|
||||||
|
(varlen = sizeof mp, &varlen),
|
||||||
|
&mp)))
|
||||||
|
notape = 1;
|
||||||
|
|
||||||
|
memset (get, 0, sizeof *get);
|
||||||
|
|
||||||
|
get->mt_type = MT_ISUNKNOWN;
|
||||||
|
|
||||||
|
if (! notape && (dp.FeaturesLow & TAPE_DRIVE_TAPE_REMAINING))
|
||||||
|
{
|
||||||
|
get->mt_remaining = get_ll (&mp.Remaining);
|
||||||
|
get->mt_resid = get->mt_remaining >> 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((dp.FeaturesHigh & TAPE_DRIVE_SET_BLOCK_SIZE) && ! notape)
|
||||||
|
get->mt_dsreg = mp.BlockSize;
|
||||||
|
else
|
||||||
|
get->mt_dsreg = dp.DefaultBlockSize;
|
||||||
|
|
||||||
|
if (notape)
|
||||||
|
get->mt_gstat |= GMT_DR_OPEN (-1);
|
||||||
|
|
||||||
|
if (! notape)
|
||||||
|
{
|
||||||
|
if (dp.FeaturesLow & TAPE_DRIVE_GET_ABSOLUTE_BLK)
|
||||||
|
tape_get_pos ((unsigned long *) &get->mt_blkno);
|
||||||
|
|
||||||
|
if (! get->mt_blkno)
|
||||||
|
get->mt_gstat |= GMT_BOT (-1);
|
||||||
|
|
||||||
|
get->mt_gstat |= GMT_ONLINE (-1);
|
||||||
|
|
||||||
|
if ((dp.FeaturesLow & TAPE_DRIVE_WRITE_PROTECT) && mp.WriteProtected)
|
||||||
|
get->mt_gstat |= GMT_WR_PROT (-1);
|
||||||
|
|
||||||
|
if (dp.FeaturesLow & TAPE_DRIVE_TAPE_CAPACITY)
|
||||||
|
get->mt_capacity = get_ll (&mp.Capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((dp.FeaturesLow & TAPE_DRIVE_COMPRESSION) && dp.Compression)
|
||||||
|
get->mt_gstat |= GMT_HW_COMP (-1);
|
||||||
|
|
||||||
|
if ((dp.FeaturesLow & TAPE_DRIVE_ECC) && dp.ECC)
|
||||||
|
get->mt_gstat |= GMT_HW_ECC (-1);
|
||||||
|
|
||||||
|
if ((dp.FeaturesLow & TAPE_DRIVE_PADDING) && dp.DataPadding)
|
||||||
|
get->mt_gstat |= GMT_PADDING (-1);
|
||||||
|
|
||||||
|
if ((dp.FeaturesLow & TAPE_DRIVE_REPORT_SMKS) && dp.ReportSetmarks)
|
||||||
|
get->mt_gstat |= GMT_IM_REP_EN (-1);
|
||||||
|
|
||||||
|
get->mt_erreg = lasterr;
|
||||||
|
|
||||||
|
get->mt_minblksize = dp.MinimumBlockSize;
|
||||||
|
get->mt_maxblksize = dp.MaximumBlockSize;
|
||||||
|
get->mt_defblksize = dp.DefaultBlockSize;
|
||||||
|
get->mt_featureslow = dp.FeaturesLow;
|
||||||
|
get->mt_featureshigh = dp.FeaturesHigh;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_tape::tape_compression (long count)
|
||||||
|
{
|
||||||
|
DWORD varlen;
|
||||||
|
TAPE_GET_DRIVE_PARAMETERS dpg;
|
||||||
|
TAPE_SET_DRIVE_PARAMETERS dps;
|
||||||
|
|
||||||
|
while (((lasterr = GetTapeParameters (get_handle (),
|
||||||
|
GET_TAPE_DRIVE_INFORMATION,
|
||||||
|
(varlen = sizeof dpg, &varlen),
|
||||||
|
&dpg)) == ERROR_MEDIA_CHANGED)
|
||||||
|
|| (lasterr == ERROR_BUS_RESET))
|
||||||
|
;
|
||||||
|
|
||||||
|
if (lasterr)
|
||||||
|
return tape_error (lasterr, "tape_compression");
|
||||||
|
|
||||||
|
if (! (dpg.FeaturesLow & TAPE_DRIVE_COMPRESSION))
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (count)
|
||||||
|
{
|
||||||
|
dps.ECC = dpg.ECC;
|
||||||
|
dps.Compression = count ? TRUE : FALSE;
|
||||||
|
dps.DataPadding = dpg.DataPadding;
|
||||||
|
dps.ReportSetmarks = dpg.ReportSetmarks;
|
||||||
|
dps.EOTWarningZoneSize = dpg.EOTWarningZoneSize;
|
||||||
|
lasterr = SetTapeParameters (get_handle (),
|
||||||
|
SET_TAPE_DRIVE_INFORMATION,
|
||||||
|
&dps);
|
||||||
|
|
||||||
|
if (lasterr)
|
||||||
|
return tape_error (lasterr, "tape_compression");
|
||||||
|
|
||||||
|
dpg.Compression = dps.Compression;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
293
winsup/cygwin/fhandler_termios.cc
Normal file
293
winsup/cygwin/fhandler_termios.cc
Normal file
@ -0,0 +1,293 @@
|
|||||||
|
/* fhandler_termios.cc
|
||||||
|
|
||||||
|
Copyright 1996, 1997, 1998 Cygnus Solutions.
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include "winsup.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
/* Common functions shared by tty/console */
|
||||||
|
|
||||||
|
void
|
||||||
|
fhandler_termios::tcinit (tty_min *this_tc, int force)
|
||||||
|
{
|
||||||
|
/* Initial termios values */
|
||||||
|
|
||||||
|
tc = this_tc;
|
||||||
|
|
||||||
|
if (force || !TTYISSETF (INITIALIZED))
|
||||||
|
{
|
||||||
|
tc->ti.c_iflag = BRKINT | ICRNL | IXON;
|
||||||
|
tc->ti.c_oflag = OPOST | ONLCR;
|
||||||
|
tc->ti.c_cflag = B38400 | CS8 | CREAD;
|
||||||
|
tc->ti.c_lflag = ISIG | ICANON | ECHO | IEXTEN;
|
||||||
|
|
||||||
|
tc->ti.c_cc[VDISCARD] = CFLUSH;
|
||||||
|
tc->ti.c_cc[VEOL] = CEOL;
|
||||||
|
tc->ti.c_cc[VEOL2] = CEOL2;
|
||||||
|
tc->ti.c_cc[VEOF] = CEOF;
|
||||||
|
tc->ti.c_cc[VERASE] = CERASE;
|
||||||
|
tc->ti.c_cc[VINTR] = CINTR;
|
||||||
|
tc->ti.c_cc[VKILL] = CKILL;
|
||||||
|
tc->ti.c_cc[VLNEXT] = CLNEXT;
|
||||||
|
tc->ti.c_cc[VMIN] = 1;
|
||||||
|
tc->ti.c_cc[VQUIT] = CQUIT;
|
||||||
|
tc->ti.c_cc[VREPRINT] = CRPRNT;
|
||||||
|
tc->ti.c_cc[VSTART] = CSTART;
|
||||||
|
tc->ti.c_cc[VSTOP] = CSTOP;
|
||||||
|
tc->ti.c_cc[VSUSP] = CSUSP;
|
||||||
|
tc->ti.c_cc[VSWTC] = CSWTCH;
|
||||||
|
tc->ti.c_cc[VTIME] = 0;
|
||||||
|
tc->ti.c_cc[VWERASE] = CWERASE;
|
||||||
|
|
||||||
|
tc->ti.c_ispeed = tc->ti.c_ospeed = B38400;
|
||||||
|
tc->pgid = myself->pgid;
|
||||||
|
TTYSETF (INITIALIZED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_termios::tcsetpgrp (const pid_t pgid)
|
||||||
|
{
|
||||||
|
termios_printf ("pgid %d, sid %d, tsid %d", pgid,
|
||||||
|
myself->sid, tc->getsid ());
|
||||||
|
if (myself->sid != tc->getsid ())
|
||||||
|
{
|
||||||
|
set_errno (EPERM);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tc->setpgid (pgid);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_termios::tcgetpgrp ()
|
||||||
|
{
|
||||||
|
return tc->pgid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fhandler_termios::set_ctty (int ttynum, int flags)
|
||||||
|
{
|
||||||
|
if ((myself->ctty < 0 || myself->ctty == ttynum) && !(flags & O_NOCTTY))
|
||||||
|
{
|
||||||
|
myself->ctty = ttynum;
|
||||||
|
syscall_printf ("attached tty%d sid %d, pid %d, tty->pgid %d, tty->sid %d",
|
||||||
|
ttynum, myself->sid, myself->pid, tc->pgid, tc->getsid ());
|
||||||
|
|
||||||
|
pinfo *p = procinfo (tc->getsid ());
|
||||||
|
if (myself->sid == myself->pid &&
|
||||||
|
(p == myself || !proc_exists (p)))
|
||||||
|
{
|
||||||
|
paranoid_printf ("resetting tty%d sid. Was %d, now %d. pgid was %d, now %d.",
|
||||||
|
ttynum, tc->getsid(), myself->sid, tc->getpgid (), myself->pgid);
|
||||||
|
/* We are the session leader */
|
||||||
|
tc->setsid (myself->sid);
|
||||||
|
tc->setpgid (myself->pgid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
myself->sid = tc->getsid ();
|
||||||
|
if (tc->getpgid () == 0)
|
||||||
|
tc->setpgid (myself->pgid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_termios::bg_check (int sig, int blocksigs)
|
||||||
|
{
|
||||||
|
if (!myself->pgid || tc->getpgid () == myself->pgid ||
|
||||||
|
myself->ctty != tc->ntty ||
|
||||||
|
((sig == SIGTTOU) && !(tc->ti.c_lflag & TOSTOP)))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (sig < 0)
|
||||||
|
sig = -sig;
|
||||||
|
|
||||||
|
termios_printf("bg I/O pgid %d, tpgid %d, ctty %d",
|
||||||
|
myself->pgid, tc->getpgid (), myself->ctty);
|
||||||
|
|
||||||
|
if (tc->getsid () == 0)
|
||||||
|
{
|
||||||
|
/* The pty has been closed by the master. Return an EOF
|
||||||
|
indication. FIXME: There is nothing to stop somebody
|
||||||
|
from reallocating this pty. I think this is the case
|
||||||
|
which is handled by unlockpt on a Unix system. */
|
||||||
|
termios_printf ("closed by master");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the process group is no more or if process is ignoring or blocks 'sig',
|
||||||
|
return with error */
|
||||||
|
int pgid_gone = !proc_exists (procinfo (myself->pgid));
|
||||||
|
int sigs_ignored =
|
||||||
|
((void *) myself->getsig(sig).sa_handler == (void *) SIG_IGN) ||
|
||||||
|
(myself->getsigmask () & SIGTOMASK (sig));
|
||||||
|
|
||||||
|
if (pgid_gone)
|
||||||
|
goto setEIO;
|
||||||
|
else if (!sigs_ignored)
|
||||||
|
/* nothing */;
|
||||||
|
else if (sig == SIGTTOU)
|
||||||
|
return 1; /* Just allow the output */
|
||||||
|
else
|
||||||
|
goto setEIO; /* This is an output error */
|
||||||
|
|
||||||
|
_raise (sig);
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
setEIO:
|
||||||
|
set_errno (EIO);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define set_input_done(x) input_done = input_done || (x)
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_termios::line_edit (const char *rptr, int nread, int always_accept)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
int input_done = 0;
|
||||||
|
int iscanon = tc->ti.c_lflag & ICANON;
|
||||||
|
|
||||||
|
while (nread-- > 0)
|
||||||
|
{
|
||||||
|
c = *rptr++;
|
||||||
|
|
||||||
|
termios_printf ("char %c", c);
|
||||||
|
|
||||||
|
/* Check for special chars */
|
||||||
|
|
||||||
|
if (c == '\r')
|
||||||
|
{
|
||||||
|
if (tc->ti.c_iflag & IGNCR)
|
||||||
|
continue;
|
||||||
|
if (tc->ti.c_iflag & ICRNL)
|
||||||
|
{
|
||||||
|
c = '\n';
|
||||||
|
set_input_done (iscanon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (c == '\n')
|
||||||
|
{
|
||||||
|
if (tc->ti.c_iflag & INLCR)
|
||||||
|
c = '\r';
|
||||||
|
else
|
||||||
|
set_input_done (iscanon);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tc->ti.c_iflag & ISTRIP)
|
||||||
|
c &= 0x7f;
|
||||||
|
if (tc->ti.c_lflag & ISIG)
|
||||||
|
{
|
||||||
|
int sig;
|
||||||
|
if (c == tc->ti.c_cc[VINTR])
|
||||||
|
sig = SIGINT;
|
||||||
|
else if (c == tc->ti.c_cc[VQUIT])
|
||||||
|
sig = SIGQUIT;
|
||||||
|
else if (c == tc->ti.c_cc[VSUSP])
|
||||||
|
sig = SIGTSTP;
|
||||||
|
else
|
||||||
|
goto not_a_sig;
|
||||||
|
|
||||||
|
termios_printf ("got interrupt %d, sending signal %d", c, sig);
|
||||||
|
kill_pgrp (tc->getpgid (), sig);
|
||||||
|
tc->ti.c_lflag &= ~FLUSHO;
|
||||||
|
goto restart_output;
|
||||||
|
}
|
||||||
|
not_a_sig:
|
||||||
|
if (tc->ti.c_iflag & IXON)
|
||||||
|
{
|
||||||
|
if (c == tc->ti.c_cc[VSTOP])
|
||||||
|
{
|
||||||
|
tc->OutputStopped++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (c == tc->ti.c_cc[VSTART])
|
||||||
|
{
|
||||||
|
restart_output:
|
||||||
|
tc->OutputStopped = 0;
|
||||||
|
SetEvent (restart_output_event);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if ((tc->ti.c_iflag & IXANY) && tc->OutputStopped)
|
||||||
|
goto restart_output;
|
||||||
|
}
|
||||||
|
if (tc->ti.c_lflag & IEXTEN && c == tc->ti.c_cc[VDISCARD])
|
||||||
|
{
|
||||||
|
tc->ti.c_lflag ^= FLUSHO;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!iscanon)
|
||||||
|
/* nothing */;
|
||||||
|
else if (c == tc->ti.c_cc[VERASE])
|
||||||
|
{
|
||||||
|
if (eat_readahead (1))
|
||||||
|
doecho ("\b \b", 3);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (c == tc->ti.c_cc[VWERASE])
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
do
|
||||||
|
if (!eat_readahead (1))
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
doecho ("\b \b", 3);
|
||||||
|
while ((ch = peek_readahead (1)) >= 0 && !isspace (ch));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (c == tc->ti.c_cc[VKILL])
|
||||||
|
{
|
||||||
|
int nchars = eat_readahead (-1);
|
||||||
|
while (nchars--)
|
||||||
|
doecho ("\b \b", 3);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (c == tc->ti.c_cc[VREPRINT])
|
||||||
|
{
|
||||||
|
doecho ("\n\r", 2);
|
||||||
|
doecho (rabuf, ralen);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (c == tc->ti.c_cc[VEOF])
|
||||||
|
{
|
||||||
|
termios_printf ("EOF");
|
||||||
|
input_done = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (c == tc->ti.c_cc[VEOL] ||
|
||||||
|
c == tc->ti.c_cc[VEOL2] ||
|
||||||
|
c == '\n')
|
||||||
|
{
|
||||||
|
set_input_done (1);
|
||||||
|
termios_printf ("EOL");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tc->ti.c_iflag & IUCLC && isupper (c))
|
||||||
|
c = tolower (c);
|
||||||
|
|
||||||
|
if (tc->ti.c_lflag & ECHO)
|
||||||
|
doecho (&c, 1);
|
||||||
|
put_readahead (c);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!iscanon || always_accept)
|
||||||
|
set_input_done (ralen > 0);
|
||||||
|
|
||||||
|
/* FIXME: It's not clear that this code will ever do anything.
|
||||||
|
Currently, it doesn't look like accept_input will ever return
|
||||||
|
a negative number. */
|
||||||
|
if (input_done)
|
||||||
|
(void) accept_input ();
|
||||||
|
|
||||||
|
return input_done;
|
||||||
|
}
|
1070
winsup/cygwin/fhandler_tty.cc
Normal file
1070
winsup/cygwin/fhandler_tty.cc
Normal file
File diff suppressed because it is too large
Load Diff
145
winsup/cygwin/fhandler_windows.cc
Normal file
145
winsup/cygwin/fhandler_windows.cc
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
/* fhandler_windows.cc: code to access windows message queues.
|
||||||
|
|
||||||
|
Copyright 1998 Cygnus Solutions.
|
||||||
|
|
||||||
|
Written by Sergey S. Okhapkin (sos@prospect.com.ru).
|
||||||
|
Feedback and testing by Andy Piper (andyp@parallax.co.uk).
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include "winsup.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
The following unix-style calls are supported:
|
||||||
|
|
||||||
|
open ("/dev/windows", flags, mode=0)
|
||||||
|
- create a unix fd for message queue.
|
||||||
|
O_NONBLOCK flag controls the read() call behavior.
|
||||||
|
|
||||||
|
read (fd, buf, len)
|
||||||
|
- return next message from queue. buf must point to MSG
|
||||||
|
structure, len must be >= sizeof (MSG). If read is set to
|
||||||
|
non-blocking and the queue is empty, read call returns -1
|
||||||
|
immediately with errno set to EAGAIN, otherwise it blocks
|
||||||
|
untill the message will be received.
|
||||||
|
|
||||||
|
write (fd, buf, len)
|
||||||
|
- send a message pointed by buf. len argument ignored.
|
||||||
|
|
||||||
|
ioctl (fd, command, *param)
|
||||||
|
- control read()/write() behavior.
|
||||||
|
ioctl (fd, WINDOWS_POST, NULL): write() will PostMessage();
|
||||||
|
ioctl (fd, WINDOWS_SEND, NULL): write() will SendMessage();
|
||||||
|
ioctl (fd, WINDOWS_HWND, &hWnd): read() messages for
|
||||||
|
hWnd window.
|
||||||
|
|
||||||
|
select () call marks read fd when any message posted to queue.
|
||||||
|
*/
|
||||||
|
|
||||||
|
fhandler_windows::fhandler_windows (const char *name) :
|
||||||
|
fhandler_base (FH_WINDOWS, name)
|
||||||
|
{
|
||||||
|
set_cb (sizeof *this);
|
||||||
|
hWnd_ = NULL;
|
||||||
|
method_ = WINDOWS_POST;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_windows::open (const char *, int flags, mode_t)
|
||||||
|
{
|
||||||
|
set_flags (flags);
|
||||||
|
set_close_on_exec_flag (1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_windows::write (const void *buf, size_t)
|
||||||
|
{
|
||||||
|
MSG *ptr = (MSG *) buf;
|
||||||
|
|
||||||
|
if (method_ == WINDOWS_POST)
|
||||||
|
{
|
||||||
|
if (!PostMessage (ptr->hwnd, ptr->message, ptr->wParam, ptr->lParam))
|
||||||
|
{
|
||||||
|
__seterrno ();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return sizeof (MSG);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return SendMessage (ptr->hwnd, ptr->message, ptr->wParam, ptr->lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_windows::read (void *buf, size_t len)
|
||||||
|
{
|
||||||
|
MSG *ptr = (MSG *) buf;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (len < sizeof (MSG))
|
||||||
|
{
|
||||||
|
set_errno (EINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = GetMessage (ptr, hWnd_, 0, 0);
|
||||||
|
|
||||||
|
if (ret == -1)
|
||||||
|
{
|
||||||
|
__seterrno ();
|
||||||
|
}
|
||||||
|
set_errno (0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_windows::ioctl (unsigned int cmd, void *val)
|
||||||
|
{
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case WINDOWS_POST:
|
||||||
|
case WINDOWS_SEND:
|
||||||
|
method_ = cmd;
|
||||||
|
break;
|
||||||
|
case WINDOWS_HWND:
|
||||||
|
if (val == NULL)
|
||||||
|
{
|
||||||
|
set_errno (EINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
hWnd_ = * ((HWND *) val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
set_errno (EINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fhandler_windows::set_close_on_exec (int val)
|
||||||
|
{
|
||||||
|
if (get_handle ())
|
||||||
|
this->fhandler_base::set_close_on_exec (val);
|
||||||
|
else
|
||||||
|
this->fhandler_base::set_close_on_exec_flag (val);
|
||||||
|
void *h = hWnd_;
|
||||||
|
if (h)
|
||||||
|
set_inheritance (h, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fhandler_windows::fixup_after_fork (HANDLE parent)
|
||||||
|
{
|
||||||
|
if (get_handle ())
|
||||||
|
this->fhandler_base::fixup_after_fork (parent);
|
||||||
|
void *h = hWnd_;
|
||||||
|
if (h)
|
||||||
|
fork_fixup (parent, h, "hWnd_");
|
||||||
|
}
|
58
winsup/cygwin/fhandler_zero.cc
Normal file
58
winsup/cygwin/fhandler_zero.cc
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/* fhandler_dev_zero.cc: code to access /dev/zero
|
||||||
|
|
||||||
|
Copyright 2000 Cygnus Solutions.
|
||||||
|
|
||||||
|
Written by DJ Delorie (dj@cygnus.com)
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include "winsup.h"
|
||||||
|
|
||||||
|
fhandler_dev_zero::fhandler_dev_zero (const char *name)
|
||||||
|
: fhandler_base (FH_ZERO, name)
|
||||||
|
{
|
||||||
|
set_cb (sizeof *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_zero::open (const char *path, int flags, mode_t mode = 0)
|
||||||
|
{
|
||||||
|
set_flags (flags);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_zero::write (const void *ptr, size_t len)
|
||||||
|
{
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_zero::read (void *ptr, size_t len)
|
||||||
|
{
|
||||||
|
memset(ptr, 0, len);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t
|
||||||
|
fhandler_dev_zero::lseek (off_t offset, int whence)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_dev_zero::close (void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fhandler_dev_zero::dump ()
|
||||||
|
{
|
||||||
|
paranoid_printf("here, fhandler_dev_zero");
|
||||||
|
}
|
625
winsup/cygwin/fork.cc
Normal file
625
winsup/cygwin/fork.cc
Normal file
@ -0,0 +1,625 @@
|
|||||||
|
/* fork.cc
|
||||||
|
|
||||||
|
Copyright 1996, 1997, 1998, 1999 Cygnus Solutions.
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include "winsup.h"
|
||||||
|
#include "dll_init.h"
|
||||||
|
|
||||||
|
DWORD chunksize = 0;
|
||||||
|
/* Timeout to wait for child to start, parent to init child, etc. */
|
||||||
|
/* FIXME: Once things stabilize, bump up to a few minutes. */
|
||||||
|
#define FORK_WAIT_TIMEOUT (300 * 1000) /* 300 seconds */
|
||||||
|
|
||||||
|
#define dll_data_start &_data_start__
|
||||||
|
#define dll_data_end &_data_end__
|
||||||
|
#define dll_bss_start &_bss_start__
|
||||||
|
#define dll_bss_end &_bss_end__
|
||||||
|
|
||||||
|
void
|
||||||
|
per_thread::set (void *s)
|
||||||
|
{
|
||||||
|
if (s == PER_THREAD_FORK_CLEAR)
|
||||||
|
{
|
||||||
|
tls = TlsAlloc ();
|
||||||
|
s = NULL;
|
||||||
|
}
|
||||||
|
TlsSetValue (get_tls (), s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
stack_base (child_info_fork &ch)
|
||||||
|
{
|
||||||
|
MEMORY_BASIC_INFORMATION m;
|
||||||
|
memset (&m, 0, sizeof m);
|
||||||
|
if (!VirtualQuery ((LPCVOID) &m, &m, sizeof m))
|
||||||
|
system_printf ("couldn't get memory info, %E");
|
||||||
|
|
||||||
|
ch.stacktop = m.AllocationBase;
|
||||||
|
ch.stackbottom = (LPBYTE) m.BaseAddress + m.RegionSize;
|
||||||
|
ch.stacksize = (DWORD) ch.stackbottom - (DWORD) &m;
|
||||||
|
debug_printf ("bottom %p, top %p, stack %p, size %d, reserve %d",
|
||||||
|
ch.stackbottom, ch.stacktop, &m, ch.stacksize,
|
||||||
|
(DWORD) ch.stackbottom - (DWORD) ch.stacktop);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy memory from parent to child.
|
||||||
|
The result is a boolean indicating success. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
fork_copy (PROCESS_INFORMATION &pi, const char *what, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
char *low;
|
||||||
|
int pass = 0;
|
||||||
|
|
||||||
|
va_start (args, what);
|
||||||
|
|
||||||
|
while ((low = va_arg (args, char *)))
|
||||||
|
{
|
||||||
|
char *high = va_arg (args, char *);
|
||||||
|
DWORD todo = chunksize ?: high - low;
|
||||||
|
char *here;
|
||||||
|
|
||||||
|
for (here = low; here < high; here += todo)
|
||||||
|
{
|
||||||
|
DWORD done = 0;
|
||||||
|
if (here + todo > high)
|
||||||
|
todo = high - here;
|
||||||
|
int res = WriteProcessMemory (pi.hProcess, here, here, todo, &done);
|
||||||
|
debug_printf ("child handle %p, low %p, high %p, res %d", pi.hProcess,
|
||||||
|
low, high, res);
|
||||||
|
if (!res || todo != done)
|
||||||
|
{
|
||||||
|
if (!res)
|
||||||
|
__seterrno ();
|
||||||
|
/* If this happens then there is a bug in our fork
|
||||||
|
implementation somewhere. */
|
||||||
|
system_printf ("%s pass %d failed, %p..%p, done %d, %E",
|
||||||
|
what, pass, low, high, done);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pass++;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_printf ("done");
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
err:
|
||||||
|
TerminateProcess (pi.hProcess, 1);
|
||||||
|
set_errno (EAGAIN);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for child to finish what it's doing and signal us.
|
||||||
|
We don't want to wait forever here.If there's a problem somewhere
|
||||||
|
it'll hang the entire system (since all forks are mutex'd). If we
|
||||||
|
time out, set errno = EAGAIN and hope the app tries again. */
|
||||||
|
static int
|
||||||
|
sync_with_child (PROCESS_INFORMATION &pi, HANDLE subproc_ready,
|
||||||
|
BOOL hang_child, const char *s)
|
||||||
|
{
|
||||||
|
/* We also add the child process handle to the wait. If the child fails
|
||||||
|
to initialize (eg. because of a missing dll). Then this
|
||||||
|
handle will become signalled. This stops a *looong* timeout wait.
|
||||||
|
*/
|
||||||
|
HANDLE w4[2];
|
||||||
|
|
||||||
|
debug_printf ("waiting for child. reason: %s", s);
|
||||||
|
w4[1] = pi.hProcess;
|
||||||
|
w4[0] = subproc_ready;
|
||||||
|
DWORD rc = WaitForMultipleObjects (2, w4, FALSE, FORK_WAIT_TIMEOUT);
|
||||||
|
|
||||||
|
if (rc == WAIT_OBJECT_0 ||
|
||||||
|
WaitForSingleObject (subproc_ready, 0) == WAIT_OBJECT_0)
|
||||||
|
/* That's ok */;
|
||||||
|
else if (rc == WAIT_FAILED || rc == WAIT_TIMEOUT)
|
||||||
|
{
|
||||||
|
if (rc != WAIT_FAILED)
|
||||||
|
system_printf ("WaitForMultipleObjects timed out");
|
||||||
|
else
|
||||||
|
system_printf ("WaitForMultipleObjects failed, %E");
|
||||||
|
set_errno (EAGAIN);
|
||||||
|
syscall_printf ("-1 = fork(), WaitForMultipleObjects failed");
|
||||||
|
TerminateProcess (pi.hProcess, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Child died. Clean up and exit. */
|
||||||
|
DWORD errcode;
|
||||||
|
GetExitCodeProcess (pi.hProcess, &errcode);
|
||||||
|
/* Fix me. This is not enough. The fork should not be considered
|
||||||
|
* to have failed if the process was essentially killed by a signal.
|
||||||
|
*/
|
||||||
|
if (errcode != STATUS_CONTROL_C_EXIT)
|
||||||
|
{
|
||||||
|
system_printf ("child %d(%p) died before initialization with status code %p",
|
||||||
|
pi.dwProcessId, pi.hProcess, errcode);
|
||||||
|
system_printf ("*** child state %s", s);
|
||||||
|
#ifdef DEBUGGING
|
||||||
|
abort ();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
set_errno (EAGAIN);
|
||||||
|
syscall_printf ("Child died before subproc_ready signalled");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_printf ("child signalled me");
|
||||||
|
if (hang_child)
|
||||||
|
{
|
||||||
|
int n = SuspendThread (pi.hThread);
|
||||||
|
debug_printf ("suspend count %d", n); \
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
resume_child (PROCESS_INFORMATION &pi, HANDLE subproc_ready,
|
||||||
|
HANDLE forker_finished)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
debug_printf ("here");
|
||||||
|
SetEvent (forker_finished);
|
||||||
|
|
||||||
|
rc = ResumeThread (pi.hThread);
|
||||||
|
|
||||||
|
debug_printf ("rc %d", rc);
|
||||||
|
if (rc == 1)
|
||||||
|
return 1; // Successful resumption
|
||||||
|
|
||||||
|
/* Can't resume the thread. Not sure why this would happen unless
|
||||||
|
there's a bug in the system. Things seem to be working OK now
|
||||||
|
though, so flag this with EAGAIN, but print a message on the
|
||||||
|
console. */
|
||||||
|
small_printf ("fork: ResumeThread failed, rc = %d, %E\n", rc);
|
||||||
|
set_errno (EAGAIN);
|
||||||
|
syscall_printf ("-1 = fork(), ResumeThread failed");
|
||||||
|
TerminateProcess (pi.hProcess, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Notify parent that it is time for the next step.
|
||||||
|
Note that this has to be a macro since the parent may be messing with
|
||||||
|
our stack. */
|
||||||
|
#define sync_with_parent(s, hang_self) \
|
||||||
|
((void) ({ \
|
||||||
|
debug_printf ("signalling parent: %s", s); \
|
||||||
|
/* Tell our parent we're waiting. */ \
|
||||||
|
if (!SetEvent (child_proc_info->subproc_ready)) \
|
||||||
|
api_fatal ("fork child - SetEvent failed, %E"); \
|
||||||
|
if (hang_self) \
|
||||||
|
{ \
|
||||||
|
/* Wait for the parent to fill in our stack and heap. \
|
||||||
|
Don't wait forever here. If our parent dies we don't want to clog \
|
||||||
|
the system. If the wait fails, we really can't continue so exit. */ \
|
||||||
|
DWORD psync_rc = WaitForSingleObject (child_proc_info->forker_finished, FORK_WAIT_TIMEOUT); \
|
||||||
|
switch (psync_rc) \
|
||||||
|
{ \
|
||||||
|
case WAIT_TIMEOUT: \
|
||||||
|
api_fatal ("sync_with_parent - WFSO timed out"); \
|
||||||
|
break; \
|
||||||
|
case WAIT_FAILED: \
|
||||||
|
if (GetLastError () == ERROR_INVALID_HANDLE && \
|
||||||
|
WaitForSingleObject (child_proc_info->forker_finished, 1) != WAIT_FAILED) \
|
||||||
|
break; \
|
||||||
|
api_fatal ("sync_with_parent - WFSO failed, fork_finished %p, %E", child_proc_info->forker_finished); \
|
||||||
|
break; \
|
||||||
|
default: \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
debug_printf ("awake"); \
|
||||||
|
} \
|
||||||
|
0; \
|
||||||
|
}))
|
||||||
|
|
||||||
|
static volatile void grow_stack_slack();
|
||||||
|
|
||||||
|
static void *
|
||||||
|
stack_dummy (int here)
|
||||||
|
{
|
||||||
|
return &here;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" int
|
||||||
|
fork ()
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
DWORD rc;
|
||||||
|
HANDLE hParent;
|
||||||
|
pinfo *child;
|
||||||
|
HANDLE subproc_ready, forker_finished;
|
||||||
|
void *stack_here;
|
||||||
|
int x;
|
||||||
|
PROCESS_INFORMATION pi = {0};
|
||||||
|
|
||||||
|
MALLOC_CHECK;
|
||||||
|
|
||||||
|
/* FIXME: something is broken when copying the stack from the parent
|
||||||
|
to the child; we try various tricks here to make sure that the
|
||||||
|
stack is good enough to prevent page faults, but the true cause
|
||||||
|
is still unknown. DJ */
|
||||||
|
volatile char dummy[4096];
|
||||||
|
dummy[0] = dummy[4095] = 0; // Just to leave some slack in the stack
|
||||||
|
|
||||||
|
grow_stack_slack ();
|
||||||
|
|
||||||
|
debug_printf ("entering");
|
||||||
|
/* Calculate how much of stack to copy to child */
|
||||||
|
stack_here = stack_dummy (0);
|
||||||
|
|
||||||
|
if (ISSTATE(myself, PID_SPLIT_HEAP))
|
||||||
|
{
|
||||||
|
system_printf ("The heap has been split, CYGWIN can't fork this process.");
|
||||||
|
system_printf ("Increase the heap_chunk_size in the registry and try again.");
|
||||||
|
set_errno (ENOMEM);
|
||||||
|
syscall_printf ("-1 = fork (), split heap");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't start the fork until we have the lock. */
|
||||||
|
child = cygwin_shared->p.allocate_pid ();
|
||||||
|
if (!child)
|
||||||
|
{
|
||||||
|
set_errno (EAGAIN);
|
||||||
|
syscall_printf ("-1 = fork (), process table full");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static child_info_fork ch;
|
||||||
|
x = setjmp (ch.jmp);
|
||||||
|
|
||||||
|
if (x == 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* This will help some of the confusion. */
|
||||||
|
fflush (stdout);
|
||||||
|
|
||||||
|
debug_printf ("parent pid %d, child pid %d", myself->pid, child->pid);
|
||||||
|
|
||||||
|
subproc_ready = CreateEvent (&sec_all, FALSE, FALSE, NULL);
|
||||||
|
forker_finished = CreateEvent (&sec_all, FALSE, FALSE, NULL);
|
||||||
|
ProtectHandle (subproc_ready);
|
||||||
|
ProtectHandle (forker_finished);
|
||||||
|
|
||||||
|
/* If we didn't obtain all the resources we need to fork, allow the program
|
||||||
|
to continue, but record the fact that fork won't work. */
|
||||||
|
if (forker_finished == NULL || subproc_ready == NULL)
|
||||||
|
{
|
||||||
|
system_printf ("unable to allocate fork() resources.");
|
||||||
|
system_printf ("fork() disabled.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
subproc_init ();
|
||||||
|
|
||||||
|
debug_printf ("about to call setjmp");
|
||||||
|
/* Parent. */
|
||||||
|
#ifdef DEBUGGING
|
||||||
|
/* The ProtectHandle call allocates memory so we need to make sure
|
||||||
|
that enough is set aside here so that the sbrk pointer does not
|
||||||
|
move when ProtectHandle is called after the child is started.
|
||||||
|
Otherwise the sbrk pointers in the parent will not agree with
|
||||||
|
the child and when user_data is (regrettably) copied over,
|
||||||
|
the user_data->ptr field will not be accurate. */
|
||||||
|
free (malloc (4096));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
init_child_info (PROC_FORK1, &ch, child->pid, subproc_ready);
|
||||||
|
|
||||||
|
ch.forker_finished = forker_finished;
|
||||||
|
ch.heaptop = user_data->heaptop;
|
||||||
|
ch.heapbase = user_data->heapbase;
|
||||||
|
ch.heapptr = user_data->heapptr;
|
||||||
|
|
||||||
|
stack_base (ch);
|
||||||
|
|
||||||
|
/* Initialize things that are done later in dll_crt0_1 that aren't done
|
||||||
|
for the forkee. */
|
||||||
|
strcpy(child->progname, myself->progname);
|
||||||
|
|
||||||
|
STARTUPINFO si = {0};
|
||||||
|
|
||||||
|
si.cb = sizeof (STARTUPINFO);
|
||||||
|
si.lpReserved2 = (LPBYTE)&ch;
|
||||||
|
si.cbReserved2 = sizeof(ch);
|
||||||
|
|
||||||
|
int c_flags = GetPriorityClass (hMainProc) /*|
|
||||||
|
CREATE_NEW_PROCESS_GROUP*/;
|
||||||
|
|
||||||
|
/* If we don't have a console, then don't create a console for the
|
||||||
|
child either. */
|
||||||
|
HANDLE console_handle = CreateFileA ("CONOUT$", GENERIC_WRITE,
|
||||||
|
FILE_SHARE_WRITE, &sec_none_nih,
|
||||||
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
syscall_printf ("CreateProcessA (%s, %s,0,0,1,%x, 0,0,%p,%p)",
|
||||||
|
myself->progname, myself->progname, c_flags, &si, &pi);
|
||||||
|
if (console_handle != INVALID_HANDLE_VALUE && console_handle != 0)
|
||||||
|
CloseHandle (console_handle);
|
||||||
|
else
|
||||||
|
c_flags |= DETACHED_PROCESS;
|
||||||
|
|
||||||
|
hParent = NULL;
|
||||||
|
if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &hParent, 0, 1,
|
||||||
|
DUPLICATE_SAME_ACCESS))
|
||||||
|
{
|
||||||
|
system_printf ("couldn't create handle to myself for child, %E");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = CreateProcessA (myself->progname, /* image to run */
|
||||||
|
myself->progname, /* what we send in arg0 */
|
||||||
|
&sec_none_nih, /* process security attrs */
|
||||||
|
&sec_none_nih, /* thread security attrs */
|
||||||
|
TRUE, /* inherit handles from parent */
|
||||||
|
c_flags,
|
||||||
|
NULL, /* environment filled in later */
|
||||||
|
0, /* use current drive/directory */
|
||||||
|
&si,
|
||||||
|
&pi);
|
||||||
|
|
||||||
|
CloseHandle (hParent);
|
||||||
|
|
||||||
|
if (!rc)
|
||||||
|
{
|
||||||
|
__seterrno ();
|
||||||
|
syscall_printf ("-1 = fork(), CreateProcessA failed");
|
||||||
|
child->process_state = PID_NOT_IN_USE;
|
||||||
|
ForceCloseHandle(subproc_ready);
|
||||||
|
ForceCloseHandle(forker_finished);
|
||||||
|
subproc_ready = forker_finished = NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProtectHandle (pi.hThread);
|
||||||
|
/* Protect the handle but name it similarly to the way it will
|
||||||
|
be called in subproc handling. */
|
||||||
|
ProtectHandle1 (pi.hProcess, childhProc);
|
||||||
|
|
||||||
|
/* Fill in fields in the child's process table entry. */
|
||||||
|
child->ppid = myself->pid;
|
||||||
|
child->hProcess = pi.hProcess;
|
||||||
|
child->dwProcessId = pi.dwProcessId;
|
||||||
|
child->uid = myself->uid;
|
||||||
|
child->gid = myself->gid;
|
||||||
|
child->pgid = myself->pgid;
|
||||||
|
child->sid = myself->sid;
|
||||||
|
child->ctty = myself->ctty;
|
||||||
|
child->umask = myself->umask;
|
||||||
|
child->copysigs(myself);
|
||||||
|
child->process_state |= PID_INITIALIZING |
|
||||||
|
(myself->process_state & PID_USETTY);
|
||||||
|
memcpy (child->username, myself->username, MAX_USER_NAME);
|
||||||
|
child->psid = myself->psid;
|
||||||
|
memcpy (child->sidbuf, myself->sidbuf, 40);
|
||||||
|
memcpy (child->logsrv, myself->logsrv, 256);
|
||||||
|
memcpy (child->domain, myself->domain, MAX_COMPUTERNAME_LENGTH+1);
|
||||||
|
set_child_mmap_ptr (child);
|
||||||
|
|
||||||
|
/* Wait for subproc to initialize itself. */
|
||||||
|
if (!sync_with_child(pi, subproc_ready, TRUE, "waiting for longjmp"))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
/* CHILD IS STOPPED */
|
||||||
|
debug_printf ("child is alive (but stopped)");
|
||||||
|
|
||||||
|
/* Initialize, in order: data, bss, heap, stack, dll data, dll bss
|
||||||
|
Note: variables marked as NO_COPY will not be copied
|
||||||
|
since they are placed in a protected segment. */
|
||||||
|
|
||||||
|
|
||||||
|
MALLOC_CHECK;
|
||||||
|
rc = fork_copy (pi, "user/cygwin data",
|
||||||
|
user_data->data_start, user_data->data_end,
|
||||||
|
user_data->bss_start, user_data->bss_end,
|
||||||
|
ch.heapbase, ch.heapptr,
|
||||||
|
stack_here, ch.stackbottom,
|
||||||
|
dll_data_start, dll_data_end,
|
||||||
|
dll_bss_start, dll_bss_end, NULL);
|
||||||
|
|
||||||
|
MALLOC_CHECK;
|
||||||
|
if (!rc)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
/* Now fill data/bss of linked dll */
|
||||||
|
DO_LINKED_DLL (p)
|
||||||
|
{
|
||||||
|
debug_printf ("copying data/bss of a linked dll");
|
||||||
|
if (!fork_copy (pi, "linked dll data/bss", p->data_start, p->data_end,
|
||||||
|
p->bss_start, p->bss_end,
|
||||||
|
NULL))
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
DLL_DONE;
|
||||||
|
|
||||||
|
proc_register (child);
|
||||||
|
int load_dll = DllList::the().forkeeMustReloadDlls() &&
|
||||||
|
DllList::the().numberOfOpenedDlls();
|
||||||
|
|
||||||
|
/* Start thread, and wait for it to reload dlls. */
|
||||||
|
if (!resume_child (pi, subproc_ready, forker_finished) ||
|
||||||
|
!sync_with_child (pi, subproc_ready, load_dll, "child loading dlls"))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
/* child reload dlls & then write their data and bss */
|
||||||
|
if (load_dll)
|
||||||
|
{
|
||||||
|
/* CHILD IS STOPPED */
|
||||||
|
/* write memory of reloaded dlls */
|
||||||
|
DO_LOADED_DLL (p)
|
||||||
|
{
|
||||||
|
debug_printf ("copying data/bss for a loaded dll");
|
||||||
|
if (!fork_copy (pi, "loaded dll data/bss", p->data_start, p->data_end,
|
||||||
|
p->bss_start, p->bss_end,
|
||||||
|
NULL))
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
DLL_DONE;
|
||||||
|
/* Start the child up again. */
|
||||||
|
(void) resume_child (pi, subproc_ready, forker_finished);
|
||||||
|
}
|
||||||
|
|
||||||
|
ForceCloseHandle (subproc_ready);
|
||||||
|
ForceCloseHandle (pi.hThread);
|
||||||
|
ForceCloseHandle (forker_finished);
|
||||||
|
forker_finished = NULL;
|
||||||
|
pi.hThread = NULL;
|
||||||
|
|
||||||
|
res = child->pid;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/**** Child *****/
|
||||||
|
|
||||||
|
/* We arrive here via a longjmp from "crt0". */
|
||||||
|
(void) stack_dummy (0); // Just to make sure
|
||||||
|
debug_printf ("child is running %d", x);
|
||||||
|
|
||||||
|
debug_printf ("self %p, pid %d, ppid %d",
|
||||||
|
myself, x, myself ? myself->ppid : -1);
|
||||||
|
|
||||||
|
sync_with_parent ("after longjmp.", TRUE);
|
||||||
|
ProtectHandle (hParent);
|
||||||
|
|
||||||
|
#ifdef DEBUGGING
|
||||||
|
char c;
|
||||||
|
if (GetEnvironmentVariable ("FORKDEBUG", &c, 1))
|
||||||
|
try_to_debug ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If we've played with the stack, stacksize != 0. That means that
|
||||||
|
fork() was invoked from other than the main thread. Make sure that
|
||||||
|
when the "main" thread exits it calls do_exit, like a normal process.
|
||||||
|
Exit with a status code of 0. */
|
||||||
|
if (child_proc_info->stacksize)
|
||||||
|
{
|
||||||
|
((DWORD *)child_proc_info->stackbottom)[-17] = (DWORD)do_exit;
|
||||||
|
((DWORD *)child_proc_info->stackbottom)[-15] = (DWORD)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MALLOC_CHECK;
|
||||||
|
|
||||||
|
dtable.fixup_after_fork (hParent);
|
||||||
|
ForceCloseHandle (hParent);
|
||||||
|
|
||||||
|
MALLOC_CHECK;
|
||||||
|
|
||||||
|
/* reload dlls if necessary */
|
||||||
|
if (!DllList::the().forkeeMustReloadDlls() ||
|
||||||
|
!DllList::the().numberOfOpenedDlls())
|
||||||
|
sync_with_parent ("performed fork fixup.", FALSE);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DllList::the().forkeeLoadDlls();
|
||||||
|
sync_with_parent ("loaded dlls", TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
(void) ForceCloseHandle (child_proc_info->subproc_ready);
|
||||||
|
(void) ForceCloseHandle (child_proc_info->forker_finished);
|
||||||
|
|
||||||
|
if (recreate_mmaps_after_fork (myself->mmap_ptr))
|
||||||
|
api_fatal ("recreate_mmaps_after_fork_failed");
|
||||||
|
|
||||||
|
res = 0;
|
||||||
|
/* Set thread local stuff to zero. Under Windows 95/98 this is sometimes
|
||||||
|
non-zero, for some reason.
|
||||||
|
FIXME: There is a memory leak here after a fork. */
|
||||||
|
for (per_thread **t = threadstuff; *t; t++)
|
||||||
|
if ((*t)->clear_on_fork ())
|
||||||
|
(*t)->set ();
|
||||||
|
|
||||||
|
/* Initialize signal/process handling */
|
||||||
|
sigproc_init ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MALLOC_CHECK;
|
||||||
|
syscall_printf ("%d = fork()", res);
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/* Common cleanup code for failure cases */
|
||||||
|
cleanup:
|
||||||
|
/* Remember to de-allocate the fd table. */
|
||||||
|
child->process_state = PID_NOT_IN_USE;
|
||||||
|
if (pi.hProcess)
|
||||||
|
ForceCloseHandle1 (pi.hProcess, childhProc);
|
||||||
|
if (pi.hThread)
|
||||||
|
ForceCloseHandle (pi.hThread);
|
||||||
|
if (subproc_ready)
|
||||||
|
ForceCloseHandle (subproc_ready);
|
||||||
|
if (forker_finished)
|
||||||
|
ForceCloseHandle (forker_finished);
|
||||||
|
forker_finished = subproc_ready = child->hProcess = NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static volatile void
|
||||||
|
grow_stack_slack ()
|
||||||
|
{
|
||||||
|
volatile char dummy[16384];
|
||||||
|
dummy[0] = dummy[16383] = 0; // Just to make some slack in the stack
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef NEWVFORK
|
||||||
|
/* Dummy function to force second assignment below to actually be
|
||||||
|
carried out */
|
||||||
|
static vfork_save *
|
||||||
|
get_vfork_val ()
|
||||||
|
{
|
||||||
|
return vfork_storage.val ();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int
|
||||||
|
vfork ()
|
||||||
|
{
|
||||||
|
#ifndef NEWVFORK
|
||||||
|
return fork ();
|
||||||
|
#else
|
||||||
|
vfork_save *vf = get_vfork_val ();
|
||||||
|
|
||||||
|
if (vf == NULL)
|
||||||
|
vf = vfork_storage.create ();
|
||||||
|
|
||||||
|
if (!setjmp (vf->j))
|
||||||
|
{
|
||||||
|
vf->pid = -1;
|
||||||
|
__asm__ volatile ("movl %%ebp,%0": "=r" (vf->vfork_ebp):);
|
||||||
|
__asm__ volatile ("movl (%%ebp),%0": "=r" (vf->caller_ebp):);
|
||||||
|
__asm__ volatile ("movl 4(%%ebp),%0": "=r" (vf->retaddr):);
|
||||||
|
return dtable.vfork_child_dup () ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dtable.vfork_parent_restore ();
|
||||||
|
|
||||||
|
vf = get_vfork_val ();
|
||||||
|
if (vf->pid < 0)
|
||||||
|
{
|
||||||
|
int exitval = -vf->pid;
|
||||||
|
if ((vf->pid = fork ()) == 0)
|
||||||
|
exit (exitval);
|
||||||
|
}
|
||||||
|
|
||||||
|
vf->vfork_ebp[0] = vf->caller_ebp;
|
||||||
|
vf->vfork_ebp[1] = vf->retaddr;
|
||||||
|
return vf->pid;
|
||||||
|
#endif
|
||||||
|
}
|
41
winsup/cygwin/gcrt0.c
Normal file
41
winsup/cygwin/gcrt0.c
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/* gcrt0.c
|
||||||
|
|
||||||
|
Copyright 1998 Cygnus Solutions.
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
extern u_char etext asm ("etext");
|
||||||
|
extern u_char eprol asm ("__eprol");
|
||||||
|
extern void _mcleanup (void);
|
||||||
|
extern void monstartup (u_long, u_long);
|
||||||
|
|
||||||
|
void _monstartup (void) __attribute__((__constructor__));
|
||||||
|
|
||||||
|
/* startup initialization for -pg support */
|
||||||
|
|
||||||
|
void
|
||||||
|
_monstartup (void)
|
||||||
|
{
|
||||||
|
static int called;
|
||||||
|
|
||||||
|
/* Guard against multiple calls that may happen if DLLs are linked
|
||||||
|
with profile option set as well. Addede side benefit is that it
|
||||||
|
makes profiling backward compatible (GCC used to emit a call to
|
||||||
|
_monstartup when compiling main with profiling enabled). */
|
||||||
|
if (called++)
|
||||||
|
return;
|
||||||
|
|
||||||
|
monstartup ((u_long) &eprol, (u_long) &etext);
|
||||||
|
atexit (&_mcleanup);
|
||||||
|
}
|
||||||
|
|
||||||
|
asm (".text");
|
||||||
|
asm ("__eprol:");
|
||||||
|
|
871
winsup/cygwin/glob.c
Normal file
871
winsup/cygwin/glob.c
Normal file
@ -0,0 +1,871 @@
|
|||||||
|
/* $NetBSD: __glob13.c,v 1.1.2.1 1997/10/22 06:41:27 thorpej Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1989, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Guido van Rossum.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* glob(3) -- a superset of the one defined in POSIX 1003.2.
|
||||||
|
*
|
||||||
|
* The [!...] convention to negate a range is supported (SysV, Posix, ksh).
|
||||||
|
*
|
||||||
|
* Optional extra services, controlled by flags not defined by POSIX:
|
||||||
|
*
|
||||||
|
* GLOB_QUOTE:
|
||||||
|
* Escaping convention: \ inhibits any special meaning the following
|
||||||
|
* character might have (except \ at end of string is retained).
|
||||||
|
* GLOB_MAGCHAR:
|
||||||
|
* Set in gl_flags if pattern contained a globbing character.
|
||||||
|
* GLOB_NOMAGIC:
|
||||||
|
* Same as GLOB_NOCHECK, but it will only append pattern if it did
|
||||||
|
* not contain any magic characters. [Used in csh style globbing]
|
||||||
|
* GLOB_ALTDIRFUNC:
|
||||||
|
* Use alternately specified directory access functions.
|
||||||
|
* GLOB_TILDE:
|
||||||
|
* expand ~user/foo to the /home/dir/of/user/foo
|
||||||
|
* GLOB_BRACE:
|
||||||
|
* expand {1,2}{a,b} to 1a 1b 2a 2b
|
||||||
|
* gl_matchc:
|
||||||
|
* Number of matches in the current invocation of glob.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* CYGNUS LOCAL: don't include */
|
||||||
|
/* #include "namespace.h" */
|
||||||
|
/* end CYGNUS LOCAL */
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <glob.h>
|
||||||
|
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifdef __weak_alias
|
||||||
|
#ifdef __LIBC12_SOURCE__
|
||||||
|
__weak_alias(glob,_glob);
|
||||||
|
__weak_alias(globfree,_globfree);
|
||||||
|
#else
|
||||||
|
#error "XXX THESE ARE NOT RIGHT!"
|
||||||
|
__weak_alias(__glob13,___glob13);
|
||||||
|
__weak_alias(__globfree13,___globfree13);
|
||||||
|
#endif /* __LIBC12_SOURCE__ */
|
||||||
|
#endif /* __weak_alias */
|
||||||
|
|
||||||
|
#ifdef __LIBC12_SOURCE__
|
||||||
|
#define STAT stat12
|
||||||
|
#else
|
||||||
|
#define STAT stat
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DOLLAR '$'
|
||||||
|
#define DOT '.'
|
||||||
|
#define EOS '\0'
|
||||||
|
#define LBRACKET '['
|
||||||
|
#define NOT '!'
|
||||||
|
#define QUESTION '?'
|
||||||
|
#define QUOTE '\\'
|
||||||
|
#define RANGE '-'
|
||||||
|
#define RBRACKET ']'
|
||||||
|
#define SEP '/'
|
||||||
|
#define STAR '*'
|
||||||
|
#define TILDE '~'
|
||||||
|
#define UNDERSCORE '_'
|
||||||
|
#define LBRACE '{'
|
||||||
|
#define RBRACE '}'
|
||||||
|
#define SLASH '/'
|
||||||
|
#define COMMA ','
|
||||||
|
|
||||||
|
#ifndef DEBUG
|
||||||
|
|
||||||
|
#define M_QUOTE 0x8000
|
||||||
|
#define M_PROTECT 0x4000
|
||||||
|
#define M_MASK 0xffff
|
||||||
|
#define M_ASCII 0x00ff
|
||||||
|
|
||||||
|
typedef u_short Char;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define M_QUOTE 0x80
|
||||||
|
#define M_PROTECT 0x40
|
||||||
|
#define M_MASK 0xff
|
||||||
|
#define M_ASCII 0x7f
|
||||||
|
|
||||||
|
typedef char Char;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define CHAR(c) ((Char)((c)&M_ASCII))
|
||||||
|
#define META(c) ((Char)((c)|M_QUOTE))
|
||||||
|
#define M_ALL META('*')
|
||||||
|
#define M_END META(']')
|
||||||
|
#define M_NOT META('!')
|
||||||
|
#define M_ONE META('?')
|
||||||
|
#define M_RNG META('-')
|
||||||
|
#define M_SET META('[')
|
||||||
|
#define ismeta(c) (((c)&M_QUOTE) != 0)
|
||||||
|
|
||||||
|
|
||||||
|
static int compare __P((const void *, const void *));
|
||||||
|
static void g_Ctoc __P((const Char *, char *));
|
||||||
|
static int g_lstat __P((Char *, struct STAT *, glob_t *));
|
||||||
|
static DIR *g_opendir __P((Char *, glob_t *));
|
||||||
|
static Char *g_strchr __P((Char *, int));
|
||||||
|
#ifdef notdef
|
||||||
|
static Char *g_strcat __P((Char *, const Char *));
|
||||||
|
#endif
|
||||||
|
static int g_stat __P((Char *, struct STAT *, glob_t *));
|
||||||
|
static int glob0 __P((const Char *, glob_t *));
|
||||||
|
static int glob1 __P((Char *, glob_t *));
|
||||||
|
static int glob2 __P((Char *, Char *, Char *, glob_t *));
|
||||||
|
static int glob3 __P((Char *, Char *, Char *, Char *, glob_t *));
|
||||||
|
static int globextend __P((const Char *, glob_t *));
|
||||||
|
static const Char * globtilde __P((const Char *, Char *, glob_t *));
|
||||||
|
static int globexp1 __P((const Char *, glob_t *));
|
||||||
|
static int globexp2 __P((const Char *, const Char *, glob_t *, int *));
|
||||||
|
static int match __P((Char *, Char *, Char *));
|
||||||
|
#ifdef DEBUG
|
||||||
|
static void qprintf __P((const char *, Char *));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef MAXPATHLEN
|
||||||
|
#define MAXPATHLEN 16384
|
||||||
|
|
||||||
|
int
|
||||||
|
glob(pattern, flags, errfunc, pglob)
|
||||||
|
const char *pattern;
|
||||||
|
int flags, (*errfunc) __P((const char *, int));
|
||||||
|
glob_t *pglob;
|
||||||
|
{
|
||||||
|
const u_char *patnext;
|
||||||
|
int c;
|
||||||
|
Char *bufnext, *bufend, patbuf[MAXPATHLEN+1];
|
||||||
|
|
||||||
|
patnext = (u_char *) pattern;
|
||||||
|
if (!(flags & GLOB_APPEND)) {
|
||||||
|
pglob->gl_pathc = 0;
|
||||||
|
pglob->gl_pathv = NULL;
|
||||||
|
if (!(flags & GLOB_DOOFFS))
|
||||||
|
pglob->gl_offs = 0;
|
||||||
|
}
|
||||||
|
pglob->gl_flags = flags & ~GLOB_MAGCHAR;
|
||||||
|
pglob->gl_errfunc = errfunc;
|
||||||
|
pglob->gl_matchc = 0;
|
||||||
|
|
||||||
|
bufnext = patbuf;
|
||||||
|
bufend = bufnext + MAXPATHLEN;
|
||||||
|
if (flags & GLOB_QUOTE) {
|
||||||
|
/* Protect the quoted characters. */
|
||||||
|
while (bufnext < bufend && (c = *patnext++) != EOS)
|
||||||
|
if (c == QUOTE) {
|
||||||
|
if ((c = *patnext++) == EOS) {
|
||||||
|
c = QUOTE;
|
||||||
|
--patnext;
|
||||||
|
}
|
||||||
|
*bufnext++ = c | M_PROTECT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*bufnext++ = c;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
while (bufnext < bufend && (c = *patnext++) != EOS)
|
||||||
|
*bufnext++ = c;
|
||||||
|
*bufnext = EOS;
|
||||||
|
|
||||||
|
if (flags & GLOB_BRACE)
|
||||||
|
return globexp1(patbuf, pglob);
|
||||||
|
else
|
||||||
|
return glob0(patbuf, pglob);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Expand recursively a glob {} pattern. When there is no more expansion
|
||||||
|
* invoke the standard globbing routine to glob the rest of the magic
|
||||||
|
* characters
|
||||||
|
*/
|
||||||
|
static int globexp1(pattern, pglob)
|
||||||
|
const Char *pattern;
|
||||||
|
glob_t *pglob;
|
||||||
|
{
|
||||||
|
const Char* ptr = pattern;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
/* Protect a single {}, for find(1), like csh */
|
||||||
|
if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS)
|
||||||
|
return glob0(pattern, pglob);
|
||||||
|
|
||||||
|
while ((ptr = (const Char *) g_strchr((Char *) ptr, LBRACE)) != NULL)
|
||||||
|
if (!globexp2(ptr, pattern, pglob, &rv))
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
return glob0(pattern, pglob);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Recursive brace globbing helper. Tries to expand a single brace.
|
||||||
|
* If it succeeds then it invokes globexp1 with the new pattern.
|
||||||
|
* If it fails then it tries to glob the rest of the pattern and returns.
|
||||||
|
*/
|
||||||
|
static int globexp2(ptr, pattern, pglob, rv)
|
||||||
|
const Char *ptr, *pattern;
|
||||||
|
glob_t *pglob;
|
||||||
|
int *rv;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
Char *lm, *ls;
|
||||||
|
const Char *pe, *pm, *pl;
|
||||||
|
Char patbuf[MAXPATHLEN + 1];
|
||||||
|
|
||||||
|
/* copy part up to the brace */
|
||||||
|
for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++)
|
||||||
|
continue;
|
||||||
|
ls = lm;
|
||||||
|
|
||||||
|
/* Find the balanced brace */
|
||||||
|
for (i = 0, pe = ++ptr; *pe; pe++)
|
||||||
|
if (*pe == LBRACKET) {
|
||||||
|
/* Ignore everything between [] */
|
||||||
|
for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++)
|
||||||
|
continue;
|
||||||
|
if (*pe == EOS) {
|
||||||
|
/*
|
||||||
|
* We could not find a matching RBRACKET.
|
||||||
|
* Ignore and just look for RBRACE
|
||||||
|
*/
|
||||||
|
pe = pm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (*pe == LBRACE)
|
||||||
|
i++;
|
||||||
|
else if (*pe == RBRACE) {
|
||||||
|
if (i == 0)
|
||||||
|
break;
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Non matching braces; just glob the pattern */
|
||||||
|
if (i != 0 || *pe == EOS) {
|
||||||
|
*rv = glob0(patbuf, pglob);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0, pl = pm = ptr; pm <= pe; pm++)
|
||||||
|
switch (*pm) {
|
||||||
|
case LBRACKET:
|
||||||
|
/* Ignore everything between [] */
|
||||||
|
for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++)
|
||||||
|
continue;
|
||||||
|
if (*pm == EOS) {
|
||||||
|
/*
|
||||||
|
* We could not find a matching RBRACKET.
|
||||||
|
* Ignore and just look for RBRACE
|
||||||
|
*/
|
||||||
|
pm = pl;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LBRACE:
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RBRACE:
|
||||||
|
if (i) {
|
||||||
|
i--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case COMMA:
|
||||||
|
if (i && *pm == COMMA)
|
||||||
|
break;
|
||||||
|
else {
|
||||||
|
/* Append the current string */
|
||||||
|
for (lm = ls; (pl < pm); *lm++ = *pl++)
|
||||||
|
continue;
|
||||||
|
/*
|
||||||
|
* Append the rest of the pattern after the
|
||||||
|
* closing brace
|
||||||
|
*/
|
||||||
|
for (pl = pe + 1; (*lm++ = *pl++) != EOS;)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Expand the current pattern */
|
||||||
|
#ifdef DEBUG
|
||||||
|
qprintf("globexp2:", patbuf);
|
||||||
|
#endif
|
||||||
|
*rv = globexp1(patbuf, pglob);
|
||||||
|
|
||||||
|
/* move after the comma, to the next string */
|
||||||
|
pl = pm + 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*rv = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* expand tilde from the passwd file.
|
||||||
|
*/
|
||||||
|
static const Char *
|
||||||
|
globtilde(pattern, patbuf, pglob)
|
||||||
|
const Char *pattern;
|
||||||
|
Char *patbuf;
|
||||||
|
glob_t *pglob;
|
||||||
|
{
|
||||||
|
struct passwd *pwd;
|
||||||
|
char *h;
|
||||||
|
const Char *p;
|
||||||
|
Char *b;
|
||||||
|
|
||||||
|
if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE))
|
||||||
|
return pattern;
|
||||||
|
|
||||||
|
/* Copy up to the end of the string or / */
|
||||||
|
for (p = pattern + 1, h = (char *) patbuf; *p && *p != SLASH;
|
||||||
|
*h++ = *p++)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
*h = EOS;
|
||||||
|
|
||||||
|
if (((char *) patbuf)[0] == EOS) {
|
||||||
|
/*
|
||||||
|
* handle a plain ~ or ~/ by expanding $HOME
|
||||||
|
* first and then trying the password file
|
||||||
|
*/
|
||||||
|
if ((h = getenv("HOME")) == NULL) {
|
||||||
|
if ((pwd = getpwuid(getuid())) == NULL)
|
||||||
|
return pattern;
|
||||||
|
else
|
||||||
|
h = pwd->pw_dir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/*
|
||||||
|
* Expand a ~user
|
||||||
|
*/
|
||||||
|
if ((pwd = getpwnam((char*) patbuf)) == NULL)
|
||||||
|
return pattern;
|
||||||
|
else
|
||||||
|
h = pwd->pw_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the home directory */
|
||||||
|
for (b = patbuf; *h; *b++ = *h++)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Append the rest of the pattern */
|
||||||
|
while ((*b++ = *p++) != EOS)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return patbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The main glob() routine: compiles the pattern (optionally processing
|
||||||
|
* quotes), calls glob1() to do the real pattern matching, and finally
|
||||||
|
* sorts the list (unless unsorted operation is requested). Returns 0
|
||||||
|
* if things went well, nonzero if errors occurred. It is not an error
|
||||||
|
* to find no matches.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
glob0(pattern, pglob)
|
||||||
|
const Char *pattern;
|
||||||
|
glob_t *pglob;
|
||||||
|
{
|
||||||
|
const Char *qpatnext;
|
||||||
|
int c, err, oldpathc;
|
||||||
|
Char *bufnext, patbuf[MAXPATHLEN+1];
|
||||||
|
|
||||||
|
qpatnext = globtilde(pattern, patbuf, pglob);
|
||||||
|
oldpathc = pglob->gl_pathc;
|
||||||
|
bufnext = patbuf;
|
||||||
|
|
||||||
|
/* We don't need to check for buffer overflow any more. */
|
||||||
|
while ((c = *qpatnext++) != EOS) {
|
||||||
|
switch (c) {
|
||||||
|
case LBRACKET:
|
||||||
|
c = *qpatnext;
|
||||||
|
if (c == NOT)
|
||||||
|
++qpatnext;
|
||||||
|
if (*qpatnext == EOS ||
|
||||||
|
g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) {
|
||||||
|
*bufnext++ = LBRACKET;
|
||||||
|
if (c == NOT)
|
||||||
|
--qpatnext;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*bufnext++ = M_SET;
|
||||||
|
if (c == NOT)
|
||||||
|
*bufnext++ = M_NOT;
|
||||||
|
c = *qpatnext++;
|
||||||
|
do {
|
||||||
|
*bufnext++ = CHAR(c);
|
||||||
|
if (*qpatnext == RANGE &&
|
||||||
|
(c = qpatnext[1]) != RBRACKET) {
|
||||||
|
*bufnext++ = M_RNG;
|
||||||
|
*bufnext++ = CHAR(c);
|
||||||
|
qpatnext += 2;
|
||||||
|
}
|
||||||
|
} while ((c = *qpatnext++) != RBRACKET);
|
||||||
|
pglob->gl_flags |= GLOB_MAGCHAR;
|
||||||
|
*bufnext++ = M_END;
|
||||||
|
break;
|
||||||
|
case QUESTION:
|
||||||
|
pglob->gl_flags |= GLOB_MAGCHAR;
|
||||||
|
*bufnext++ = M_ONE;
|
||||||
|
break;
|
||||||
|
case STAR:
|
||||||
|
pglob->gl_flags |= GLOB_MAGCHAR;
|
||||||
|
/* collapse adjacent stars to one,
|
||||||
|
* to avoid exponential behavior
|
||||||
|
*/
|
||||||
|
if (bufnext == patbuf || bufnext[-1] != M_ALL)
|
||||||
|
*bufnext++ = M_ALL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*bufnext++ = CHAR(c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*bufnext = EOS;
|
||||||
|
#ifdef DEBUG
|
||||||
|
qprintf("glob0:", patbuf);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((err = glob1(patbuf, pglob)) != 0)
|
||||||
|
return(err);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If there was no match we are going to append the pattern
|
||||||
|
* if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified
|
||||||
|
* and the pattern did not contain any magic characters
|
||||||
|
* GLOB_NOMAGIC is there just for compatibility with csh.
|
||||||
|
*/
|
||||||
|
if (pglob->gl_pathc == oldpathc &&
|
||||||
|
((pglob->gl_flags & GLOB_NOCHECK) ||
|
||||||
|
((pglob->gl_flags & GLOB_NOMAGIC) &&
|
||||||
|
!(pglob->gl_flags & GLOB_MAGCHAR))))
|
||||||
|
return(globextend(pattern, pglob));
|
||||||
|
else if (!(pglob->gl_flags & GLOB_NOSORT))
|
||||||
|
qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
|
||||||
|
pglob->gl_pathc - oldpathc, sizeof(char *), compare);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
compare(p, q)
|
||||||
|
const void *p, *q;
|
||||||
|
{
|
||||||
|
return(strcmp(*(char **)p, *(char **)q));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
glob1(pattern, pglob)
|
||||||
|
Char *pattern;
|
||||||
|
glob_t *pglob;
|
||||||
|
{
|
||||||
|
Char pathbuf[MAXPATHLEN+1];
|
||||||
|
|
||||||
|
/* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */
|
||||||
|
if (*pattern == EOS)
|
||||||
|
return(0);
|
||||||
|
return(glob2(pathbuf, pathbuf, pattern, pglob));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The functions glob2 and glob3 are mutually recursive; there is one level
|
||||||
|
* of recursion for each segment in the pattern that contains one or more
|
||||||
|
* meta characters.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
glob2(pathbuf, pathend, pattern, pglob)
|
||||||
|
Char *pathbuf, *pathend, *pattern;
|
||||||
|
glob_t *pglob;
|
||||||
|
{
|
||||||
|
struct STAT sb;
|
||||||
|
Char *p, *q;
|
||||||
|
int anymeta;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Loop over pattern segments until end of pattern or until
|
||||||
|
* segment with meta character found.
|
||||||
|
*/
|
||||||
|
for (anymeta = 0;;) {
|
||||||
|
if (*pattern == EOS) { /* End of pattern? */
|
||||||
|
*pathend = EOS;
|
||||||
|
if (g_lstat(pathbuf, &sb, pglob))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if (((pglob->gl_flags & GLOB_MARK) &&
|
||||||
|
pathend[-1] != SEP) && (S_ISDIR(sb.st_mode)
|
||||||
|
|| (S_ISLNK(sb.st_mode) &&
|
||||||
|
(g_stat(pathbuf, &sb, pglob) == 0) &&
|
||||||
|
S_ISDIR(sb.st_mode)))) {
|
||||||
|
*pathend++ = SEP;
|
||||||
|
*pathend = EOS;
|
||||||
|
}
|
||||||
|
++pglob->gl_matchc;
|
||||||
|
return(globextend(pathbuf, pglob));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find end of next segment, copy tentatively to pathend. */
|
||||||
|
q = pathend;
|
||||||
|
p = pattern;
|
||||||
|
while (*p != EOS && *p != SEP) {
|
||||||
|
if (ismeta(*p))
|
||||||
|
anymeta = 1;
|
||||||
|
*q++ = *p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!anymeta) { /* No expansion, do next segment. */
|
||||||
|
pathend = q;
|
||||||
|
pattern = p;
|
||||||
|
while (*pattern == SEP)
|
||||||
|
*pathend++ = *pattern++;
|
||||||
|
} else /* Need expansion, recurse. */
|
||||||
|
return(glob3(pathbuf, pathend, pattern, p, pglob));
|
||||||
|
}
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
glob3(pathbuf, pathend, pattern, restpattern, pglob)
|
||||||
|
Char *pathbuf, *pathend, *pattern, *restpattern;
|
||||||
|
glob_t *pglob;
|
||||||
|
{
|
||||||
|
register struct dirent *dp;
|
||||||
|
DIR *dirp;
|
||||||
|
int err;
|
||||||
|
char buf[MAXPATHLEN];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The readdirfunc declaration can't be prototyped, because it is
|
||||||
|
* assigned, below, to two functions which are prototyped in glob.h
|
||||||
|
* and dirent.h as taking pointers to differently typed opaque
|
||||||
|
* structures.
|
||||||
|
*/
|
||||||
|
struct dirent *(*readdirfunc) __P((void *));
|
||||||
|
|
||||||
|
*pathend = EOS;
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {
|
||||||
|
/* TODO: don't call for ENOENT or ENOTDIR? */
|
||||||
|
if (pglob->gl_errfunc) {
|
||||||
|
g_Ctoc(pathbuf, buf);
|
||||||
|
if (pglob->gl_errfunc(buf, errno) ||
|
||||||
|
pglob->gl_flags & GLOB_ERR)
|
||||||
|
return (GLOB_ABEND);
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
err = 0;
|
||||||
|
|
||||||
|
/* Search directory for matching names. */
|
||||||
|
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
|
||||||
|
readdirfunc = pglob->gl_readdir;
|
||||||
|
else
|
||||||
|
readdirfunc = (struct dirent *(*)__P((void *))) readdir;
|
||||||
|
while ((dp = (*readdirfunc)(dirp))) {
|
||||||
|
register u_char *sc;
|
||||||
|
register Char *dc;
|
||||||
|
|
||||||
|
/* Initial DOT must be matched literally. */
|
||||||
|
if (dp->d_name[0] == DOT && *pattern != DOT)
|
||||||
|
continue;
|
||||||
|
for (sc = (u_char *) dp->d_name, dc = pathend;
|
||||||
|
(*dc++ = *sc++) != EOS;)
|
||||||
|
continue;
|
||||||
|
if (!match(pathend, pattern, restpattern)) {
|
||||||
|
*pathend = EOS;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
err = glob2(pathbuf, --dc, restpattern, pglob);
|
||||||
|
if (err)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
|
||||||
|
(*pglob->gl_closedir)(dirp);
|
||||||
|
else
|
||||||
|
closedir(dirp);
|
||||||
|
return(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extend the gl_pathv member of a glob_t structure to accomodate a new item,
|
||||||
|
* add the new item, and update gl_pathc.
|
||||||
|
*
|
||||||
|
* This assumes the BSD realloc, which only copies the block when its size
|
||||||
|
* crosses a power-of-two boundary; for v7 realloc, this would cause quadratic
|
||||||
|
* behavior.
|
||||||
|
*
|
||||||
|
* Return 0 if new item added, error code if memory couldn't be allocated.
|
||||||
|
*
|
||||||
|
* Invariant of the glob_t structure:
|
||||||
|
* Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and
|
||||||
|
* gl_pathv points to (gl_offs + gl_pathc + 1) items.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
globextend(path, pglob)
|
||||||
|
const Char *path;
|
||||||
|
glob_t *pglob;
|
||||||
|
{
|
||||||
|
register char **pathv;
|
||||||
|
register int i;
|
||||||
|
u_int newsize;
|
||||||
|
char *copy;
|
||||||
|
const Char *p;
|
||||||
|
|
||||||
|
newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);
|
||||||
|
pathv = pglob->gl_pathv ?
|
||||||
|
realloc((char *)pglob->gl_pathv, newsize) :
|
||||||
|
malloc(newsize);
|
||||||
|
if (pathv == NULL)
|
||||||
|
return(GLOB_NOSPACE);
|
||||||
|
|
||||||
|
if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) {
|
||||||
|
/* first time around -- clear initial gl_offs items */
|
||||||
|
pathv += pglob->gl_offs;
|
||||||
|
for (i = pglob->gl_offs; --i >= 0; )
|
||||||
|
*--pathv = NULL;
|
||||||
|
}
|
||||||
|
pglob->gl_pathv = pathv;
|
||||||
|
|
||||||
|
for (p = path; *p++;)
|
||||||
|
continue;
|
||||||
|
if ((copy = malloc(p - path)) != NULL) {
|
||||||
|
g_Ctoc(path, copy);
|
||||||
|
pathv[pglob->gl_offs + pglob->gl_pathc++] = copy;
|
||||||
|
}
|
||||||
|
pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
|
||||||
|
return(copy == NULL ? GLOB_NOSPACE : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pattern matching function for filenames. Each occurrence of the *
|
||||||
|
* pattern causes a recursion level.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
match(name, pat, patend)
|
||||||
|
register Char *name, *pat, *patend;
|
||||||
|
{
|
||||||
|
int ok, negate_range;
|
||||||
|
Char c, k;
|
||||||
|
|
||||||
|
while (pat < patend) {
|
||||||
|
c = *pat++;
|
||||||
|
switch (c & M_MASK) {
|
||||||
|
case M_ALL:
|
||||||
|
if (pat == patend)
|
||||||
|
return(1);
|
||||||
|
do
|
||||||
|
if (match(name, pat, patend))
|
||||||
|
return(1);
|
||||||
|
while (*name++ != EOS);
|
||||||
|
return(0);
|
||||||
|
case M_ONE:
|
||||||
|
if (*name++ == EOS)
|
||||||
|
return(0);
|
||||||
|
break;
|
||||||
|
case M_SET:
|
||||||
|
ok = 0;
|
||||||
|
if ((k = *name++) == EOS)
|
||||||
|
return(0);
|
||||||
|
if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS)
|
||||||
|
++pat;
|
||||||
|
while (((c = *pat++) & M_MASK) != M_END)
|
||||||
|
if ((*pat & M_MASK) == M_RNG) {
|
||||||
|
if (c <= k && k <= pat[1])
|
||||||
|
ok = 1;
|
||||||
|
pat += 2;
|
||||||
|
} else if (c == k)
|
||||||
|
ok = 1;
|
||||||
|
if (ok == negate_range)
|
||||||
|
return(0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (*name++ != c)
|
||||||
|
return(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(*name == EOS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free allocated data belonging to a glob_t structure. */
|
||||||
|
void
|
||||||
|
globfree(pglob)
|
||||||
|
glob_t *pglob;
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
register char **pp;
|
||||||
|
|
||||||
|
if (pglob->gl_pathv != NULL) {
|
||||||
|
pp = pglob->gl_pathv + pglob->gl_offs;
|
||||||
|
for (i = pglob->gl_pathc; i--; ++pp)
|
||||||
|
if (*pp)
|
||||||
|
free(*pp);
|
||||||
|
free(pglob->gl_pathv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DIR *
|
||||||
|
g_opendir(str, pglob)
|
||||||
|
register Char *str;
|
||||||
|
glob_t *pglob;
|
||||||
|
{
|
||||||
|
char buf[MAXPATHLEN];
|
||||||
|
|
||||||
|
if (!*str)
|
||||||
|
strcpy(buf, ".");
|
||||||
|
else
|
||||||
|
g_Ctoc(str, buf);
|
||||||
|
|
||||||
|
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
|
||||||
|
return((*pglob->gl_opendir)(buf));
|
||||||
|
|
||||||
|
return(opendir(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
g_lstat(fn, sb, pglob)
|
||||||
|
register Char *fn;
|
||||||
|
struct STAT *sb;
|
||||||
|
glob_t *pglob;
|
||||||
|
{
|
||||||
|
char buf[MAXPATHLEN];
|
||||||
|
|
||||||
|
g_Ctoc(fn, buf);
|
||||||
|
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
|
||||||
|
return((*pglob->gl_lstat)(buf, sb));
|
||||||
|
return(lstat(buf, sb));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
g_stat(fn, sb, pglob)
|
||||||
|
register Char *fn;
|
||||||
|
struct STAT *sb;
|
||||||
|
glob_t *pglob;
|
||||||
|
{
|
||||||
|
char buf[MAXPATHLEN];
|
||||||
|
|
||||||
|
g_Ctoc(fn, buf);
|
||||||
|
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
|
||||||
|
return((*pglob->gl_stat)(buf, sb));
|
||||||
|
return(stat(buf, sb));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Char *
|
||||||
|
g_strchr(str, ch)
|
||||||
|
Char *str;
|
||||||
|
int ch;
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
if (*str == ch)
|
||||||
|
return (str);
|
||||||
|
} while (*str++);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef notdef
|
||||||
|
static Char *
|
||||||
|
g_strcat(dst, src)
|
||||||
|
Char *dst;
|
||||||
|
const Char* src;
|
||||||
|
{
|
||||||
|
Char *sdst = dst;
|
||||||
|
|
||||||
|
while (*dst++)
|
||||||
|
continue;
|
||||||
|
--dst;
|
||||||
|
while((*dst++ = *src++) != EOS)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return (sdst);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_Ctoc(str, buf)
|
||||||
|
register const Char *str;
|
||||||
|
char *buf;
|
||||||
|
{
|
||||||
|
register char *dc;
|
||||||
|
|
||||||
|
for (dc = buf; (*dc++ = *str++) != EOS;)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
static void
|
||||||
|
qprintf(str, s)
|
||||||
|
const char *str;
|
||||||
|
register Char *s;
|
||||||
|
{
|
||||||
|
register Char *p;
|
||||||
|
|
||||||
|
(void)printf("%s:\n", str);
|
||||||
|
for (p = s; *p; p++)
|
||||||
|
(void)printf("%c", CHAR(*p));
|
||||||
|
(void)printf("\n");
|
||||||
|
for (p = s; *p; p++)
|
||||||
|
(void)printf("%c", *p & M_PROTECT ? '"' : ' ');
|
||||||
|
(void)printf("\n");
|
||||||
|
for (p = s; *p; p++)
|
||||||
|
(void)printf("%c", ismeta(*p) ? '_' : ' ');
|
||||||
|
(void)printf("\n");
|
||||||
|
}
|
||||||
|
#endif
|
277
winsup/cygwin/gmon.c
Normal file
277
winsup/cygwin/gmon.c
Normal file
@ -0,0 +1,277 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1983, 1992, 1993
|
||||||
|
* 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(lint) && defined(LIBC_SCCS)
|
||||||
|
static char rcsid[] = "$OpenBSD: gmon.c,v 1.8 1997/07/23 21:11:27 kstailey Exp $";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <gmon.h>
|
||||||
|
|
||||||
|
#include <profil.h>
|
||||||
|
|
||||||
|
/* XXX needed? */
|
||||||
|
//extern char *minbrk __asm ("minbrk");
|
||||||
|
|
||||||
|
struct gmonparam _gmonparam = { GMON_PROF_OFF };
|
||||||
|
|
||||||
|
static int s_scale;
|
||||||
|
/* see profil(2) where this is describe (incorrectly) */
|
||||||
|
#define SCALE_1_TO_1 0x10000L
|
||||||
|
|
||||||
|
#define ERR(s) write(2, s, sizeof(s))
|
||||||
|
|
||||||
|
void moncontrol __P((int));
|
||||||
|
|
||||||
|
static void *
|
||||||
|
fake_sbrk(int size)
|
||||||
|
{
|
||||||
|
return malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
monstartup(lowpc, highpc)
|
||||||
|
u_long lowpc;
|
||||||
|
u_long highpc;
|
||||||
|
{
|
||||||
|
register int o;
|
||||||
|
char *cp;
|
||||||
|
struct gmonparam *p = &_gmonparam;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* round lowpc and highpc to multiples of the density we're using
|
||||||
|
* so the rest of the scaling (here and in gprof) stays in ints.
|
||||||
|
*/
|
||||||
|
p->lowpc = ROUNDDOWN(lowpc, HISTFRACTION * sizeof(HISTCOUNTER));
|
||||||
|
p->highpc = ROUNDUP(highpc, HISTFRACTION * sizeof(HISTCOUNTER));
|
||||||
|
p->textsize = p->highpc - p->lowpc;
|
||||||
|
p->kcountsize = p->textsize / HISTFRACTION;
|
||||||
|
p->hashfraction = HASHFRACTION;
|
||||||
|
p->fromssize = p->textsize / p->hashfraction;
|
||||||
|
p->tolimit = p->textsize * ARCDENSITY / 100;
|
||||||
|
if (p->tolimit < MINARCS)
|
||||||
|
p->tolimit = MINARCS;
|
||||||
|
else if (p->tolimit > MAXARCS)
|
||||||
|
p->tolimit = MAXARCS;
|
||||||
|
p->tossize = p->tolimit * sizeof(struct tostruct);
|
||||||
|
|
||||||
|
cp = fake_sbrk(p->kcountsize + p->fromssize + p->tossize);
|
||||||
|
if (cp == (char *)-1) {
|
||||||
|
ERR("monstartup: out of memory\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#ifdef notdef
|
||||||
|
bzero(cp, p->kcountsize + p->fromssize + p->tossize);
|
||||||
|
#endif
|
||||||
|
p->tos = (struct tostruct *)cp;
|
||||||
|
cp += p->tossize;
|
||||||
|
p->kcount = (u_short *)cp;
|
||||||
|
cp += p->kcountsize;
|
||||||
|
p->froms = (u_short *)cp;
|
||||||
|
|
||||||
|
/* XXX minbrk needed? */
|
||||||
|
//minbrk = fake_sbrk(0);
|
||||||
|
p->tos[0].link = 0;
|
||||||
|
|
||||||
|
o = p->highpc - p->lowpc;
|
||||||
|
if (p->kcountsize < o) {
|
||||||
|
#ifndef notdef
|
||||||
|
s_scale = ((float)p->kcountsize / o ) * SCALE_1_TO_1;
|
||||||
|
#else /* avoid floating point */
|
||||||
|
int quot = o / p->kcountsize;
|
||||||
|
|
||||||
|
if (quot >= 0x10000)
|
||||||
|
s_scale = 1;
|
||||||
|
else if (quot >= 0x100)
|
||||||
|
s_scale = 0x10000 / quot;
|
||||||
|
else if (o >= 0x800000)
|
||||||
|
s_scale = 0x1000000 / (o / (p->kcountsize >> 8));
|
||||||
|
else
|
||||||
|
s_scale = 0x1000000 / ((o << 8) / p->kcountsize);
|
||||||
|
#endif
|
||||||
|
} else
|
||||||
|
s_scale = SCALE_1_TO_1;
|
||||||
|
|
||||||
|
moncontrol(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_mcleanup()
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int hz;
|
||||||
|
int fromindex;
|
||||||
|
int endfrom;
|
||||||
|
u_long frompc;
|
||||||
|
int toindex;
|
||||||
|
struct rawarc rawarc;
|
||||||
|
struct gmonparam *p = &_gmonparam;
|
||||||
|
struct gmonhdr gmonhdr, *hdr;
|
||||||
|
char *proffile;
|
||||||
|
#ifdef DEBUG
|
||||||
|
int log, len;
|
||||||
|
char dbuf[200];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (p->state == GMON_PROF_ERROR)
|
||||||
|
ERR("_mcleanup: tos overflow\n");
|
||||||
|
|
||||||
|
hz = PROF_HZ;
|
||||||
|
moncontrol(0);
|
||||||
|
|
||||||
|
#ifdef nope
|
||||||
|
if ((profdir = getenv("PROFDIR")) != NULL) {
|
||||||
|
extern char *__progname;
|
||||||
|
char *s, *t, *limit;
|
||||||
|
pid_t pid;
|
||||||
|
long divisor;
|
||||||
|
|
||||||
|
/* If PROFDIR contains a null value, no profiling
|
||||||
|
output is produced */
|
||||||
|
if (*profdir == '\0') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
limit = buf + sizeof buf - 1 - 10 - 1 -
|
||||||
|
strlen(__progname) - 1;
|
||||||
|
t = buf;
|
||||||
|
s = profdir;
|
||||||
|
while((*t = *s) != '\0' && t < limit) {
|
||||||
|
t++;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
*t++ = '/';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy and convert pid from a pid_t to a string. For
|
||||||
|
* best performance, divisor should be initialized to
|
||||||
|
* the largest power of 10 less than PID_MAX.
|
||||||
|
*/
|
||||||
|
pid = getpid();
|
||||||
|
divisor=10000;
|
||||||
|
while (divisor > pid) divisor /= 10; /* skip leading zeros */
|
||||||
|
do {
|
||||||
|
*t++ = (pid/divisor) + '0';
|
||||||
|
pid %= divisor;
|
||||||
|
} while (divisor /= 10);
|
||||||
|
*t++ = '.';
|
||||||
|
|
||||||
|
s = __progname;
|
||||||
|
while ((*t++ = *s++) != '\0')
|
||||||
|
;
|
||||||
|
|
||||||
|
proffile = buf;
|
||||||
|
} else {
|
||||||
|
proffile = "gmon.out";
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
proffile = "gmon.out";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fd = open(proffile , O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, 0666);
|
||||||
|
if (fd < 0) {
|
||||||
|
perror( proffile );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
log = open("gmon.log", O_CREAT|O_TRUNC|O_WRONLY, 0664);
|
||||||
|
if (log < 0) {
|
||||||
|
perror("mcount: gmon.log");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
len = sprintf(dbuf, "[mcleanup1] kcount 0x%x ssiz %d\n",
|
||||||
|
p->kcount, p->kcountsize);
|
||||||
|
write(log, dbuf, len);
|
||||||
|
#endif
|
||||||
|
hdr = (struct gmonhdr *)&gmonhdr;
|
||||||
|
hdr->lpc = p->lowpc;
|
||||||
|
hdr->hpc = p->highpc;
|
||||||
|
hdr->ncnt = p->kcountsize + sizeof(gmonhdr);
|
||||||
|
hdr->version = GMONVERSION;
|
||||||
|
hdr->profrate = hz;
|
||||||
|
write(fd, (char *)hdr, sizeof *hdr);
|
||||||
|
write(fd, p->kcount, p->kcountsize);
|
||||||
|
endfrom = p->fromssize / sizeof(*p->froms);
|
||||||
|
for (fromindex = 0; fromindex < endfrom; fromindex++) {
|
||||||
|
if (p->froms[fromindex] == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
frompc = p->lowpc;
|
||||||
|
frompc += fromindex * p->hashfraction * sizeof(*p->froms);
|
||||||
|
for (toindex = p->froms[fromindex]; toindex != 0;
|
||||||
|
toindex = p->tos[toindex].link) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
len = sprintf(dbuf,
|
||||||
|
"[mcleanup2] frompc 0x%x selfpc 0x%x count %d\n" ,
|
||||||
|
frompc, p->tos[toindex].selfpc,
|
||||||
|
p->tos[toindex].count);
|
||||||
|
write(log, dbuf, len);
|
||||||
|
#endif
|
||||||
|
rawarc.raw_frompc = frompc;
|
||||||
|
rawarc.raw_selfpc = p->tos[toindex].selfpc;
|
||||||
|
rawarc.raw_count = p->tos[toindex].count;
|
||||||
|
write(fd, &rawarc, sizeof rawarc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Control profiling
|
||||||
|
* profiling is what mcount checks to see if
|
||||||
|
* all the data structures are ready.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
moncontrol(mode)
|
||||||
|
int mode;
|
||||||
|
{
|
||||||
|
struct gmonparam *p = &_gmonparam;
|
||||||
|
|
||||||
|
if (mode) {
|
||||||
|
/* start */
|
||||||
|
profil((char *)p->kcount, p->kcountsize, p->lowpc,
|
||||||
|
s_scale);
|
||||||
|
p->state = GMON_PROF_ON;
|
||||||
|
} else {
|
||||||
|
/* stop */
|
||||||
|
profil((char *)0, 0, 0, 0);
|
||||||
|
p->state = GMON_PROF_OFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
166
winsup/cygwin/gmon.h
Normal file
166
winsup/cygwin/gmon.h
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
/* $OpenBSD: gmon.h,v 1.3 1996/04/21 22:31:46 deraadt Exp $ */
|
||||||
|
/* $NetBSD: gmon.h,v 1.5 1996/04/09 20:55:30 cgd Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1982, 1986, 1992, 1993
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @(#)gmon.h 8.2 (Berkeley) 1/4/94
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SYS_GMON_H_
|
||||||
|
#define _SYS_GMON_H_
|
||||||
|
|
||||||
|
#ifndef __P
|
||||||
|
#define __P(x) x
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <profile.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure prepended to gmon.out profiling data file.
|
||||||
|
*/
|
||||||
|
struct gmonhdr {
|
||||||
|
u_long lpc; /* base pc address of sample buffer */
|
||||||
|
u_long hpc; /* max pc address of sampled buffer */
|
||||||
|
int ncnt; /* size of sample buffer (plus this header) */
|
||||||
|
int version; /* version number */
|
||||||
|
int profrate; /* profiling clock rate */
|
||||||
|
int spare[3]; /* reserved */
|
||||||
|
};
|
||||||
|
#define GMONVERSION 0x00051879
|
||||||
|
|
||||||
|
/*
|
||||||
|
* histogram counters are unsigned shorts (according to the kernel).
|
||||||
|
*/
|
||||||
|
#define HISTCOUNTER unsigned short
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fraction of text space to allocate for histogram counters here, 1/2
|
||||||
|
*/
|
||||||
|
#define HISTFRACTION 2
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fraction of text space to allocate for from hash buckets.
|
||||||
|
* The value of HASHFRACTION is based on the minimum number of bytes
|
||||||
|
* of separation between two subroutine call points in the object code.
|
||||||
|
* Given MIN_SUBR_SEPARATION bytes of separation the value of
|
||||||
|
* HASHFRACTION is calculated as:
|
||||||
|
*
|
||||||
|
* HASHFRACTION = MIN_SUBR_SEPARATION / (2 * sizeof(short) - 1);
|
||||||
|
*
|
||||||
|
* For example, on the VAX, the shortest two call sequence is:
|
||||||
|
*
|
||||||
|
* calls $0,(r0)
|
||||||
|
* calls $0,(r0)
|
||||||
|
*
|
||||||
|
* which is separated by only three bytes, thus HASHFRACTION is
|
||||||
|
* calculated as:
|
||||||
|
*
|
||||||
|
* HASHFRACTION = 3 / (2 * 2 - 1) = 1
|
||||||
|
*
|
||||||
|
* Note that the division above rounds down, thus if MIN_SUBR_FRACTION
|
||||||
|
* is less than three, this algorithm will not work!
|
||||||
|
*
|
||||||
|
* In practice, however, call instructions are rarely at a minimal
|
||||||
|
* distance. Hence, we will define HASHFRACTION to be 2 across all
|
||||||
|
* architectures. This saves a reasonable amount of space for
|
||||||
|
* profiling data structures without (in practice) sacrificing
|
||||||
|
* any granularity.
|
||||||
|
*/
|
||||||
|
#define HASHFRACTION 2
|
||||||
|
|
||||||
|
/*
|
||||||
|
* percent of text space to allocate for tostructs with a minimum.
|
||||||
|
*/
|
||||||
|
#define ARCDENSITY 2
|
||||||
|
#define MINARCS 50
|
||||||
|
#define MAXARCS ((1 << (8 * sizeof(HISTCOUNTER))) - 2)
|
||||||
|
|
||||||
|
struct tostruct {
|
||||||
|
u_long selfpc;
|
||||||
|
long count;
|
||||||
|
u_short link;
|
||||||
|
u_short pad;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* a raw arc, with pointers to the calling site and
|
||||||
|
* the called site and a count.
|
||||||
|
*/
|
||||||
|
struct rawarc {
|
||||||
|
u_long raw_frompc;
|
||||||
|
u_long raw_selfpc;
|
||||||
|
long raw_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* general rounding functions.
|
||||||
|
*/
|
||||||
|
#define ROUNDDOWN(x,y) (((x)/(y))*(y))
|
||||||
|
#define ROUNDUP(x,y) ((((x)+(y)-1)/(y))*(y))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The profiling data structures are housed in this structure.
|
||||||
|
*/
|
||||||
|
struct gmonparam {
|
||||||
|
int state;
|
||||||
|
u_short *kcount;
|
||||||
|
u_long kcountsize;
|
||||||
|
u_short *froms;
|
||||||
|
u_long fromssize;
|
||||||
|
struct tostruct *tos;
|
||||||
|
u_long tossize;
|
||||||
|
long tolimit;
|
||||||
|
u_long lowpc;
|
||||||
|
u_long highpc;
|
||||||
|
u_long textsize;
|
||||||
|
u_long hashfraction;
|
||||||
|
};
|
||||||
|
extern struct gmonparam _gmonparam;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Possible states of profiling.
|
||||||
|
*/
|
||||||
|
#define GMON_PROF_ON 0
|
||||||
|
#define GMON_PROF_BUSY 1
|
||||||
|
#define GMON_PROF_ERROR 2
|
||||||
|
#define GMON_PROF_OFF 3
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sysctl definitions for extracting profiling information from the kernel.
|
||||||
|
*/
|
||||||
|
#define GPROF_STATE 0 /* int: profiling enabling variable */
|
||||||
|
#define GPROF_COUNT 1 /* struct: profile tick count buffer */
|
||||||
|
#define GPROF_FROMS 2 /* struct: from location hash bucket */
|
||||||
|
#define GPROF_TOS 3 /* struct: destination/count structure */
|
||||||
|
#define GPROF_GMONPARAM 4 /* struct: profiling parameters (see above) */
|
||||||
|
#endif /* !_SYS_GMONH_ */
|
283
winsup/cygwin/grp.cc
Normal file
283
winsup/cygwin/grp.cc
Normal file
@ -0,0 +1,283 @@
|
|||||||
|
/* grp.cc
|
||||||
|
|
||||||
|
Copyright 1996, 1997, 1998, 2000 Cygnus Solutions.
|
||||||
|
|
||||||
|
Original stubs by Jason Molenda of Cygnus Support, crash@cygnus.com
|
||||||
|
First implementation by Gunther Ebert, gunther.ebert@ixos-leipzig.de
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include <grp.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "winsup.h"
|
||||||
|
|
||||||
|
/* Read /etc/group only once for better performance. This is done
|
||||||
|
on the first call that needs information from it. */
|
||||||
|
|
||||||
|
#define MAX_DOMAIN_NAME 100
|
||||||
|
|
||||||
|
static NO_COPY const char *etc_group = "/etc/group";
|
||||||
|
static struct group *group_buf = NULL; /* group contents in memory */
|
||||||
|
static int curr_lines = 0;
|
||||||
|
static int max_lines = 0;
|
||||||
|
|
||||||
|
/* Position in the group cache */
|
||||||
|
#ifdef _MT_SAFE
|
||||||
|
#define grp_pos _reent_winsup()->_grp_pos
|
||||||
|
#else
|
||||||
|
static int grp_pos = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Set to 1 when /etc/group has been read in by read_etc_group (). */
|
||||||
|
/* Functions in this file need to check the value of group_in_memory_p
|
||||||
|
and read in the group file if it isn't set. */
|
||||||
|
/* FIXME: This should be static but this is called in uinfo_init outside
|
||||||
|
this file */
|
||||||
|
int group_in_memory_p = 0;
|
||||||
|
|
||||||
|
static int
|
||||||
|
parse_grp (struct group &grp, const char *line)
|
||||||
|
{
|
||||||
|
int len = strlen(line);
|
||||||
|
char *newline = (char *) malloc (len + 1);
|
||||||
|
(void) memcpy (newline, line, len + 1);
|
||||||
|
|
||||||
|
if (newline[--len] == '\n')
|
||||||
|
newline[len] = '\0';
|
||||||
|
|
||||||
|
char *dp = strchr (newline, ':');
|
||||||
|
|
||||||
|
if (!dp)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
*dp++ = '\0';
|
||||||
|
grp.gr_name = newline;
|
||||||
|
|
||||||
|
grp.gr_passwd = dp;
|
||||||
|
dp = strchr (grp.gr_passwd, ':');
|
||||||
|
if (dp)
|
||||||
|
{
|
||||||
|
*dp++ = '\0';
|
||||||
|
if (!strlen (grp.gr_passwd))
|
||||||
|
grp.gr_passwd = NULL;
|
||||||
|
|
||||||
|
grp.gr_gid = atoi (dp);
|
||||||
|
dp = strchr (dp, ':');
|
||||||
|
if (dp)
|
||||||
|
{
|
||||||
|
if (*++dp)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
for (cp = dp; (cp = strchr (cp, ',')) != NULL; ++cp)
|
||||||
|
++i;
|
||||||
|
char **namearray = (char **) calloc (i + 2, sizeof (char *));
|
||||||
|
if (namearray)
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
for (cp = dp; (cp = strchr (dp, ',')) != NULL; dp = cp + 1)
|
||||||
|
{
|
||||||
|
*cp = '\0';
|
||||||
|
namearray[i++] = dp;
|
||||||
|
}
|
||||||
|
namearray[i++] = dp;
|
||||||
|
namearray[i] = NULL;
|
||||||
|
}
|
||||||
|
grp.gr_mem = namearray;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
grp.gr_mem = NULL;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read one line from /etc/group into the group cache */
|
||||||
|
static void
|
||||||
|
add_grp_line (const char *line)
|
||||||
|
{
|
||||||
|
if (curr_lines == max_lines)
|
||||||
|
{
|
||||||
|
max_lines += 10;
|
||||||
|
group_buf = (struct group *) realloc (group_buf, max_lines * sizeof (struct group));
|
||||||
|
}
|
||||||
|
if (parse_grp (group_buf[curr_lines], line))
|
||||||
|
curr_lines++;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern PSID get_admin_sid ();
|
||||||
|
|
||||||
|
/* Cygwin internal */
|
||||||
|
/* Read in /etc/group and save contents in the group cache */
|
||||||
|
/* This sets group_in_memory_p to 1 so functions in this file can
|
||||||
|
tell that /etc/group has been read in */
|
||||||
|
/* FIXME: should be static but this is called in uinfo_init outside this
|
||||||
|
file */
|
||||||
|
void
|
||||||
|
read_etc_group ()
|
||||||
|
{
|
||||||
|
extern int group_sem;
|
||||||
|
char linebuf [ 200 ];
|
||||||
|
char group_name [ MAX_USER_NAME ];
|
||||||
|
DWORD group_name_len = MAX_USER_NAME;
|
||||||
|
|
||||||
|
strncpy (group_name, "Administrators", sizeof (group_name));
|
||||||
|
|
||||||
|
++group_sem;
|
||||||
|
FILE *f = fopen (etc_group, "r");
|
||||||
|
--group_sem;
|
||||||
|
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
while (fgets (linebuf, sizeof (linebuf), f) != NULL)
|
||||||
|
{
|
||||||
|
if (strlen (linebuf))
|
||||||
|
add_grp_line (linebuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose (f);
|
||||||
|
}
|
||||||
|
else /* /etc/group doesn't exist -- create default one in memory */
|
||||||
|
{
|
||||||
|
char domain_name [ MAX_DOMAIN_NAME ];
|
||||||
|
DWORD domain_name_len = MAX_DOMAIN_NAME;
|
||||||
|
SID_NAME_USE acType;
|
||||||
|
debug_printf ("Emulating /etc/group");
|
||||||
|
if (! LookupAccountSidA (NULL ,
|
||||||
|
get_admin_sid () ,
|
||||||
|
group_name,
|
||||||
|
&group_name_len,
|
||||||
|
domain_name,
|
||||||
|
&domain_name_len,
|
||||||
|
&acType))
|
||||||
|
{
|
||||||
|
strcpy (group_name, "unknown");
|
||||||
|
debug_printf ("Failed to get local admins group name. %E");
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf (linebuf, sizeof (linebuf), "%s::%u:\n", group_name, DEFAULT_GID);
|
||||||
|
add_grp_line (linebuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
group_in_memory_p = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
struct group *
|
||||||
|
getgrgid (gid_t gid)
|
||||||
|
{
|
||||||
|
struct group * default_grp = NULL;
|
||||||
|
if (!group_in_memory_p)
|
||||||
|
read_etc_group();
|
||||||
|
|
||||||
|
for (int i = 0; i < curr_lines; i++)
|
||||||
|
{
|
||||||
|
if (group_buf[i].gr_gid == DEFAULT_GID)
|
||||||
|
default_grp = group_buf + i;
|
||||||
|
if (group_buf[i].gr_gid == gid)
|
||||||
|
return group_buf + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return default_grp;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
struct group *
|
||||||
|
getgrnam (const char *name)
|
||||||
|
{
|
||||||
|
if (!group_in_memory_p)
|
||||||
|
read_etc_group();
|
||||||
|
|
||||||
|
for (int i = 0; i < curr_lines; i++)
|
||||||
|
if (strcasematch (group_buf[i].gr_name, name))
|
||||||
|
return group_buf + i;
|
||||||
|
|
||||||
|
/* Didn't find requested group */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
void
|
||||||
|
endgrent()
|
||||||
|
{
|
||||||
|
grp_pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
struct group *
|
||||||
|
getgrent()
|
||||||
|
{
|
||||||
|
if (!group_in_memory_p)
|
||||||
|
read_etc_group();
|
||||||
|
|
||||||
|
if (grp_pos < curr_lines)
|
||||||
|
return group_buf + grp_pos++;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
void
|
||||||
|
setgrent ()
|
||||||
|
{
|
||||||
|
grp_pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
getgroups (int gidsetsize, gid_t *grouplist, gid_t gid, const char *username)
|
||||||
|
{
|
||||||
|
if (!group_in_memory_p)
|
||||||
|
read_etc_group();
|
||||||
|
|
||||||
|
int cnt = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < curr_lines; ++i)
|
||||||
|
if (gid == group_buf[i].gr_gid)
|
||||||
|
{
|
||||||
|
if (cnt < gidsetsize)
|
||||||
|
grouplist[cnt] = group_buf[i].gr_gid;
|
||||||
|
++cnt;
|
||||||
|
if (gidsetsize && cnt >= gidsetsize)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
else if (group_buf[i].gr_mem)
|
||||||
|
for (int gi = 0; group_buf[i].gr_mem[gi]; ++gi)
|
||||||
|
if (! strcasecmp (username, group_buf[i].gr_mem[gi]))
|
||||||
|
{
|
||||||
|
if (cnt < gidsetsize)
|
||||||
|
grouplist[cnt] = group_buf[i].gr_gid;
|
||||||
|
++cnt;
|
||||||
|
if (gidsetsize && cnt >= gidsetsize)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int
|
||||||
|
getgroups (int gidsetsize, gid_t *grouplist)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
if (gidsetsize <= 0)
|
||||||
|
return 0;
|
||||||
|
grouplist[0] = myself->gid;
|
||||||
|
return 1;
|
||||||
|
#else
|
||||||
|
return getgroups (gidsetsize, grouplist, myself->gid, myself->username);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int
|
||||||
|
initgroups (const char *user, gid_t grp)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
140
winsup/cygwin/heap.cc
Normal file
140
winsup/cygwin/heap.cc
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
/* heap.cc: Cygwin heap manager.
|
||||||
|
|
||||||
|
Copyright 1996, 1997, 1998, 1999 Cygnus Solutions.
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include "winsup.h"
|
||||||
|
|
||||||
|
#define brksize ((char *) user_data->heaptop - (char *) user_data->heapbase)
|
||||||
|
#define brk (user_data->heapptr)
|
||||||
|
#define brkbase (user_data->heapbase)
|
||||||
|
#define brktop (user_data->heaptop)
|
||||||
|
#define brkchunk (cygwin_shared->heap_chunk_size ())
|
||||||
|
#define assert(x)
|
||||||
|
|
||||||
|
static unsigned page_const = 0;
|
||||||
|
|
||||||
|
static int __inline
|
||||||
|
getpagesize(void)
|
||||||
|
{
|
||||||
|
SYSTEM_INFO si;
|
||||||
|
GetSystemInfo(&si);
|
||||||
|
return (int)si.dwPageSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the heap at process start up. */
|
||||||
|
|
||||||
|
void
|
||||||
|
heap_init ()
|
||||||
|
{
|
||||||
|
/* If we're the forkee, we must allocate the heap at exactly the same place
|
||||||
|
as our parent. If not, we don't care where it ends up. */
|
||||||
|
|
||||||
|
page_const = getpagesize();
|
||||||
|
if (brkbase)
|
||||||
|
{
|
||||||
|
DWORD chunk = brkchunk; /* allocation chunk */
|
||||||
|
/* total size commited in parent */
|
||||||
|
DWORD allocsize = (char *) brktop - (char *) brkbase;
|
||||||
|
/* round up by chunk size */
|
||||||
|
DWORD reserve_size = chunk * ((allocsize + (chunk - 1)) / chunk);
|
||||||
|
|
||||||
|
/* Loop until we've managed to reserve an adequate amount of memory. */
|
||||||
|
char *p;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
p = (char *) VirtualAlloc (brkbase, reserve_size,
|
||||||
|
MEM_RESERVE, PAGE_READWRITE);
|
||||||
|
if (p)
|
||||||
|
break;
|
||||||
|
if ((reserve_size -= page_const) <= allocsize)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (p == NULL)
|
||||||
|
api_fatal ("1. unable to allocate heap, heap_chunk_size %d, pid %d, %E",
|
||||||
|
brkchunk, myself->pid);
|
||||||
|
if (p != brkbase)
|
||||||
|
api_fatal ("heap allocated but not at %p", brkbase);
|
||||||
|
if (! VirtualAlloc (brkbase, allocsize, MEM_COMMIT, PAGE_READWRITE))
|
||||||
|
api_fatal ("MEM_COMMIT failed, %E");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Initialize page mask and default heap size. Preallocate a heap
|
||||||
|
* to assure contiguous memory. */
|
||||||
|
brk = brktop = brkbase = VirtualAlloc(NULL, brkchunk, MEM_RESERVE, PAGE_NOACCESS);
|
||||||
|
if (brkbase == NULL)
|
||||||
|
api_fatal ("2. unable to allocate heap, heap_chunk_size %d, %E",
|
||||||
|
brkchunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
page_const--;
|
||||||
|
malloc_init ();
|
||||||
|
}
|
||||||
|
|
||||||
|
#define pround(n) (((size_t)(n) + page_const) & ~page_const)
|
||||||
|
|
||||||
|
/* FIXME: This function no longer handles "split heaps". */
|
||||||
|
|
||||||
|
extern "C" void *
|
||||||
|
_sbrk(int n)
|
||||||
|
{
|
||||||
|
char *newtop, *newbrk;
|
||||||
|
unsigned commitbytes, newbrksize;
|
||||||
|
|
||||||
|
if (n == 0)
|
||||||
|
return brk; /* Just wanted to find current brk address */
|
||||||
|
|
||||||
|
newbrk = (char *) brk + n; /* Where new brk will be */
|
||||||
|
newtop = (char *) pround (newbrk); /* Actual top of allocated memory -
|
||||||
|
on page boundary */
|
||||||
|
|
||||||
|
if (newtop == brktop)
|
||||||
|
goto good;
|
||||||
|
|
||||||
|
if (n < 0)
|
||||||
|
{ /* Freeing memory */
|
||||||
|
assert(newtop < brktop);
|
||||||
|
n = (char *) brktop - newtop;
|
||||||
|
if (VirtualFree(newtop, n, MEM_DECOMMIT)) /* Give it back to OS */
|
||||||
|
goto good; /* Didn't take */
|
||||||
|
else
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(newtop > brktop);
|
||||||
|
|
||||||
|
/* Need to grab more pages from the OS. If this fails it may be because
|
||||||
|
* we have used up previously reserved memory. Or, we're just plumb out
|
||||||
|
* of memory. */
|
||||||
|
commitbytes = pround (newtop - (char *) brktop);
|
||||||
|
if (VirtualAlloc(brktop, commitbytes, MEM_COMMIT, PAGE_READWRITE) != NULL)
|
||||||
|
goto good;
|
||||||
|
|
||||||
|
/* Couldn't allocate memory. Maybe we can reserve some more.
|
||||||
|
Reserve either the maximum of the standard brkchunk or the requested
|
||||||
|
amount. Then attempt to actually allocate it. */
|
||||||
|
|
||||||
|
if ((newbrksize = brkchunk) < commitbytes)
|
||||||
|
newbrksize = commitbytes;
|
||||||
|
|
||||||
|
if ((VirtualAlloc(brktop, newbrksize, MEM_RESERVE, PAGE_NOACCESS) != NULL) &&
|
||||||
|
(VirtualAlloc(brktop, commitbytes, MEM_COMMIT, PAGE_READWRITE) != NULL))
|
||||||
|
goto good;
|
||||||
|
|
||||||
|
err:
|
||||||
|
set_errno (ENOMEM);
|
||||||
|
return (void *) -1;
|
||||||
|
|
||||||
|
good:
|
||||||
|
void *oldbrk = brk;
|
||||||
|
brk = newbrk;
|
||||||
|
brktop = newtop;
|
||||||
|
return oldbrk;
|
||||||
|
}
|
421
winsup/cygwin/include/a.out.h
Normal file
421
winsup/cygwin/include/a.out.h
Normal file
@ -0,0 +1,421 @@
|
|||||||
|
#ifndef _A_OUT_H_
|
||||||
|
#define _A_OUT_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
#define COFF_IMAGE_WITH_PE
|
||||||
|
#define COFF_LONG_SECTION_NAMES
|
||||||
|
|
||||||
|
/*** coff information for Intel 386/486. */
|
||||||
|
|
||||||
|
|
||||||
|
/********************** FILE HEADER **********************/
|
||||||
|
|
||||||
|
struct external_filehdr {
|
||||||
|
short f_magic; /* magic number */
|
||||||
|
short f_nscns; /* number of sections */
|
||||||
|
unsigned long f_timdat; /* time & date stamp */
|
||||||
|
unsigned long f_symptr; /* file pointer to symtab */
|
||||||
|
unsigned long f_nsyms; /* number of symtab entries */
|
||||||
|
short f_opthdr; /* sizeof(optional hdr) */
|
||||||
|
short f_flags; /* flags */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Bits for f_flags:
|
||||||
|
* F_RELFLG relocation info stripped from file
|
||||||
|
* F_EXEC file is executable (no unresolved external references)
|
||||||
|
* F_LNNO line numbers stripped from file
|
||||||
|
* F_LSYMS local symbols stripped from file
|
||||||
|
* F_AR32WR file has byte ordering of an AR32WR machine (e.g. vax)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define F_RELFLG (0x0001)
|
||||||
|
#define F_EXEC (0x0002)
|
||||||
|
#define F_LNNO (0x0004)
|
||||||
|
#define F_LSYMS (0x0008)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define I386MAGIC 0x14c
|
||||||
|
#define I386PTXMAGIC 0x154
|
||||||
|
#define I386AIXMAGIC 0x175
|
||||||
|
|
||||||
|
/* This is Lynx's all-platform magic number for executables. */
|
||||||
|
|
||||||
|
#define LYNXCOFFMAGIC 0415
|
||||||
|
|
||||||
|
#define I386BADMAG(x) (((x).f_magic != I386MAGIC) \
|
||||||
|
&& (x).f_magic != I386AIXMAGIC \
|
||||||
|
&& (x).f_magic != I386PTXMAGIC \
|
||||||
|
&& (x).f_magic != LYNXCOFFMAGIC)
|
||||||
|
|
||||||
|
#define FILHDR struct external_filehdr
|
||||||
|
#define FILHSZ 20
|
||||||
|
|
||||||
|
|
||||||
|
/********************** AOUT "OPTIONAL HEADER"=
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned short magic; /* type of file */
|
||||||
|
unsigned short vstamp; /* version stamp */
|
||||||
|
unsigned long tsize; /* text size in bytes, padded to FW bdry*/
|
||||||
|
unsigned long dsize; /* initialized data " " */
|
||||||
|
unsigned long bsize; /* uninitialized data " " */
|
||||||
|
unsigned long entry; /* entry pt. */
|
||||||
|
unsigned long text_start; /* base of text used for this file */
|
||||||
|
unsigned long data_start; /* base of data used for this file=
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
AOUTHDR;
|
||||||
|
|
||||||
|
#define AOUTSZ 28
|
||||||
|
#define AOUTHDRSZ 28
|
||||||
|
|
||||||
|
#define OMAGIC 0404 /* object files, eg as output */
|
||||||
|
#define ZMAGIC 0413 /* demand load format, eg normal ld output */
|
||||||
|
#define STMAGIC 0401 /* target shlib */
|
||||||
|
#define SHMAGIC 0443 /* host shlib */
|
||||||
|
|
||||||
|
|
||||||
|
/* define some NT default values */
|
||||||
|
/* #define NT_IMAGE_BASE 0x400000 moved to internal.h */
|
||||||
|
#define NT_SECTION_ALIGNMENT 0x1000
|
||||||
|
#define NT_FILE_ALIGNMENT 0x200
|
||||||
|
#define NT_DEF_RESERVE 0x100000
|
||||||
|
#define NT_DEF_COMMIT 0x1000
|
||||||
|
|
||||||
|
/********************** SECTION HEADER **********************/
|
||||||
|
|
||||||
|
|
||||||
|
struct external_scnhdr {
|
||||||
|
char s_name[8]; /* section name */
|
||||||
|
unsigned long s_paddr; /* physical address, offset
|
||||||
|
of last addr in scn */
|
||||||
|
unsigned long s_vaddr; /* virtual address */
|
||||||
|
unsigned long s_size; /* section size */
|
||||||
|
unsigned long s_scnptr; /* file ptr to raw data for section */
|
||||||
|
unsigned long s_relptr; /* file ptr to relocation */
|
||||||
|
unsigned long s_lnnoptr; /* file ptr to line numbers */
|
||||||
|
unsigned short s_nreloc; /* number of relocation entries */
|
||||||
|
unsigned short s_nlnno; /* number of line number entries*/
|
||||||
|
unsigned long s_flags; /* flags */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SCNHDR struct external_scnhdr
|
||||||
|
#define SCNHSZ 40
|
||||||
|
|
||||||
|
/*
|
||||||
|
* names of "special" sections
|
||||||
|
*/
|
||||||
|
#define _TEXT ".text"
|
||||||
|
#define _DATA ".data"
|
||||||
|
#define _BSS ".bss"
|
||||||
|
#define _COMMENT ".comment"
|
||||||
|
#define _LIB ".lib"
|
||||||
|
|
||||||
|
/********************** LINE NUMBERS **********************/
|
||||||
|
|
||||||
|
/* 1 line number entry for every "breakpointable" source line in a section.
|
||||||
|
* Line numbers are grouped on a per function basis; first entry in a function
|
||||||
|
* grouping will have l_lnno = 0 and in place of physical address will be the
|
||||||
|
* symbol table index of the function name.
|
||||||
|
*/
|
||||||
|
struct external_lineno {
|
||||||
|
union {
|
||||||
|
unsigned long l_symndx; /* function name symbol index, iff l_lnno 0 */
|
||||||
|
unsigned long l_paddr; /* (physical) address of line number */
|
||||||
|
} l_addr;
|
||||||
|
unsigned short l_lnno; /* line number */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LINENO struct external_lineno
|
||||||
|
#define LINESZ 6
|
||||||
|
|
||||||
|
/********************** SYMBOLS **********************/
|
||||||
|
|
||||||
|
#define E_SYMNMLEN 8 /* # characters in a symbol name */
|
||||||
|
#define E_FILNMLEN 14 /* # characters in a file name */
|
||||||
|
#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
|
||||||
|
|
||||||
|
struct external_syment
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
char e_name[E_SYMNMLEN];
|
||||||
|
struct {
|
||||||
|
unsigned long e_zeroes;
|
||||||
|
unsigned long e_offset;
|
||||||
|
} e;
|
||||||
|
} e;
|
||||||
|
unsigned long e_value;
|
||||||
|
unsigned short e_scnum;
|
||||||
|
unsigned short e_type;
|
||||||
|
char e_sclass[1];
|
||||||
|
char e_numaux[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
#define N_BTMASK (0xf)
|
||||||
|
#define N_TMASK (0x30)
|
||||||
|
#define N_BTSHFT (4)
|
||||||
|
#define N_TSHIFT (2)
|
||||||
|
|
||||||
|
union external_auxent {
|
||||||
|
struct {
|
||||||
|
unsigned long x_tagndx; /* str, un, or enum tag indx */
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
unsigned short x_lnno; /* declaration line number */
|
||||||
|
unsigned short x_size; /* str/union/array size */
|
||||||
|
} x_lnsz;
|
||||||
|
unsigned long x_fsize; /* size of function */
|
||||||
|
} x_misc;
|
||||||
|
union {
|
||||||
|
struct { /* if ISFCN, tag, or .bb */
|
||||||
|
unsigned long x_lnnoptr;/* ptr to fcn line # */
|
||||||
|
unsigned long x_endndx; /* entry ndx past block end */
|
||||||
|
} x_fcn;
|
||||||
|
struct { /* if ISARY, up to 4 dimen. */
|
||||||
|
char x_dimen[E_DIMNUM][2];
|
||||||
|
} x_ary;
|
||||||
|
} x_fcnary;
|
||||||
|
unsigned short x_tvndx; /* tv index */
|
||||||
|
} x_sym;
|
||||||
|
|
||||||
|
union {
|
||||||
|
char x_fname[E_FILNMLEN];
|
||||||
|
struct {
|
||||||
|
unsigned long x_zeroes;
|
||||||
|
unsigned long x_offset;
|
||||||
|
} x_n;
|
||||||
|
} x_file;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
unsigned long x_scnlen; /* section length */
|
||||||
|
unsigned short x_nreloc; /* # relocation entries */
|
||||||
|
unsigned short x_nlinno; /* # line numbers */
|
||||||
|
unsigned long x_checksum; /* section COMDAT checksum */
|
||||||
|
unsigned short x_associated;/* COMDAT associated section index */
|
||||||
|
char x_comdat[1]; /* COMDAT selection number */
|
||||||
|
} x_scn;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
unsigned long x_tvfill; /* tv fill value */
|
||||||
|
unsigned short x_tvlen; /* length of .tv */
|
||||||
|
char x_tvran[2][2]; /* tv range */
|
||||||
|
} x_tv; /* info about .tv section (in auxent of symbol .tv)) */
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SYMENT struct external_syment
|
||||||
|
#define SYMESZ 18
|
||||||
|
#define AUXENT union external_auxent
|
||||||
|
#define AUXESZ 18
|
||||||
|
|
||||||
|
#define _ETEXT "etext"
|
||||||
|
|
||||||
|
/********************** RELOCATION DIRECTIVES **********************/
|
||||||
|
|
||||||
|
struct external_reloc {
|
||||||
|
char r_vaddr[4];
|
||||||
|
char r_symndx[4];
|
||||||
|
char r_type[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
#define RELOC struct external_reloc
|
||||||
|
#define RELSZ 10
|
||||||
|
|
||||||
|
/* end of coff/i386.h */
|
||||||
|
|
||||||
|
/* PE COFF header information */
|
||||||
|
|
||||||
|
#ifndef _PE_H
|
||||||
|
#define _PE_H
|
||||||
|
|
||||||
|
/* NT specific file attributes */
|
||||||
|
#define IMAGE_FILE_RELOCS_STRIPPED 0x0001
|
||||||
|
#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
|
||||||
|
#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004
|
||||||
|
#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008
|
||||||
|
#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080
|
||||||
|
#define IMAGE_FILE_32BIT_MACHINE 0x0100
|
||||||
|
#define IMAGE_FILE_DEBUG_STRIPPED 0x0200
|
||||||
|
#define IMAGE_FILE_SYSTEM 0x1000
|
||||||
|
#define IMAGE_FILE_DLL 0x2000
|
||||||
|
#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
|
||||||
|
|
||||||
|
/* additional flags to be set for section headers to allow the NT loader to
|
||||||
|
read and write to the section data (to replace the addresses of data in
|
||||||
|
dlls for one thing); also to execute the section in .text's case=
|
||||||
|
*/
|
||||||
|
#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
|
||||||
|
#define IMAGE_SCN_MEM_EXECUTE 0x20000000
|
||||||
|
#define IMAGE_SCN_MEM_READ 0x40000000
|
||||||
|
#define IMAGE_SCN_MEM_WRITE 0x80000000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Section characteristics added for ppc-nt
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* Reserved. */
|
||||||
|
|
||||||
|
#define IMAGE_SCN_CNT_CODE 0x00000020 /* Section contains code. */
|
||||||
|
#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* Section contains initialized data. */
|
||||||
|
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 /* Section contains uninitialized data. */
|
||||||
|
|
||||||
|
#define IMAGE_SCN_LNK_OTHER 0x00000100 /* Reserved. */
|
||||||
|
#define IMAGE_SCN_LNK_INFO 0x00000200 /* Section contains comments or some other type of information. */
|
||||||
|
#define IMAGE_SCN_LNK_REMOVE 0x00000800 /* Section contents will not become part of image. */
|
||||||
|
#define IMAGE_SCN_LNK_COMDAT 0x00001000 /* Section contents comdat. */
|
||||||
|
|
||||||
|
#define IMAGE_SCN_MEM_FARDATA 0x00008000
|
||||||
|
|
||||||
|
#define IMAGE_SCN_MEM_PURGEABLE 0x00020000
|
||||||
|
#define IMAGE_SCN_MEM_16BIT 0x00020000
|
||||||
|
#define IMAGE_SCN_MEM_LOCKED 0x00040000
|
||||||
|
#define IMAGE_SCN_MEM_PRELOAD 0x00080000
|
||||||
|
|
||||||
|
#define IMAGE_SCN_ALIGN_1BYTES 0x00100000
|
||||||
|
#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
|
||||||
|
#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
|
||||||
|
#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
|
||||||
|
#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 /* Default alignment if no others are specified. */
|
||||||
|
#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
|
||||||
|
#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
|
||||||
|
|
||||||
|
|
||||||
|
#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 /* Section contains extended relocations. */
|
||||||
|
#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 /* Section is not cachable. */
|
||||||
|
#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 /* Section is not pageable. */
|
||||||
|
#define IMAGE_SCN_MEM_SHARED 0x10000000 /* Section is shareable. */
|
||||||
|
|
||||||
|
/* COMDAT selection codes. */
|
||||||
|
|
||||||
|
#define IMAGE_COMDAT_SELECT_NODUPLICATES (1) /* Warn if duplicates. */
|
||||||
|
#define IMAGE_COMDAT_SELECT_ANY (2) /* No warning. */
|
||||||
|
#define IMAGE_COMDAT_SELECT_SAME_SIZE (3) /* Warn if different size. */
|
||||||
|
#define IMAGE_COMDAT_SELECT_EXACT_MATCH (4) /* Warn if different. */
|
||||||
|
#define IMAGE_COMDAT_SELECT_ASSOCIATIVE (5) /* Base on other section. */
|
||||||
|
|
||||||
|
/* Magic values that are true for all dos/nt implementations */
|
||||||
|
#define DOSMAGIC 0x5a4d
|
||||||
|
#define NT_SIGNATURE 0x00004550
|
||||||
|
|
||||||
|
/* NT allows long filenames, we want to accommodate this. This may break
|
||||||
|
some of the bfd functions */
|
||||||
|
#undef FILNMLEN
|
||||||
|
#define FILNMLEN 18 /* # characters in a file name */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef COFF_IMAGE_WITH_PE
|
||||||
|
/* The filehdr is only weired in images */
|
||||||
|
|
||||||
|
#undef FILHDR
|
||||||
|
struct external_PE_filehdr
|
||||||
|
{
|
||||||
|
/* DOS header fields */
|
||||||
|
unsigned short e_magic; /* Magic number, 0x5a4d */
|
||||||
|
unsigned short e_cblp; /* Bytes on last page of file, 0x90 */
|
||||||
|
unsigned short e_cp; /* Pages in file, 0x3 */
|
||||||
|
unsigned short e_crlc; /* Relocations, 0x0 */
|
||||||
|
unsigned short e_cparhdr; /* Size of header in paragraphs, 0x4 */
|
||||||
|
unsigned short e_minalloc; /* Minimum extra paragraphs needed, 0x0 */
|
||||||
|
unsigned short e_maxalloc; /* Maximum extra paragraphs needed, 0xFFFF */
|
||||||
|
unsigned short e_ss; /* Initial (relative) SS value, 0x0 */
|
||||||
|
unsigned short e_sp; /* Initial SP value, 0xb8 */
|
||||||
|
unsigned short e_csum; /* Checksum, 0x0 */
|
||||||
|
unsigned short e_ip; /* Initial IP value, 0x0 */
|
||||||
|
unsigned short e_cs; /* Initial (relative) CS value, 0x0 */
|
||||||
|
unsigned short e_lfarlc; /* File address of relocation table, 0x40 */
|
||||||
|
unsigned short e_ovno; /* Overlay number, 0x0 */
|
||||||
|
char e_res[4][2]; /* Reserved words, all 0x0 */
|
||||||
|
unsigned short e_oemid; /* OEM identifier (for e_oeminfo), 0x0 */
|
||||||
|
unsigned short e_oeminfo; /* OEM information; e_oemid specific, 0x0 */
|
||||||
|
char e_res2[10][2]; /* Reserved words, all 0x0 */
|
||||||
|
unsigned long e_lfanew; /* File address of new exe header, 0x80 */
|
||||||
|
char dos_message[16][4]; /* other stuff, always follow DOS header */
|
||||||
|
unsigned int nt_signature; /* required NT signature, 0x4550 */
|
||||||
|
|
||||||
|
/* From standard header */
|
||||||
|
|
||||||
|
unsigned short f_magic; /* magic number */
|
||||||
|
unsigned short f_nscns; /* number of sections */
|
||||||
|
unsigned long f_timdat; /* time & date stamp */
|
||||||
|
unsigned long f_symptr; /* file pointer to symtab */
|
||||||
|
unsigned long f_nsyms; /* number of symtab entries */
|
||||||
|
unsigned short f_opthdr; /* sizeof(optional hdr) */
|
||||||
|
unsigned short f_flags; /* flags */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define FILHDR struct external_PE_filehdr
|
||||||
|
#undef FILHSZ
|
||||||
|
#define FILHSZ 152
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned short magic; /* type of file */
|
||||||
|
unsigned short vstamp; /* version stamp */
|
||||||
|
unsigned long tsize; /* text size in bytes, padded to FW bdry*/
|
||||||
|
unsigned long dsize; /* initialized data " " */
|
||||||
|
unsigned long bsize; /* uninitialized data " " */
|
||||||
|
unsigned long entry; /* entry pt. */
|
||||||
|
unsigned long text_start; /* base of text used for this file */
|
||||||
|
unsigned long data_start; /* base of all data used for this file */
|
||||||
|
|
||||||
|
/* NT extra fields; see internal.h for descriptions */
|
||||||
|
unsigned long ImageBase;
|
||||||
|
unsigned long SectionAlignment;
|
||||||
|
unsigned long FileAlignment;
|
||||||
|
unsigned short MajorOperatingSystemVersion;
|
||||||
|
unsigned short MinorOperatingSystemVersion;
|
||||||
|
unsigned short MajorImageVersion;
|
||||||
|
unsigned short MinorImageVersion;
|
||||||
|
unsigned short MajorSubsystemVersion;
|
||||||
|
unsigned short MinorSubsystemVersion;
|
||||||
|
char Reserved1[4];
|
||||||
|
unsigned long SizeOfImage;
|
||||||
|
unsigned long SizeOfHeaders;
|
||||||
|
unsigned long CheckSum;
|
||||||
|
unsigned short Subsystem;
|
||||||
|
unsigned short DllCharacteristics;
|
||||||
|
unsigned long SizeOfStackReserve;
|
||||||
|
unsigned long SizeOfStackCommit;
|
||||||
|
unsigned long SizeOfHeapReserve;
|
||||||
|
unsigned long SizeOfHeapCommit;
|
||||||
|
unsigned long LoaderFlags;
|
||||||
|
unsigned long NumberOfRvaAndSizes;
|
||||||
|
/* IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; */
|
||||||
|
char DataDirectory[16][2][4]; /* 16 entries, 2 elements/entry, 4 chars */
|
||||||
|
|
||||||
|
} PEAOUTHDR;
|
||||||
|
|
||||||
|
|
||||||
|
#undef AOUTSZ
|
||||||
|
#define AOUTSZ (AOUTHDRSZ + 196)
|
||||||
|
|
||||||
|
#undef E_FILNMLEN
|
||||||
|
#define E_FILNMLEN 18 /* # characters in a file name */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* end of coff/pe.h */
|
||||||
|
|
||||||
|
#define DT_NON (0) /* no derived type */
|
||||||
|
#define DT_PTR (1) /* pointer */
|
||||||
|
#define DT_FCN (2) /* function */
|
||||||
|
#define DT_ARY (3) /* array */
|
||||||
|
|
||||||
|
#define ISPTR(x) (((x) & N_TMASK) == (DT_PTR << N_BTSHFT))
|
||||||
|
#define ISFCN(x) (((x) & N_TMASK) == (DT_FCN << N_BTSHFT))
|
||||||
|
#define ISARY(x) (((x) & N_TMASK) == (DT_ARY << N_BTSHFT))
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _A_OUT_H_ */
|
||||||
|
|
109
winsup/cygwin/include/arpa/ftp.h
Normal file
109
winsup/cygwin/include/arpa/ftp.h
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1983, 1989, 1993
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @(#)ftp.h 8.1 (Berkeley) 6/2/93
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ARPA_FTP_H
|
||||||
|
#define _ARPA_FTP_H
|
||||||
|
|
||||||
|
/* Definitions for FTP; see RFC-765. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reply codes.
|
||||||
|
*/
|
||||||
|
#define PRELIM 1 /* positive preliminary */
|
||||||
|
#define COMPLETE 2 /* positive completion */
|
||||||
|
#define CONTINUE 3 /* positive intermediate */
|
||||||
|
#define TRANSIENT 4 /* transient negative completion */
|
||||||
|
#define ERROR 5 /* permanent negative completion */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Type codes
|
||||||
|
*/
|
||||||
|
#define TYPE_A 1 /* ASCII */
|
||||||
|
#define TYPE_E 2 /* EBCDIC */
|
||||||
|
#define TYPE_I 3 /* image */
|
||||||
|
#define TYPE_L 4 /* local byte size */
|
||||||
|
|
||||||
|
#ifdef FTP_NAMES
|
||||||
|
char *typenames[] = {"0", "ASCII", "EBCDIC", "Image", "Local" };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Form codes
|
||||||
|
*/
|
||||||
|
#define FORM_N 1 /* non-print */
|
||||||
|
#define FORM_T 2 /* telnet format effectors */
|
||||||
|
#define FORM_C 3 /* carriage control (ASA) */
|
||||||
|
#ifdef FTP_NAMES
|
||||||
|
char *formnames[] = {"0", "Nonprint", "Telnet", "Carriage-control" };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure codes
|
||||||
|
*/
|
||||||
|
#define STRU_F 1 /* file (no record structure) */
|
||||||
|
#define STRU_R 2 /* record structure */
|
||||||
|
#define STRU_P 3 /* page structure */
|
||||||
|
#ifdef FTP_NAMES
|
||||||
|
char *strunames[] = {"0", "File", "Record", "Page" };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mode types
|
||||||
|
*/
|
||||||
|
#define MODE_S 1 /* stream */
|
||||||
|
#define MODE_B 2 /* block */
|
||||||
|
#define MODE_C 3 /* compressed */
|
||||||
|
#ifdef FTP_NAMES
|
||||||
|
char *modenames[] = {"0", "Stream", "Block", "Compressed" };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Record Tokens
|
||||||
|
*/
|
||||||
|
#define REC_ESC '\377' /* Record-mode Escape */
|
||||||
|
#define REC_EOR '\001' /* Record-mode End-of-Record */
|
||||||
|
#define REC_EOF '\002' /* Record-mode End-of-File */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Block Header
|
||||||
|
*/
|
||||||
|
#define BLK_EOR 0x80 /* Block is End-of-Record */
|
||||||
|
#define BLK_EOF 0x40 /* Block is End-of-File */
|
||||||
|
#define BLK_ERRORS 0x20 /* Block is suspected of containing errors */
|
||||||
|
#define BLK_RESTART 0x10 /* Block is Restart Marker */
|
||||||
|
|
||||||
|
#define BLK_BYTECOUNT 2 /* Bytes in this block */
|
||||||
|
|
||||||
|
#endif /* !_ARPA_FTP_H */
|
25
winsup/cygwin/include/arpa/inet.h
Normal file
25
winsup/cygwin/include/arpa/inet.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef _ARPA_INET_H
|
||||||
|
#define _ARPA_INET_H
|
||||||
|
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __INSIDE_CYGWIN_NET__
|
||||||
|
unsigned long inet_addr (const char *);
|
||||||
|
int inet_aton (const char *, struct in_addr *);
|
||||||
|
unsigned long inet_lnaof (struct in_addr);
|
||||||
|
struct in_addr inet_makeaddr (unsigned long , unsigned long);
|
||||||
|
unsigned int inet_netof (struct in_addr);
|
||||||
|
unsigned int inet_network (const char *);
|
||||||
|
char *inet_ntoa (struct in_addr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _ARPA_INET_H */
|
322
winsup/cygwin/include/arpa/telnet.h
Normal file
322
winsup/cygwin/include/arpa/telnet.h
Normal file
@ -0,0 +1,322 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1983, 1993
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @(#)telnet.h 8.2 (Berkeley) 12/15/93
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ARPA_TELNET_H
|
||||||
|
#define _ARPA_TELNET_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Definitions for the TELNET protocol.
|
||||||
|
*/
|
||||||
|
#define IAC 255 /* interpret as command: */
|
||||||
|
#define DONT 254 /* you are not to use option */
|
||||||
|
#define DO 253 /* please, you use option */
|
||||||
|
#define WONT 252 /* I won't use option */
|
||||||
|
#define WILL 251 /* I will use option */
|
||||||
|
#define SB 250 /* interpret as subnegotiation */
|
||||||
|
#define GA 249 /* you may reverse the line */
|
||||||
|
#define EL 248 /* erase the current line */
|
||||||
|
#define EC 247 /* erase the current character */
|
||||||
|
#define AYT 246 /* are you there */
|
||||||
|
#define AO 245 /* abort output--but let prog finish */
|
||||||
|
#define IP 244 /* interrupt process--permanently */
|
||||||
|
#define BREAK 243 /* break */
|
||||||
|
#define DM 242 /* data mark--for connect. cleaning */
|
||||||
|
#define NOP 241 /* nop */
|
||||||
|
#define SE 240 /* end sub negotiation */
|
||||||
|
#define EOR 239 /* end of record (transparent mode) */
|
||||||
|
#define ABORT 238 /* Abort process */
|
||||||
|
#define SUSP 237 /* Suspend process */
|
||||||
|
#define xEOF 236 /* End of file: EOF is already used... */
|
||||||
|
|
||||||
|
#define SYNCH 242 /* for telfunc calls */
|
||||||
|
|
||||||
|
#ifdef TELCMDS
|
||||||
|
char *telcmds[] = {
|
||||||
|
"EOF", "SUSP", "ABORT", "EOR",
|
||||||
|
"SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC",
|
||||||
|
"EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0,
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
extern char *telcmds[];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TELCMD_FIRST xEOF
|
||||||
|
#define TELCMD_LAST IAC
|
||||||
|
#define TELCMD_OK(x) ((unsigned int)(x) <= TELCMD_LAST && \
|
||||||
|
(unsigned int)(x) >= TELCMD_FIRST)
|
||||||
|
#define TELCMD(x) telcmds[(x)-TELCMD_FIRST]
|
||||||
|
|
||||||
|
/* telnet options */
|
||||||
|
#define TELOPT_BINARY 0 /* 8-bit data path */
|
||||||
|
#define TELOPT_ECHO 1 /* echo */
|
||||||
|
#define TELOPT_RCP 2 /* prepare to reconnect */
|
||||||
|
#define TELOPT_SGA 3 /* suppress go ahead */
|
||||||
|
#define TELOPT_NAMS 4 /* approximate message size */
|
||||||
|
#define TELOPT_STATUS 5 /* give status */
|
||||||
|
#define TELOPT_TM 6 /* timing mark */
|
||||||
|
#define TELOPT_RCTE 7 /* remote controlled transmission and echo */
|
||||||
|
#define TELOPT_NAOL 8 /* negotiate about output line width */
|
||||||
|
#define TELOPT_NAOP 9 /* negotiate about output page size */
|
||||||
|
#define TELOPT_NAOCRD 10 /* negotiate about CR disposition */
|
||||||
|
#define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */
|
||||||
|
#define TELOPT_NAOHTD 12 /* negotiate about horizontal tab disposition */
|
||||||
|
#define TELOPT_NAOFFD 13 /* negotiate about formfeed disposition */
|
||||||
|
#define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */
|
||||||
|
#define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */
|
||||||
|
#define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */
|
||||||
|
#define TELOPT_XASCII 17 /* extended ascic character set */
|
||||||
|
#define TELOPT_LOGOUT 18 /* force logout */
|
||||||
|
#define TELOPT_BM 19 /* byte macro */
|
||||||
|
#define TELOPT_DET 20 /* data entry terminal */
|
||||||
|
#define TELOPT_SUPDUP 21 /* supdup protocol */
|
||||||
|
#define TELOPT_SUPDUPOUTPUT 22 /* supdup output */
|
||||||
|
#define TELOPT_SNDLOC 23 /* send location */
|
||||||
|
#define TELOPT_TTYPE 24 /* terminal type */
|
||||||
|
#define TELOPT_EOR 25 /* end or record */
|
||||||
|
#define TELOPT_TUID 26 /* TACACS user identification */
|
||||||
|
#define TELOPT_OUTMRK 27 /* output marking */
|
||||||
|
#define TELOPT_TTYLOC 28 /* terminal location number */
|
||||||
|
#define TELOPT_3270REGIME 29 /* 3270 regime */
|
||||||
|
#define TELOPT_X3PAD 30 /* X.3 PAD */
|
||||||
|
#define TELOPT_NAWS 31 /* window size */
|
||||||
|
#define TELOPT_TSPEED 32 /* terminal speed */
|
||||||
|
#define TELOPT_LFLOW 33 /* remote flow control */
|
||||||
|
#define TELOPT_LINEMODE 34 /* Linemode option */
|
||||||
|
#define TELOPT_XDISPLOC 35 /* X Display Location */
|
||||||
|
#define TELOPT_OLD_ENVIRON 36 /* Old - Environment variables */
|
||||||
|
#define TELOPT_AUTHENTICATION 37/* Authenticate */
|
||||||
|
#define TELOPT_ENCRYPT 38 /* Encryption option */
|
||||||
|
#define TELOPT_NEW_ENVIRON 39 /* New - Environment variables */
|
||||||
|
#define TELOPT_EXOPL 255 /* extended-options-list */
|
||||||
|
#define TELOPT_ENVIRON TELOPT_OLD_ENVIRON
|
||||||
|
|
||||||
|
#define NTELOPTS (1+TELOPT_NEW_ENVIRON)
|
||||||
|
#ifdef TELOPTS
|
||||||
|
char *telopts[NTELOPTS+1] = {
|
||||||
|
"BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME",
|
||||||
|
"STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP",
|
||||||
|
"NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS",
|
||||||
|
"NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
|
||||||
|
"DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT",
|
||||||
|
"SEND LOCATION", "TERMINAL TYPE", "END OF RECORD",
|
||||||
|
"TACACS UID", "OUTPUT MARKING", "TTYLOC",
|
||||||
|
"3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW",
|
||||||
|
"LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION",
|
||||||
|
"ENCRYPT", "NEW-ENVIRON",
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
#define TELOPT_FIRST TELOPT_BINARY
|
||||||
|
#define TELOPT_LAST TELOPT_NEW_ENVIRON
|
||||||
|
#define TELOPT_OK(x) ((unsigned int)(x) <= TELOPT_LAST)
|
||||||
|
#define TELOPT(x) telopts[(x)-TELOPT_FIRST]
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* sub-option qualifiers */
|
||||||
|
#define TELQUAL_IS 0 /* option is... */
|
||||||
|
#define TELQUAL_SEND 1 /* send option */
|
||||||
|
#define TELQUAL_INFO 2 /* ENVIRON: informational version of IS */
|
||||||
|
#define TELQUAL_REPLY 2 /* AUTHENTICATION: client version of IS */
|
||||||
|
#define TELQUAL_NAME 3 /* AUTHENTICATION: client version of IS */
|
||||||
|
|
||||||
|
#define LFLOW_OFF 0 /* Disable remote flow control */
|
||||||
|
#define LFLOW_ON 1 /* Enable remote flow control */
|
||||||
|
#define LFLOW_RESTART_ANY 2 /* Restart output on any char */
|
||||||
|
#define LFLOW_RESTART_XON 3 /* Restart output only on XON */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LINEMODE suboptions
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LM_MODE 1
|
||||||
|
#define LM_FORWARDMASK 2
|
||||||
|
#define LM_SLC 3
|
||||||
|
|
||||||
|
#define MODE_EDIT 0x01
|
||||||
|
#define MODE_TRAPSIG 0x02
|
||||||
|
#define MODE_ACK 0x04
|
||||||
|
#define MODE_SOFT_TAB 0x08
|
||||||
|
#define MODE_LIT_ECHO 0x10
|
||||||
|
|
||||||
|
#define MODE_MASK 0x1f
|
||||||
|
|
||||||
|
/* Not part of protocol, but needed to simplify things... */
|
||||||
|
#define MODE_FLOW 0x0100
|
||||||
|
#define MODE_ECHO 0x0200
|
||||||
|
#define MODE_INBIN 0x0400
|
||||||
|
#define MODE_OUTBIN 0x0800
|
||||||
|
#define MODE_FORCE 0x1000
|
||||||
|
|
||||||
|
#define SLC_SYNCH 1
|
||||||
|
#define SLC_BRK 2
|
||||||
|
#define SLC_IP 3
|
||||||
|
#define SLC_AO 4
|
||||||
|
#define SLC_AYT 5
|
||||||
|
#define SLC_EOR 6
|
||||||
|
#define SLC_ABORT 7
|
||||||
|
#define SLC_EOF 8
|
||||||
|
#define SLC_SUSP 9
|
||||||
|
#define SLC_EC 10
|
||||||
|
#define SLC_EL 11
|
||||||
|
#define SLC_EW 12
|
||||||
|
#define SLC_RP 13
|
||||||
|
#define SLC_LNEXT 14
|
||||||
|
#define SLC_XON 15
|
||||||
|
#define SLC_XOFF 16
|
||||||
|
#define SLC_FORW1 17
|
||||||
|
#define SLC_FORW2 18
|
||||||
|
|
||||||
|
#define NSLC 18
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For backwards compatability, we define SLC_NAMES to be the
|
||||||
|
* list of names if SLC_NAMES is not defined.
|
||||||
|
*/
|
||||||
|
#define SLC_NAMELIST "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \
|
||||||
|
"ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \
|
||||||
|
"LNEXT", "XON", "XOFF", "FORW1", "FORW2", 0,
|
||||||
|
#ifdef SLC_NAMES
|
||||||
|
char *slc_names[] = {
|
||||||
|
SLC_NAMELIST
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
extern char *slc_names[];
|
||||||
|
#define SLC_NAMES SLC_NAMELIST
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SLC_NAME_OK(x) ((unsigned int)(x) <= NSLC)
|
||||||
|
#define SLC_NAME(x) slc_names[x]
|
||||||
|
|
||||||
|
#define SLC_NOSUPPORT 0
|
||||||
|
#define SLC_CANTCHANGE 1
|
||||||
|
#define SLC_VARIABLE 2
|
||||||
|
#define SLC_DEFAULT 3
|
||||||
|
#define SLC_LEVELBITS 0x03
|
||||||
|
|
||||||
|
#define SLC_FUNC 0
|
||||||
|
#define SLC_FLAGS 1
|
||||||
|
#define SLC_VALUE 2
|
||||||
|
|
||||||
|
#define SLC_ACK 0x80
|
||||||
|
#define SLC_FLUSHIN 0x40
|
||||||
|
#define SLC_FLUSHOUT 0x20
|
||||||
|
|
||||||
|
#define OLD_ENV_VAR 1
|
||||||
|
#define OLD_ENV_VALUE 0
|
||||||
|
#define NEW_ENV_VAR 0
|
||||||
|
#define NEW_ENV_VALUE 1
|
||||||
|
#define ENV_ESC 2
|
||||||
|
#define ENV_USERVAR 3
|
||||||
|
|
||||||
|
#define ENV_VALUE 0
|
||||||
|
#define ENV_VAR 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AUTHENTICATION suboptions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Who is authenticating who ...
|
||||||
|
*/
|
||||||
|
#define AUTH_WHO_CLIENT 0 /* Client authenticating server */
|
||||||
|
#define AUTH_WHO_SERVER 1 /* Server authenticating client */
|
||||||
|
#define AUTH_WHO_MASK 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* amount of authentication done
|
||||||
|
*/
|
||||||
|
#define AUTH_HOW_ONE_WAY 0
|
||||||
|
#define AUTH_HOW_MUTUAL 2
|
||||||
|
#define AUTH_HOW_MASK 2
|
||||||
|
|
||||||
|
#define AUTHTYPE_NULL 0
|
||||||
|
#define AUTHTYPE_KERBEROS_V4 1
|
||||||
|
#define AUTHTYPE_KERBEROS_V5 2
|
||||||
|
#define AUTHTYPE_SPX 3
|
||||||
|
#define AUTHTYPE_MINK 4
|
||||||
|
#define AUTHTYPE_CNT 5
|
||||||
|
|
||||||
|
#define AUTHTYPE_TEST 99
|
||||||
|
|
||||||
|
#ifdef AUTH_NAMES
|
||||||
|
char *authtype_names[] = {
|
||||||
|
"NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 0,
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
extern char *authtype_names[];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define AUTHTYPE_NAME_OK(x) ((unsigned int)(x) < AUTHTYPE_CNT)
|
||||||
|
#define AUTHTYPE_NAME(x) authtype_names[x]
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ENCRYPTion suboptions
|
||||||
|
*/
|
||||||
|
#define ENCRYPT_IS 0 /* I pick encryption type ... */
|
||||||
|
#define ENCRYPT_SUPPORT 1 /* I support encryption types ... */
|
||||||
|
#define ENCRYPT_REPLY 2 /* Initial setup response */
|
||||||
|
#define ENCRYPT_START 3 /* Am starting to send encrypted */
|
||||||
|
#define ENCRYPT_END 4 /* Am ending encrypted */
|
||||||
|
#define ENCRYPT_REQSTART 5 /* Request you start encrypting */
|
||||||
|
#define ENCRYPT_REQEND 6 /* Request you send encrypting */
|
||||||
|
#define ENCRYPT_ENC_KEYID 7
|
||||||
|
#define ENCRYPT_DEC_KEYID 8
|
||||||
|
#define ENCRYPT_CNT 9
|
||||||
|
|
||||||
|
#define ENCTYPE_ANY 0
|
||||||
|
#define ENCTYPE_DES_CFB64 1
|
||||||
|
#define ENCTYPE_DES_OFB64 2
|
||||||
|
#define ENCTYPE_CNT 3
|
||||||
|
|
||||||
|
#ifdef ENCRYPT_NAMES
|
||||||
|
char *encrypt_names[] = {
|
||||||
|
"IS", "SUPPORT", "REPLY", "START", "END",
|
||||||
|
"REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID",
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
char *enctype_names[] = {
|
||||||
|
"ANY", "DES_CFB64", "DES_OFB64", 0,
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
extern char *encrypt_names[];
|
||||||
|
extern char *enctype_names[];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define ENCRYPT_NAME_OK(x) ((unsigned int)(x) < ENCRYPT_CNT)
|
||||||
|
#define ENCRYPT_NAME(x) encrypt_names[x]
|
||||||
|
|
||||||
|
#define ENCTYPE_NAME_OK(x) ((unsigned int)(x) < ENCTYPE_CNT)
|
||||||
|
#define ENCTYPE_NAME(x) enctype_names[x]
|
||||||
|
#endif /* _ARPA_TELNET_H */
|
93
winsup/cygwin/include/asm/byteorder.h
Normal file
93
winsup/cygwin/include/asm/byteorder.h
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#ifndef _I386_BYTEORDER_H
|
||||||
|
#define _I386_BYTEORDER_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#undef ntohl
|
||||||
|
#undef ntohs
|
||||||
|
#undef htonl
|
||||||
|
#undef htons
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __LITTLE_ENDIAN
|
||||||
|
#define __LITTLE_ENDIAN 1234
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __LITTLE_ENDIAN_BITFIELD
|
||||||
|
#define __LITTLE_ENDIAN_BITFIELD
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
extern unsigned long int ntohl(unsigned long int);
|
||||||
|
extern unsigned short int ntohs(unsigned short int);
|
||||||
|
extern unsigned long int htonl(unsigned long int);
|
||||||
|
extern unsigned short int htons(unsigned short int);
|
||||||
|
|
||||||
|
extern __inline__ unsigned long int __ntohl(unsigned long int);
|
||||||
|
extern __inline__ unsigned short int __ntohs(unsigned short int);
|
||||||
|
extern __inline__ unsigned long int __constant_ntohl(unsigned long int);
|
||||||
|
extern __inline__ unsigned short int __constant_ntohs(unsigned short int);
|
||||||
|
|
||||||
|
extern __inline__ unsigned long int
|
||||||
|
__ntohl(unsigned long int x)
|
||||||
|
{
|
||||||
|
__asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */
|
||||||
|
"rorl $16,%0\n\t" /* swap words */
|
||||||
|
"xchgb %b0,%h0" /* swap higher bytes */
|
||||||
|
:"=q" (x)
|
||||||
|
: "0" (x));
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define __constant_ntohl(x) \
|
||||||
|
((unsigned long int)((((unsigned long int)(x) & 0x000000ffU) << 24) | \
|
||||||
|
(((unsigned long int)(x) & 0x0000ff00U) << 8) | \
|
||||||
|
(((unsigned long int)(x) & 0x00ff0000U) >> 8) | \
|
||||||
|
(((unsigned long int)(x) & 0xff000000U) >> 24)))
|
||||||
|
|
||||||
|
extern __inline__ unsigned short int
|
||||||
|
__ntohs(unsigned short int x)
|
||||||
|
{
|
||||||
|
__asm__("xchgb %b0,%h0" /* swap bytes */
|
||||||
|
: "=q" (x)
|
||||||
|
: "0" (x));
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define __constant_ntohs(x) \
|
||||||
|
((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \
|
||||||
|
(((unsigned short int)(x) & 0xff00) >> 8))) \
|
||||||
|
|
||||||
|
#define __htonl(x) __ntohl(x)
|
||||||
|
#define __htons(x) __ntohs(x)
|
||||||
|
#define __constant_htonl(x) __constant_ntohl(x)
|
||||||
|
#define __constant_htons(x) __constant_ntohs(x)
|
||||||
|
|
||||||
|
#ifdef __OPTIMIZE__
|
||||||
|
# define ntohl(x) \
|
||||||
|
(__builtin_constant_p((long)(x)) ? \
|
||||||
|
__constant_ntohl((x)) : \
|
||||||
|
__ntohl((x)))
|
||||||
|
# define ntohs(x) \
|
||||||
|
(__builtin_constant_p((short)(x)) ? \
|
||||||
|
__constant_ntohs((x)) : \
|
||||||
|
__ntohs((x)))
|
||||||
|
# define htonl(x) \
|
||||||
|
(__builtin_constant_p((long)(x)) ? \
|
||||||
|
__constant_htonl((x)) : \
|
||||||
|
__htonl((x)))
|
||||||
|
# define htons(x) \
|
||||||
|
(__builtin_constant_p((short)(x)) ? \
|
||||||
|
__constant_htons((x)) : \
|
||||||
|
__htons((x)))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
58
winsup/cygwin/include/asm/socket.h
Normal file
58
winsup/cygwin/include/asm/socket.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#ifndef _ASM_SOCKET_H
|
||||||
|
#define _ASM_SOCKET_H
|
||||||
|
|
||||||
|
#include <cygwin/if.h>
|
||||||
|
|
||||||
|
#define IOCPARM_MASK 0x7f /* parameters must be < 128 bytes */
|
||||||
|
#define IOC_VOID 0x20000000 /* no parameters */
|
||||||
|
#define IOC_OUT 0x40000000 /* copy out parameters */
|
||||||
|
#define IOC_IN 0x80000000 /* copy in parameters */
|
||||||
|
|
||||||
|
#define _IO(x,y) (IOC_VOID|(x<<8)|y)
|
||||||
|
#define _IOR(x,y,t) (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y)
|
||||||
|
#define _IOW(x,y,t) (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y)
|
||||||
|
|
||||||
|
#define SIOCATMARK _IOR('s', 7, u_long) /* at oob mark? */
|
||||||
|
#define FIONREAD _IOR('f', 127, u_long) /* get # bytes to read */
|
||||||
|
#define FIONBIO 0x8004667e /* To be compatible with termiost version */
|
||||||
|
#define REAL_FIONBIO _IOW('f', 126, u_long) /* set/clear non-blocking i/o */
|
||||||
|
#define FIOASYNC _IOW('f', 125, u_long) /* set/clear async i/o */
|
||||||
|
#define SIOCSHIWAT _IOW('s', 0, u_long) /* set high watermark */
|
||||||
|
#define SIOCGHIWAT _IOR('s', 1, u_long) /* get high watermark */
|
||||||
|
#define SIOCSLOWAT _IOW('s', 2, u_long) /* set low watermark */
|
||||||
|
#define SIOCGLOWAT _IOR('s', 3, u_long) /* get low watermark */
|
||||||
|
|
||||||
|
/* Needed for if queries */
|
||||||
|
#define SIOCGIFCONF _IOW('s', 100, struct ifconf) /* get if list */
|
||||||
|
#define SIOCGIFFLAGS _IOW('s', 101, struct ifreq) /* Get if flags */
|
||||||
|
#define SIOCGIFADDR _IOW('s', 102, struct ifreq) /* Get if addr */
|
||||||
|
#define SIOCGIFBRDADDR _IOW('s', 103, struct ifreq) /* Get if broadcastaddr */
|
||||||
|
#define SIOCGIFNETMASK _IOW('s', 104, struct ifreq) /* Get if netmask */
|
||||||
|
|
||||||
|
#define SOL_SOCKET 0xffff /* options for socket level */
|
||||||
|
|
||||||
|
#define SO_DEBUG 0x0001 /* turn on debugging info recording */
|
||||||
|
#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
|
||||||
|
#define SO_REUSEADDR 0x0004 /* allow local address reuse */
|
||||||
|
#define SO_KEEPALIVE 0x0008 /* keep connections alive */
|
||||||
|
#define SO_DONTROUTE 0x0010 /* just use interface addresses */
|
||||||
|
#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
|
||||||
|
#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
|
||||||
|
#define SO_LINGER 0x0080 /* linger on close if data present */
|
||||||
|
#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
|
||||||
|
#define SO_DONTLINGER (u_int)(~SO_LINGER)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Additional options.
|
||||||
|
*/
|
||||||
|
#define SO_SNDBUF 0x1001 /* send buffer size */
|
||||||
|
#define SO_RCVBUF 0x1002 /* receive buffer size */
|
||||||
|
#define SO_SNDLOWAT 0x1003 /* send low-water mark */
|
||||||
|
#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
|
||||||
|
#define SO_SNDTIMEO 0x1005 /* send timeout */
|
||||||
|
#define SO_RCVTIMEO 0x1006 /* receive timeout */
|
||||||
|
#define SO_ERROR 0x1007 /* get error status and clear */
|
||||||
|
#define SO_TYPE 0x1008 /* get socket type */
|
||||||
|
|
||||||
|
#endif /* _ASM_SOCKET_H */
|
||||||
|
|
13
winsup/cygwin/include/asm/types.h
Normal file
13
winsup/cygwin/include/asm/types.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#ifndef _ASM_TYPES_H
|
||||||
|
#define _ASM_TYPES_H
|
||||||
|
|
||||||
|
typedef __signed__ char __s8;
|
||||||
|
typedef unsigned char __u8;
|
||||||
|
|
||||||
|
typedef __signed__ short __s16;
|
||||||
|
typedef unsigned short __u16;
|
||||||
|
|
||||||
|
typedef __signed__ int __s32;
|
||||||
|
typedef unsigned int __u32;
|
||||||
|
|
||||||
|
#endif /* _ASM_TYPES_H */
|
81
winsup/cygwin/include/cygwin/acl.h
Normal file
81
winsup/cygwin/include/cygwin/acl.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/* cygwin/acl.h header file for Cygwin.
|
||||||
|
|
||||||
|
Copyright 1999, 2000 Cygnus Solutions.
|
||||||
|
Written by C. Vinschen.
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#ifndef _CYGWIN_ACL_H
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
#define _CYGWIN_ACL_H
|
||||||
|
|
||||||
|
#include <_ansi.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
/* Values for `cmd' in calls to acl(2) and facl(2) */
|
||||||
|
#define SETACL (0x0)
|
||||||
|
#define GETACL (0x1)
|
||||||
|
#define GETACLCNT (0x2)
|
||||||
|
|
||||||
|
#define MIN_ACL_ENTRIES (4) // minimal acl entries from GETACLCNT
|
||||||
|
#define MAX_ACL_ENTRIES (256) // max entries of each type
|
||||||
|
|
||||||
|
// Return values of aclcheck(3) in case of error */
|
||||||
|
#define GRP_ERROR (0x1)
|
||||||
|
#define USER_ERROR (0x2)
|
||||||
|
#define CLASS_ERROR (0x3)
|
||||||
|
#define OTHER_ERROR (0x4)
|
||||||
|
#define DUPLICATE_ERROR (0x5)
|
||||||
|
#define ENTRY_ERROR (0x6)
|
||||||
|
#define MISS_ERROR (0x7) // which = -1
|
||||||
|
#define MEM_ERROR (0x8) // which = -1
|
||||||
|
|
||||||
|
// Values for entry type of struct acl
|
||||||
|
#define USER_OBJ (0x0001) // owner
|
||||||
|
#define USER (0x0002) // additional user
|
||||||
|
#define GROUP_OBJ (0x0004) // owning group
|
||||||
|
#define GROUP (0x0008) // additional group
|
||||||
|
#define CLASS_OBJ (0x0010) // mask entry
|
||||||
|
#define OTHER_OBJ (0x0020) // others
|
||||||
|
#define ACL_DEFAULT (0x1000) // default flag
|
||||||
|
#define DEF_USER_OBJ (ACL_DEFAULT|USER_OBJ) // default owner
|
||||||
|
#define DEF_USER (ACL_DEFAULT|USER) // default additional user
|
||||||
|
#define DEF_GROUP_OBJ (ACL_DEFAULT|GROUP_OBJ) // default owning group
|
||||||
|
#define DEF_GROUP (ACL_DEFAULT|GROUP) // default additional group
|
||||||
|
#define DEF_CLASS_OBJ (ACL_DEFAULT|CLASS_OBJ) // default mask entry
|
||||||
|
#define DEF_OTHER_OBJ (ACL_DEFAULT|OTHER_OBJ) // default others
|
||||||
|
// Values with equivalent meanings
|
||||||
|
#define USER_OWNER USER_OBJ
|
||||||
|
#define GROUP_OWNER GROUP_OBJ
|
||||||
|
#define MASK CLASS_OBJ
|
||||||
|
#define OTHER OTHER_OBJ
|
||||||
|
|
||||||
|
typedef struct acl {
|
||||||
|
int a_type; /* entry type */
|
||||||
|
uid_t a_id; /* UID | GID */
|
||||||
|
mode_t a_perm; /* permissions */
|
||||||
|
} aclent_t;
|
||||||
|
|
||||||
|
int _EXFUN(acl,(const char *path, int cmd, int nentries, aclent_t *aclbufp));
|
||||||
|
int _EXFUN(facl,(int fd, int cmd, int nentries, aclent_t *aclbufp));
|
||||||
|
int _EXFUN(aclcheck,(aclent_t *aclbufp, int nentries, int *which));
|
||||||
|
int _EXFUN(aclsort,(int nentries, int calclass, aclent_t *aclbufp));
|
||||||
|
int _EXFUN(acltomode,(aclent_t *aclbufp, int nentries, mode_t *modep));
|
||||||
|
int _EXFUN(aclfrommode,(aclent_t *aclbufp, int nentries, mode_t *modep));
|
||||||
|
int _EXFUN(acltopbits,(aclent_t *aclbufp, int nentries, mode_t *pbitsp));
|
||||||
|
int _EXFUN(aclfrompbits,(aclent_t *aclbufp, int nentries, mode_t *pbitsp));
|
||||||
|
char *_EXFUN(acltotext,(aclent_t *aclbufp, int aclcnt));
|
||||||
|
aclent_t *_EXFUN(aclfromtext,(char *acltextp, int *aclcnt));
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* _CYGWIN_ACL_H */
|
96
winsup/cygwin/include/cygwin/cygwin_dll.h
Normal file
96
winsup/cygwin/include/cygwin/cygwin_dll.h
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/* cygwin_dll.h
|
||||||
|
|
||||||
|
Copyright 1998 Cygnus Solutions
|
||||||
|
|
||||||
|
This file is part of Cygwin32.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin32 license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#ifndef __CYGWIN_CYGWIN_DLL_H__
|
||||||
|
#define __CYGWIN_CYGWIN_DLL_H__
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define CDECL_BEGIN extern "C" {
|
||||||
|
#define CDECL_END }
|
||||||
|
#else
|
||||||
|
#define CDECL_BEGIN
|
||||||
|
#define CDECL_END
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DECLARE_CYGWIN_DLL(Entry) \
|
||||||
|
\
|
||||||
|
CDECL_BEGIN \
|
||||||
|
int WINAPI _cygwin_dll_entry (HANDLE h, DWORD reason, void *ptr); \
|
||||||
|
int WINAPI _cygwin_noncygwin_dll_entry (HANDLE h, DWORD reason, void *ptr); \
|
||||||
|
\
|
||||||
|
int WINAPI Entry (HANDLE h, DWORD reason, void *ptr); \
|
||||||
|
extern int cygwin_attach_dll (); \
|
||||||
|
extern void cygwin_detach_dll (); \
|
||||||
|
CDECL_END \
|
||||||
|
\
|
||||||
|
static HANDLE storedHandle; \
|
||||||
|
static DWORD storedReason; \
|
||||||
|
static void* storedPtr; \
|
||||||
|
\
|
||||||
|
static int __dllMain (int a, char **b, char **c) \
|
||||||
|
{ \
|
||||||
|
return Entry (storedHandle, storedReason, storedPtr); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
static int dll_index; \
|
||||||
|
\
|
||||||
|
int WINAPI _cygwin_dll_entry (HANDLE h, DWORD reason, void *ptr) \
|
||||||
|
{ \
|
||||||
|
int ret; \
|
||||||
|
ret = 1; \
|
||||||
|
\
|
||||||
|
switch (reason) \
|
||||||
|
{ \
|
||||||
|
case DLL_PROCESS_ATTACH: \
|
||||||
|
{ \
|
||||||
|
storedHandle = h; \
|
||||||
|
storedReason = reason; \
|
||||||
|
storedPtr = ptr; \
|
||||||
|
dll_index = cygwin_attach_dll (h, &__dllMain); \
|
||||||
|
if (dll_index == -1) \
|
||||||
|
ret = 0; \
|
||||||
|
} \
|
||||||
|
break; \
|
||||||
|
\
|
||||||
|
case DLL_PROCESS_DETACH: \
|
||||||
|
{ \
|
||||||
|
ret = Entry (h, reason, ptr); \
|
||||||
|
if (ret) \
|
||||||
|
{ \
|
||||||
|
cygwin_detach_dll (dll_index); \
|
||||||
|
dll_index = -1; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
break; \
|
||||||
|
\
|
||||||
|
case DLL_THREAD_ATTACH: \
|
||||||
|
{ \
|
||||||
|
ret = Entry (h, reason, ptr); \
|
||||||
|
} \
|
||||||
|
break; \
|
||||||
|
\
|
||||||
|
case DLL_THREAD_DETACH: \
|
||||||
|
{ \
|
||||||
|
ret = Entry (h, reason, ptr); \
|
||||||
|
} \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
return ret; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
/* OBSOLETE: This is only provided for source level compatibility. */ \
|
||||||
|
int WINAPI _cygwin_noncygwin_dll_entry (HANDLE h, DWORD reason, void *ptr) \
|
||||||
|
{ \
|
||||||
|
return _cygwin_dll_entry (h, reason, ptr); \
|
||||||
|
} \
|
||||||
|
|
||||||
|
#endif /* __CYGWIN_CYGWIN_DLL_H__ */
|
1
winsup/cygwin/include/cygwin/icmp.h
Normal file
1
winsup/cygwin/include/cygwin/icmp.h
Normal file
@ -0,0 +1 @@
|
|||||||
|
/* icmp.h */
|
74
winsup/cygwin/include/cygwin/if.h
Normal file
74
winsup/cygwin/include/cygwin/if.h
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#ifndef _CYGWIN_IF_H_
|
||||||
|
#define _CYGWIN_IF_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
/* Standard interface flags. */
|
||||||
|
#define IFF_UP 0x1 /* interface is up */
|
||||||
|
#define IFF_BROADCAST 0x2 /* broadcast address valid */
|
||||||
|
#define IFF_LOOPBACK 0x8 /* is a loopback net */
|
||||||
|
#define IFF_NOTRAILERS 0x20 /* avoid use of trailers */
|
||||||
|
#define IFF_RUNNING 0x40 /* resources allocated */
|
||||||
|
#define IFF_PROMISC 0x100 /* receive all packets */
|
||||||
|
#define IFF_MULTICAST 0x1000 /* Supports multicast */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interface request structure used for socket
|
||||||
|
* ioctl's. All interface ioctl's must have parameter
|
||||||
|
* definitions which begin with ifr_name. The
|
||||||
|
* remainder may be interface specific.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct ifreq
|
||||||
|
{
|
||||||
|
#define IFNAMSIZ 16
|
||||||
|
union
|
||||||
|
{
|
||||||
|
char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */
|
||||||
|
} ifr_ifrn;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct sockaddr ifru_addr;
|
||||||
|
struct sockaddr ifru_broadaddr;
|
||||||
|
struct sockaddr ifru_netmask;
|
||||||
|
short ifru_flags;
|
||||||
|
int ifru_metric;
|
||||||
|
int ifru_mtu;
|
||||||
|
} ifr_ifru;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ifr_name ifr_ifrn.ifrn_name /* interface name */
|
||||||
|
#define ifr_addr ifr_ifru.ifru_addr /* address */
|
||||||
|
#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
|
||||||
|
#define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */
|
||||||
|
#define ifr_flags ifr_ifru.ifru_flags /* flags */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure used in SIOCGIFCONF request.
|
||||||
|
* Used to retrieve interface configuration
|
||||||
|
* for machine (useful for programs which
|
||||||
|
* must know all networks accessible).
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct ifconf
|
||||||
|
{
|
||||||
|
int ifc_len; /* size of buffer */
|
||||||
|
union
|
||||||
|
{
|
||||||
|
caddr_t ifcu_buf;
|
||||||
|
struct ifreq *ifcu_req;
|
||||||
|
} ifc_ifcu;
|
||||||
|
};
|
||||||
|
#define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */
|
||||||
|
#define ifc_req ifc_ifcu.ifcu_req /* array of structures */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
};
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif /* _CYGWIN_IF_H_ */
|
188
winsup/cygwin/include/cygwin/in.h
Normal file
188
winsup/cygwin/include/cygwin/in.h
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
/*
|
||||||
|
* INET An implementation of the TCP/IP protocol suite for the LINUX
|
||||||
|
* operating system. INET is implemented using the BSD Socket
|
||||||
|
* interface as the means of communication with the user level.
|
||||||
|
*
|
||||||
|
* Definitions of the Internet Protocol.
|
||||||
|
*
|
||||||
|
* Version: @(#)in.h 1.0.1 04/21/93
|
||||||
|
*
|
||||||
|
* Authors: Original taken from the GNU Project <netinet/in.h> file.
|
||||||
|
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version
|
||||||
|
* 2 of the License, or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
#ifndef _CYGWIN_IN_H
|
||||||
|
#define _CYGWIN_IN_H
|
||||||
|
|
||||||
|
#include <cygwin/types.h>
|
||||||
|
|
||||||
|
/* Standard well-defined IP protocols. */
|
||||||
|
enum {
|
||||||
|
IPPROTO_IP = 0, /* Dummy protocol for TCP */
|
||||||
|
IPPROTO_ICMP = 1, /* Internet Control Message Protocol */
|
||||||
|
IPPROTO_IGMP = 2, /* Internet Gateway Management Protocol */
|
||||||
|
IPPROTO_IPIP = 4, /* IPIP tunnels (older KA9Q tunnels use 94) */
|
||||||
|
IPPROTO_TCP = 6, /* Transmission Control Protocol */
|
||||||
|
IPPROTO_EGP = 8, /* Exterior Gateway Protocol */
|
||||||
|
IPPROTO_PUP = 12, /* PUP protocol */
|
||||||
|
IPPROTO_UDP = 17, /* User Datagram Protocol */
|
||||||
|
IPPROTO_IDP = 22, /* XNS IDP protocol */
|
||||||
|
|
||||||
|
IPPROTO_RAW = 255, /* Raw IP packets */
|
||||||
|
IPPROTO_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Standard well-known ports. *//* from winsup/include/netinet/in.h */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
IPPORT_ECHO = 7, /* Echo service. */
|
||||||
|
IPPORT_DISCARD = 9, /* Discard transmissions service. */
|
||||||
|
IPPORT_SYSTAT = 11, /* System status service. */
|
||||||
|
IPPORT_DAYTIME = 13, /* Time of day service. */
|
||||||
|
IPPORT_NETSTAT = 15, /* Network status service. */
|
||||||
|
IPPORT_FTP = 21, /* File Transfer Protocol. */
|
||||||
|
IPPORT_TELNET = 23, /* Telnet protocol. */
|
||||||
|
IPPORT_SMTP = 25, /* Simple Mail Transfer Protocol. */
|
||||||
|
IPPORT_TIMESERVER = 37, /* Timeserver service. */
|
||||||
|
IPPORT_NAMESERVER = 42, /* Domain Name Service. */
|
||||||
|
IPPORT_WHOIS = 43, /* Internet Whois service. */
|
||||||
|
IPPORT_MTP = 57,
|
||||||
|
|
||||||
|
IPPORT_TFTP = 69, /* Trivial File Transfer Protocol. */
|
||||||
|
IPPORT_RJE = 77,
|
||||||
|
IPPORT_FINGER = 79, /* Finger service. */
|
||||||
|
IPPORT_TTYLINK = 87,
|
||||||
|
IPPORT_SUPDUP = 95, /* SUPDUP protocol. */
|
||||||
|
|
||||||
|
|
||||||
|
IPPORT_EXECSERVER = 512, /* execd service. */
|
||||||
|
IPPORT_LOGINSERVER = 513, /* rlogind service. */
|
||||||
|
IPPORT_CMDSERVER = 514,
|
||||||
|
IPPORT_EFSSERVER = 520,
|
||||||
|
|
||||||
|
/* UDP ports. */
|
||||||
|
IPPORT_BIFFUDP = 512,
|
||||||
|
IPPORT_WHOSERVER = 513,
|
||||||
|
IPPORT_ROUTESERVER = 520,
|
||||||
|
|
||||||
|
/* Ports less than this value are reserved for privileged processes. */
|
||||||
|
IPPORT_RESERVED = 1024,
|
||||||
|
|
||||||
|
/* Ports greater this value are reserved for (non-privileged) servers. */
|
||||||
|
IPPORT_USERRESERVED = 5000
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Internet address. */
|
||||||
|
struct in_addr {
|
||||||
|
unsigned int s_addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Request struct for multicast socket ops */
|
||||||
|
|
||||||
|
struct ip_mreq
|
||||||
|
{
|
||||||
|
struct in_addr imr_multiaddr; /* IP multicast address of group */
|
||||||
|
struct in_addr imr_interface; /* local IP address of interface */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Structure describing an Internet (IP) socket address. */
|
||||||
|
#define __SOCK_SIZE__ 16 /* sizeof(struct sockaddr) */
|
||||||
|
struct sockaddr_in {
|
||||||
|
short int sin_family; /* Address family */
|
||||||
|
unsigned short int sin_port; /* Port number */
|
||||||
|
struct in_addr sin_addr; /* Internet address */
|
||||||
|
|
||||||
|
/* Pad to size of `struct sockaddr'. */
|
||||||
|
unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) -
|
||||||
|
sizeof(unsigned short int) - sizeof(struct in_addr)];
|
||||||
|
};
|
||||||
|
#define sin_zero __pad /* for BSD UNIX comp. -FvK */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Definitions of the bits in an Internet address integer.
|
||||||
|
* On subnets, host and network parts are found according
|
||||||
|
* to the subnet mask, not these masks.
|
||||||
|
*/
|
||||||
|
#define IN_CLASSA(a) ((((long int) (a)) & 0x80000000) == 0)
|
||||||
|
#define IN_CLASSA_NET 0xff000000
|
||||||
|
#define IN_CLASSA_NSHIFT 24
|
||||||
|
#define IN_CLASSA_HOST (0xffffffff & ~IN_CLASSA_NET)
|
||||||
|
#define IN_CLASSA_MAX 128
|
||||||
|
|
||||||
|
#define IN_CLASSB(a) ((((long int) (a)) & 0xc0000000) == 0x80000000)
|
||||||
|
#define IN_CLASSB_NET 0xffff0000
|
||||||
|
#define IN_CLASSB_NSHIFT 16
|
||||||
|
#define IN_CLASSB_HOST (0xffffffff & ~IN_CLASSB_NET)
|
||||||
|
#define IN_CLASSB_MAX 65536
|
||||||
|
|
||||||
|
#define IN_CLASSC(a) ((((long int) (a)) & 0xe0000000) == 0xc0000000)
|
||||||
|
#define IN_CLASSC_NET 0xffffff00
|
||||||
|
#define IN_CLASSC_NSHIFT 8
|
||||||
|
#define IN_CLASSC_HOST (0xffffffff & ~IN_CLASSC_NET)
|
||||||
|
|
||||||
|
#define IN_CLASSD(a) ((((long int) (a)) & 0xf0000000) == 0xe0000000)
|
||||||
|
#define IN_MULTICAST(a) IN_CLASSD(a)
|
||||||
|
#define IN_MULTICAST_NET 0xF0000000
|
||||||
|
|
||||||
|
#define IN_EXPERIMENTAL(a) ((((long int) (a)) & 0xe0000000) == 0xe0000000)
|
||||||
|
#define IN_BADCLASS(a) ((((long int) (a)) & 0xf0000000) == 0xf0000000)
|
||||||
|
|
||||||
|
/* Address to accept any incoming messages. */
|
||||||
|
#define INADDR_ANY ((unsigned long int) 0x00000000)
|
||||||
|
|
||||||
|
/* Address to send to all hosts. */
|
||||||
|
#define INADDR_BROADCAST ((unsigned long int) 0xffffffff)
|
||||||
|
|
||||||
|
/* Address indicating an error return. */
|
||||||
|
#define INADDR_NONE 0xffffffff
|
||||||
|
|
||||||
|
/* Network number for local host loopback. */
|
||||||
|
#define IN_LOOPBACKNET 127
|
||||||
|
|
||||||
|
/* Address to loopback in software to local host. */
|
||||||
|
#define INADDR_LOOPBACK 0x7f000001 /* 127.0.0.1 */
|
||||||
|
#define IN_LOOPBACK(a) ((((long int) (a)) & 0xff000000) == 0x7f000000)
|
||||||
|
|
||||||
|
/* Defines for Multicast INADDR */
|
||||||
|
#define INADDR_UNSPEC_GROUP 0xe0000000 /* 224.0.0.0 */
|
||||||
|
#define INADDR_ALLHOSTS_GROUP 0xe0000001 /* 224.0.0.1 */
|
||||||
|
#define INADDR_MAX_LOCAL_GROUP 0xe00000ff /* 224.0.0.255 */
|
||||||
|
|
||||||
|
/* <asm/byteorder.h> contains the htonl type stuff.. */
|
||||||
|
|
||||||
|
#include <asm/byteorder.h>
|
||||||
|
|
||||||
|
/* Some random defines to make it easier in the kernel.. */
|
||||||
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
|
#define LOOPBACK(x) (((x) & htonl(0xff000000)) == htonl(0x7f000000))
|
||||||
|
#define MULTICAST(x) (((x) & htonl(0xf0000000)) == htonl(0xe0000000))
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IPv6 definitions as we start to include them. This is just
|
||||||
|
* a beginning dont get excited 8)
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct in_addr6
|
||||||
|
{
|
||||||
|
unsigned char s6_addr[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sockaddr_in6
|
||||||
|
{
|
||||||
|
unsigned short sin6_family;
|
||||||
|
unsigned short sin6_port;
|
||||||
|
unsigned long sin6_flowinfo;
|
||||||
|
struct in_addr6 sin6_addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _CYGWIN_IN_H */
|
190
winsup/cygwin/include/cygwin/mtio.h
Normal file
190
winsup/cygwin/include/cygwin/mtio.h
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
/*
|
||||||
|
* cygwin/mtio.h header file for Cygwin.
|
||||||
|
*
|
||||||
|
* Original written by H. Bergman for Linux.
|
||||||
|
* Changed for Cygwin by C. Vinschen.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _CYGWIN_MTIO_H
|
||||||
|
#define _CYGWIN_MTIO_H
|
||||||
|
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <asm/socket.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structures and definitions for mag tape io control commands
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* structure for MTIOCTOP - mag tape op command */
|
||||||
|
struct mtop {
|
||||||
|
short mt_op; /* operations defined below */
|
||||||
|
int mt_count; /* how many of them */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Magnetic Tape operations [Not all operations supported by all drivers]: */
|
||||||
|
#define MTRESET 0 /* +reset drive in case of problems */
|
||||||
|
#define MTFSF 1 /* forward space over FileMark,
|
||||||
|
* position at first record of next file
|
||||||
|
*/
|
||||||
|
#define MTBSF 2 /* backward space FileMark (position before FM) */
|
||||||
|
#define MTFSR 3 /* forward space record */
|
||||||
|
#define MTBSR 4 /* backward space record */
|
||||||
|
#define MTWEOF 5 /* write an end-of-file record (mark) */
|
||||||
|
#define MTREW 6 /* rewind */
|
||||||
|
#define MTOFFL 7 /* rewind and put the drive offline (eject?) */
|
||||||
|
#define MTNOP 8 /* no op, set status only (read with MTIOCGET) */
|
||||||
|
#define MTRETEN 9 /* retension tape */
|
||||||
|
#define MTBSFM 10 /* +backward space FileMark, position at FM */
|
||||||
|
#define MTFSFM 11 /* +forward space FileMark, position at FM */
|
||||||
|
#define MTEOM 12 /* goto end of recorded media (for appending files).
|
||||||
|
* MTEOM positions after the last FM, ready for
|
||||||
|
* appending another file.
|
||||||
|
*/
|
||||||
|
#define MTERASE 13 /* erase tape -- be careful! */
|
||||||
|
|
||||||
|
#define MTRAS1 14 /* run self test 1 (nondestructive) */
|
||||||
|
#define MTRAS2 15 /* run self test 2 (destructive) */
|
||||||
|
#define MTRAS3 16 /* reserved for self test 3 */
|
||||||
|
|
||||||
|
#define MTSETBLK 20 /* set block length (SCSI) */
|
||||||
|
#define MTSETDENSITY 21 /* set tape density (SCSI) */
|
||||||
|
#define MTSEEK 22 /* seek to block (Tandberg, etc.) */
|
||||||
|
#define MTTELL 23 /* tell block (Tandberg, etc.) */
|
||||||
|
#define MTSETDRVBUFFER 24 /* set the drive buffering according to SCSI-2 */
|
||||||
|
/* ordinary buffered operation with code 1 */
|
||||||
|
#define MTFSS 25 /* space forward over setmarks */
|
||||||
|
#define MTBSS 26 /* space backward over setmarks */
|
||||||
|
#define MTWSM 27 /* write setmarks */
|
||||||
|
|
||||||
|
#define MTLOCK 28 /* lock the drive door */
|
||||||
|
#define MTUNLOCK 29 /* unlock the drive door */
|
||||||
|
#define MTLOAD 30 /* execute the SCSI load command */
|
||||||
|
#define MTUNLOAD 31 /* execute the SCSI unload command */
|
||||||
|
#define MTCOMPRESSION 32/* control compression with SCSI mode page 15 */
|
||||||
|
#define MTSETPART 33 /* Change the active tape partition */
|
||||||
|
#define MTMKPART 34 /* Format the tape with one or two partitions */
|
||||||
|
|
||||||
|
/* structure for MTIOCGET - mag tape get status command */
|
||||||
|
|
||||||
|
struct mtget {
|
||||||
|
long mt_type; /* type of magtape device
|
||||||
|
* Cygwin: MT_ISUNKNOWN */
|
||||||
|
long mt_resid; /* residual count: (not sure)
|
||||||
|
* number of bytes ignored, or
|
||||||
|
* number of files not skipped, or
|
||||||
|
* number of records not skipped.
|
||||||
|
* Cygwin: remaining KB.
|
||||||
|
*/
|
||||||
|
/* the following registers are device dependent */
|
||||||
|
long mt_dsreg; /* status register */
|
||||||
|
long mt_gstat; /* generic (device independent) status */
|
||||||
|
long mt_erreg; /* error register */
|
||||||
|
/* The next two fields are not always used */
|
||||||
|
long mt_fileno; /* number of current file on tape */
|
||||||
|
long mt_blkno; /* current block number */
|
||||||
|
/* The next are Windows NT specific */
|
||||||
|
long long mt_capacity; /* Tape capacity in bytes */
|
||||||
|
long long mt_remaining; /* Remaining bytes */
|
||||||
|
int mt_minblksize;
|
||||||
|
int mt_maxblksize;
|
||||||
|
int mt_defblksize;
|
||||||
|
unsigned long mt_featureslow;
|
||||||
|
unsigned long mt_featureshigh;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* structure for MTIOCPOS - mag tape get position command */
|
||||||
|
|
||||||
|
struct mtpos {
|
||||||
|
long mt_blkno; /* current block number */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* mag tape io control commands */
|
||||||
|
#define MTIOCTOP _IOW('m', 1, struct mtop) /* do a mag tape op */
|
||||||
|
#define MTIOCGET _IOR('m', 2, struct mtget) /* get tape status */
|
||||||
|
#define MTIOCPOS _IOR('m', 3, struct mtpos) /* get tape position */
|
||||||
|
|
||||||
|
/* Generic Mag Tape (device independent) status macros for examining
|
||||||
|
* mt_gstat -- HP-UX compatible.
|
||||||
|
* There is room for more generic status bits here, but I don't
|
||||||
|
* know which of them are reserved. At least three or so should
|
||||||
|
* be added to make this really useful.
|
||||||
|
*/
|
||||||
|
#define GMT_EOF(x) ((x) & 0x80000000)
|
||||||
|
#define GMT_BOT(x) ((x) & 0x40000000)
|
||||||
|
#define GMT_EOT(x) ((x) & 0x20000000)
|
||||||
|
#define GMT_SM(x) ((x) & 0x10000000) /* DDS setmark */
|
||||||
|
#define GMT_EOD(x) ((x) & 0x08000000) /* DDS EOD */
|
||||||
|
#define GMT_WR_PROT(x) ((x) & 0x04000000)
|
||||||
|
/* #define GMT_ ? ((x) & 0x02000000) */
|
||||||
|
#define GMT_ONLINE(x) ((x) & 0x01000000)
|
||||||
|
#define GMT_D_6250(x) ((x) & 0x00800000)
|
||||||
|
#define GMT_D_1600(x) ((x) & 0x00400000)
|
||||||
|
#define GMT_D_800(x) ((x) & 0x00200000)
|
||||||
|
#define GMT_PADDING(x) ((x) & 0x00100000) /* data padding */
|
||||||
|
#define GMT_HW_ECC(x) ((x) & 0x00080000) /* HW error correction */
|
||||||
|
#define GMT_DR_OPEN(x) ((x) & 0x00040000) /* door open (no tape) */
|
||||||
|
#define GMT_HW_COMP(x) ((x) & 0x00020000) /* HW compression */
|
||||||
|
#define GMT_IM_REP_EN(x) ((x) & 0x00010000) /* immediate report mode */
|
||||||
|
/* 16 generic status bits unused */
|
||||||
|
|
||||||
|
|
||||||
|
/* SCSI-tape specific definitions */
|
||||||
|
/* Bitfield shifts in the status mt_dsreg */
|
||||||
|
#define MT_ST_BLKSIZE_SHIFT 0
|
||||||
|
#define MT_ST_BLKSIZE_MASK 0xffffff
|
||||||
|
#define MT_ST_DENSITY_SHIFT 24
|
||||||
|
#define MT_ST_DENSITY_MASK 0xff000000
|
||||||
|
|
||||||
|
#define MT_ST_SOFTERR_SHIFT 0
|
||||||
|
#define MT_ST_SOFTERR_MASK 0xffff
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constants for mt_type. Not all of these are supported,
|
||||||
|
* and these are not all of the ones that are supported.
|
||||||
|
*/
|
||||||
|
#define MT_ISUNKNOWN 0x01
|
||||||
|
#define MT_ISQIC02 0x02 /* Generic QIC-02 tape streamer */
|
||||||
|
#define MT_ISWT5150 0x03 /* Wangtek 5150EQ, QIC-150, QIC-02 */
|
||||||
|
#define MT_ISARCHIVE_5945L2 0x04 /* Archive 5945L-2, QIC-24, QIC-02? */
|
||||||
|
#define MT_ISCMSJ500 0x05 /* CMS Jumbo 500 (QIC-02?) */
|
||||||
|
#define MT_ISTDC3610 0x06 /* Tandberg 6310, QIC-24 */
|
||||||
|
#define MT_ISARCHIVE_VP60I 0x07 /* Archive VP60i, QIC-02 */
|
||||||
|
#define MT_ISARCHIVE_2150L 0x08 /* Archive Viper 2150L */
|
||||||
|
#define MT_ISARCHIVE_2060L 0x09 /* Archive Viper 2060L */
|
||||||
|
#define MT_ISARCHIVESC499 0x0A /* Archive SC-499 QIC-36 controller */
|
||||||
|
#define MT_ISQIC02_ALL_FEATURES 0x0F /* Generic QIC-02 with all features */
|
||||||
|
#define MT_ISWT5099EEN24 0x11 /* Wangtek 5099-een24, 60MB, QIC-24 */
|
||||||
|
#define MT_ISTEAC_MT2ST 0x12 /* Teac MT-2ST 155mb drive, Teac DC-1 card (Wangtek type) */
|
||||||
|
#define MT_ISEVEREX_FT40A 0x32 /* Everex FT40A (QIC-40) */
|
||||||
|
#define MT_ISDDS1 0x51 /* DDS device without partitions */
|
||||||
|
#define MT_ISDDS2 0x52 /* DDS device with partitions */
|
||||||
|
#define MT_ISSCSI1 0x71 /* Generic ANSI SCSI-1 tape unit */
|
||||||
|
#define MT_ISSCSI2 0x72 /* Generic ANSI SCSI-2 tape unit */
|
||||||
|
|
||||||
|
struct mt_tape_info {
|
||||||
|
long t_type; /* device type id (mt_type) */
|
||||||
|
char *t_name; /* descriptive name */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MT_TAPE_INFO { \
|
||||||
|
{MT_ISUNKNOWN, "Unknown type of tape device"}, \
|
||||||
|
{MT_ISQIC02, "Generic QIC-02 tape streamer"}, \
|
||||||
|
{MT_ISWT5150, "Wangtek 5150, QIC-150"}, \
|
||||||
|
{MT_ISARCHIVE_5945L2, "Archive 5945L-2"}, \
|
||||||
|
{MT_ISCMSJ500, "CMS Jumbo 500"}, \
|
||||||
|
{MT_ISTDC3610, "Tandberg TDC 3610, QIC-24"}, \
|
||||||
|
{MT_ISARCHIVE_VP60I, "Archive VP60i, QIC-02"}, \
|
||||||
|
{MT_ISARCHIVE_2150L, "Archive Viper 2150L"}, \
|
||||||
|
{MT_ISARCHIVE_2060L, "Archive Viper 2060L"}, \
|
||||||
|
{MT_ISARCHIVESC499, "Archive SC-499 QIC-36 controller"}, \
|
||||||
|
{MT_ISQIC02_ALL_FEATURES, "Generic QIC-02 tape, all features"}, \
|
||||||
|
{MT_ISWT5099EEN24, "Wangtek 5099-een24, 60MB"}, \
|
||||||
|
{MT_ISTEAC_MT2ST, "Teac MT-2ST 155mb data cassette drive"}, \
|
||||||
|
{MT_ISEVEREX_FT40A, "Everex FT40A, QIC-40"}, \
|
||||||
|
{MT_ISSCSI1, "Generic SCSI-1 tape"}, \
|
||||||
|
{MT_ISSCSI2, "Generic SCSI-2 tape"}, \
|
||||||
|
{0, NULL} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _CYGWIN_MTIO_H */
|
30
winsup/cygwin/include/cygwin/rdevio.h
Normal file
30
winsup/cygwin/include/cygwin/rdevio.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* cygwin/rdevio.h header file for Cygwin.
|
||||||
|
*
|
||||||
|
* Written by C. Vinschen.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _CYGWIN_RDEVIO_H
|
||||||
|
#define _CYGWIN_RDEVIO_H
|
||||||
|
|
||||||
|
/* structure for RDIOCDOP - raw device operation */
|
||||||
|
struct rdop {
|
||||||
|
short rd_op;
|
||||||
|
unsigned long rd_parm;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Raw device operations */
|
||||||
|
#define RDSETBLK 1 /* set buffer for driver */
|
||||||
|
|
||||||
|
/* structure for RDIOCGET - get raw device */
|
||||||
|
struct rdget {
|
||||||
|
unsigned long bufsiz;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ioctl commands
|
||||||
|
*/
|
||||||
|
#define RDIOCDOP _IOW('r', 128, struct rdop)
|
||||||
|
#define RDIOCGET _IOR('r', 129, struct rdget)
|
||||||
|
|
||||||
|
#endif /* _CYGWIN_RDEVIO_H */
|
152
winsup/cygwin/include/cygwin/socket.h
Normal file
152
winsup/cygwin/include/cygwin/socket.h
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
#ifndef _CYGWIN_SOCKET_H
|
||||||
|
#define _CYGWIN_SOCKET_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
struct sockaddr {
|
||||||
|
unsigned short sa_family; /* address family, AF_xxx */
|
||||||
|
char sa_data[14]; /* 14 bytes of protocol address */
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <asm/socket.h> /* arch-dependent defines */
|
||||||
|
#include <cygwin/sockios.h> /* the SIOCxxx I/O controls */
|
||||||
|
#include <cygwin/uio.h> /* iovec support */
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
struct linger {
|
||||||
|
unsigned short l_onoff; /* Linger active */
|
||||||
|
unsigned short l_linger; /* How long to linger for */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct msghdr
|
||||||
|
{
|
||||||
|
void * msg_name; /* Socket name */
|
||||||
|
int msg_namelen; /* Length of name */
|
||||||
|
struct iovec * msg_iov; /* Data blocks */
|
||||||
|
int msg_iovlen; /* Number of blocks */
|
||||||
|
void * msg_accrights; /* Per protocol magic (eg BSD file descriptor passing) */
|
||||||
|
int msg_accrightslen; /* Length of rights list */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Socket types. */
|
||||||
|
#define SOCK_STREAM 1 /* stream (connection) socket */
|
||||||
|
#define SOCK_DGRAM 2 /* datagram (conn.less) socket */
|
||||||
|
#define SOCK_RAW 3 /* raw socket */
|
||||||
|
#define SOCK_RDM 4 /* reliably-delivered message */
|
||||||
|
#define SOCK_SEQPACKET 5 /* sequential packet socket */
|
||||||
|
#define SOCK_PACKET 10 /* CYGWIN specific way of */
|
||||||
|
/* getting packets at the dev */
|
||||||
|
/* level. For writing rarp and */
|
||||||
|
/* other similar things on the */
|
||||||
|
/* user level. */
|
||||||
|
|
||||||
|
/* Supported address families. */
|
||||||
|
/*
|
||||||
|
* Address families.
|
||||||
|
*/
|
||||||
|
#define AF_UNSPEC 0 /* unspecified */
|
||||||
|
#define AF_UNIX 1 /* local to host (pipes, portals) */
|
||||||
|
#define AF_LOCAL 1 /* POSIX name for AF_UNIX */
|
||||||
|
#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
|
||||||
|
#define AF_IMPLINK 3 /* arpanet imp addresses */
|
||||||
|
#define AF_PUP 4 /* pup protocols: e.g. BSP */
|
||||||
|
#define AF_CHAOS 5 /* mit CHAOS protocols */
|
||||||
|
#define AF_NS 6 /* XEROX NS protocols */
|
||||||
|
#define AF_ISO 7 /* ISO protocols */
|
||||||
|
#define AF_OSI AF_ISO /* OSI is ISO */
|
||||||
|
#define AF_ECMA 8 /* european computer manufacturers */
|
||||||
|
#define AF_DATAKIT 9 /* datakit protocols */
|
||||||
|
#define AF_CCITT 10 /* CCITT protocols, X.25 etc */
|
||||||
|
#define AF_SNA 11 /* IBM SNA */
|
||||||
|
#define AF_DECnet 12 /* DECnet */
|
||||||
|
#define AF_DLI 13 /* Direct data link interface */
|
||||||
|
#define AF_LAT 14 /* LAT */
|
||||||
|
#define AF_HYLINK 15 /* NSC Hyperchannel */
|
||||||
|
#define AF_APPLETALK 16 /* AppleTalk */
|
||||||
|
#define AF_NETBIOS 17 /* NetBios-style addresses */
|
||||||
|
|
||||||
|
#define AF_MAX 18
|
||||||
|
/*
|
||||||
|
* Protocol families, same as address families for now.
|
||||||
|
*/
|
||||||
|
#define PF_UNSPEC AF_UNSPEC
|
||||||
|
#define PF_UNIX AF_UNIX
|
||||||
|
#define PF_LOCAL AF_LOCAL
|
||||||
|
#define PF_INET AF_INET
|
||||||
|
#define PF_IMPLINK AF_IMPLINK
|
||||||
|
#define PF_PUP AF_PUP
|
||||||
|
#define PF_CHAOS AF_CHAOS
|
||||||
|
#define PF_NS AF_NS
|
||||||
|
#define PF_ISO AF_ISO
|
||||||
|
#define PF_OSI AF_OSI
|
||||||
|
#define PF_ECMA AF_ECMA
|
||||||
|
#define PF_DATAKIT AF_DATAKIT
|
||||||
|
#define PF_CCITT AF_CCITT
|
||||||
|
#define PF_SNA AF_SNA
|
||||||
|
#define PF_DECnet AF_DECnet
|
||||||
|
#define PF_DLI AF_DLI
|
||||||
|
#define PF_LAT AF_LAT
|
||||||
|
#define PF_HYLINK AF_HYLINK
|
||||||
|
#define PF_APPLETALK AF_APPLETALK
|
||||||
|
#define PF_NETBIOS AF_NETBIOS
|
||||||
|
|
||||||
|
#define PF_MAX AF_MAX
|
||||||
|
|
||||||
|
/* Maximum queue length specificable by listen. */
|
||||||
|
#define SOMAXCONN 5
|
||||||
|
|
||||||
|
/* Flags we can use with send/ and recv. */
|
||||||
|
#define MSG_OOB 0x1 /* process out-of-band data */
|
||||||
|
#define MSG_PEEK 0x2 /* peek at incoming message */
|
||||||
|
#define MSG_DONTROUTE 0x4 /* send without using routing tables */
|
||||||
|
|
||||||
|
/* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx */
|
||||||
|
#define SOL_IP 0
|
||||||
|
#define SOL_IPX 256
|
||||||
|
#define SOL_AX25 257
|
||||||
|
#define SOL_ATALK 258
|
||||||
|
#define SOL_NETROM 259
|
||||||
|
#define SOL_TCP 6
|
||||||
|
#define SOL_UDP 17
|
||||||
|
|
||||||
|
/* IP options */
|
||||||
|
#define IPTOS_LOWDELAY 0x10
|
||||||
|
#define IPTOS_THROUGHPUT 0x08
|
||||||
|
#define IPTOS_RELIABILITY 0x04
|
||||||
|
|
||||||
|
/* These need to appear somewhere around here */
|
||||||
|
#define IP_DEFAULT_MULTICAST_TTL 1
|
||||||
|
#define IP_DEFAULT_MULTICAST_LOOP 1
|
||||||
|
#define IP_MAX_MEMBERSHIPS 20
|
||||||
|
|
||||||
|
/* IP options for use with WinSock */
|
||||||
|
|
||||||
|
#define IP_OPTIONS 1
|
||||||
|
#define IP_MULTICAST_IF 2
|
||||||
|
#define IP_MULTICAST_TTL 3
|
||||||
|
#define IP_MULTICAST_LOOP 4
|
||||||
|
#define IP_ADD_MEMBERSHIP 5
|
||||||
|
#define IP_DROP_MEMBERSHIP 6
|
||||||
|
#define IP_TTL 7
|
||||||
|
#define IP_TOS 8
|
||||||
|
#define IP_DONTFRAGMENT 9
|
||||||
|
|
||||||
|
/* IPX options */
|
||||||
|
#define IPX_TYPE 1
|
||||||
|
|
||||||
|
/* TCP options - this way around because someone left a set in the c library includes */
|
||||||
|
#define TCP_NODELAY 0x0001
|
||||||
|
#define TCP_MAXSEG 2
|
||||||
|
|
||||||
|
/* The various priorities. */
|
||||||
|
#define SOPRI_INTERACTIVE 0
|
||||||
|
#define SOPRI_NORMAL 1
|
||||||
|
#define SOPRI_BACKGROUND 2
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
};
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif /* _CYGWIN_SOCKET_H */
|
1
winsup/cygwin/include/cygwin/sockios.h
Normal file
1
winsup/cygwin/include/cygwin/sockios.h
Normal file
@ -0,0 +1 @@
|
|||||||
|
/* sockios.h */
|
1
winsup/cygwin/include/cygwin/types.h
Normal file
1
winsup/cygwin/include/cygwin/types.h
Normal file
@ -0,0 +1 @@
|
|||||||
|
/* types.h */
|
1
winsup/cygwin/include/cygwin/uio.h
Normal file
1
winsup/cygwin/include/cygwin/uio.h
Normal file
@ -0,0 +1 @@
|
|||||||
|
/* uio.h */
|
159
winsup/cygwin/include/cygwin/version.h
Normal file
159
winsup/cygwin/include/cygwin/version.h
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
/* version.h -- Cygwin version numbers and accompanying documentation.
|
||||||
|
|
||||||
|
Copyright 1996, 1997, 1998, 1999 Cygnus Solutions.
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
/* Cygwin versioning is relatively complicated because of its status
|
||||||
|
as a shared library. Let's start with how versioning used to be done.
|
||||||
|
|
||||||
|
Historical versioning in Cygwin 16.0 to 19.5:
|
||||||
|
|
||||||
|
In the olden days of Cygwin, we had a dll major and minor version
|
||||||
|
and a registry version. The major number started at 16 because the
|
||||||
|
"b15" GNU-Win32 release of the compiler tools was out when this
|
||||||
|
scheme was started. We incremented the DLL name frequently (for
|
||||||
|
every official release) and towards the end of this period every
|
||||||
|
release used a different shared memory area to prevent DLLs from
|
||||||
|
interfering with each other (embedding a build timestamp into the
|
||||||
|
name of the shared memory area). This turned out to be a Bad Idea
|
||||||
|
(tm) because people needed to mingle separate releases and have
|
||||||
|
them work together more than we thought they would. This was
|
||||||
|
especially problematic when tty info needed to be retained when an
|
||||||
|
old Cygwin executable executed a newer one.
|
||||||
|
|
||||||
|
In the old scheme, we incremented the major number whenever a
|
||||||
|
change to the dll invalidated existing executables. This can
|
||||||
|
happen for a number of reasons, including when functions are
|
||||||
|
removed from the export list of the dll. The minor number was
|
||||||
|
incremented when a change was made that we wanted to record, but
|
||||||
|
that didn't invalidate existing executables. Both numbers were
|
||||||
|
recorded in the executable and in the dll.
|
||||||
|
|
||||||
|
In October 1998 (starting with Cygwin 19.6), we started a new
|
||||||
|
means of Cygwin versioning: */
|
||||||
|
|
||||||
|
/* The DLL major and minor numbers correspond to the "version of
|
||||||
|
the Cygwin library". This version is used to track important
|
||||||
|
changes to the DLL and is mainly informative in nature. */
|
||||||
|
|
||||||
|
/* The current cygwin version is 1.1.0 */
|
||||||
|
|
||||||
|
#define CYGWIN_VERSION_DLL_MAJOR 1001
|
||||||
|
#define CYGWIN_VERSION_DLL_MINOR 0
|
||||||
|
|
||||||
|
/* Major numbers before CYGWIN_VERSION_DLL_EPOCH are
|
||||||
|
incompatible. */
|
||||||
|
|
||||||
|
#define CYGWIN_VERSION_DLL_EPOCH 19
|
||||||
|
|
||||||
|
/* CYGWIN_VERSION_DLL_COMBINED gives us a single number
|
||||||
|
representing the combined DLL major and minor numbers. */
|
||||||
|
|
||||||
|
#define CYGWIN_VERSION_DLL_MAKE_COMBINED(maj, min) (((maj) * 1000) + min)
|
||||||
|
#define CYGWIN_VERSION_DLL_COMBINED \
|
||||||
|
CYGWIN_VERSION_DLL_MAKE_COMBINED (CYGWIN_DLL_VERSION_MAJOR, CYGWIN_DLL_VERSION_MINOR)
|
||||||
|
|
||||||
|
/* Every version of cygwin <= this uses an old, incorrect method
|
||||||
|
to determine signal masks. */
|
||||||
|
|
||||||
|
#define CYGWIN_VERSION_DLL_BAD_SIGNAL_MASK 19005
|
||||||
|
|
||||||
|
/* API versions <= this had a termios structure whose members were
|
||||||
|
too small to accomodate modern settings. */
|
||||||
|
#define CYGWIN_VERSION_DLL_OLD_TERMIOS 00005
|
||||||
|
#define CYGWIN_VERSION_DLL_IS_OLD_TERMIOS \
|
||||||
|
(CYGWIN_VERSION_DLL_MAKE_COMBINED (user_data->api_major, user_data->api_minor) <= \
|
||||||
|
CYGWIN_VERSION_DLL_OLD_TERMIOS)
|
||||||
|
|
||||||
|
/* We used to use the DLL major/minor to track
|
||||||
|
non-backward-compatible interface changes to the API. Now we
|
||||||
|
use an API major/minor number for this purpose. */
|
||||||
|
|
||||||
|
/* API_MAJOR 0.0: Initial version. API_MINOR changes:
|
||||||
|
1: Export cygwin32_ calls as cygwin_ as well.
|
||||||
|
2: Export j1, jn, y1, yn.
|
||||||
|
3: Export dll_noncygwin_dllcrt0.
|
||||||
|
4: New socket ioctls, revamped ifconf support.
|
||||||
|
5: Thread support/exports.
|
||||||
|
6: Change in termios handling.
|
||||||
|
7: Export scandir and alphasort.
|
||||||
|
8: Export _ctype_, _sys_errlist, _sys_nerr.
|
||||||
|
9: Mount-related changes, new cygwin_umount export.
|
||||||
|
Raw device support (tape, floppies).
|
||||||
|
10: Fast math routine support added.
|
||||||
|
11: Export seekdir, telldir.
|
||||||
|
12: Export pthread_join, pthread_detach.
|
||||||
|
13: Export math funcs gamma and friends, also _j0, _j1, etc.
|
||||||
|
14: Export snprintf and vnsprintf.
|
||||||
|
15: Export glob
|
||||||
|
16: Export cygwin_stackdump
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CYGWIN_VERSION_API_MAJOR 0
|
||||||
|
#define CYGWIN_VERSION_API_MINOR 16
|
||||||
|
|
||||||
|
/* There is also a compatibity version number associated with the
|
||||||
|
shared memory regions. It is incremented when incompatible
|
||||||
|
changes are made to the shared memory region *or* to any named
|
||||||
|
shared mutexes, semaphores, etc. The arbitrary starting
|
||||||
|
version was 0 (cygwin release 98r2). */
|
||||||
|
|
||||||
|
#define CYGWIN_VERSION_SHARED_DATA 3
|
||||||
|
|
||||||
|
/* An identifier used in the names used to create shared objects.
|
||||||
|
The full names include the CYGWIN_VERSION_SHARED_DATA version
|
||||||
|
as well as this identifier. */
|
||||||
|
|
||||||
|
#define CYGWIN_VERSION_DLL_IDENTIFIER "cygwin1"
|
||||||
|
|
||||||
|
/* The Cygwin mount table interface in the Win32 registry also
|
||||||
|
has a version number associated with it in case that is
|
||||||
|
changed in a non-backwards compatible fashion. Increment this
|
||||||
|
version number whenever incompatible changes in mount table
|
||||||
|
registry usage are made.
|
||||||
|
|
||||||
|
1: Original number version.
|
||||||
|
2: New mount registry layout, system-wide mount accessibility.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CYGWIN_VERSION_MOUNT_REGISTRY 2
|
||||||
|
|
||||||
|
/* Identifiers used in the Win32 registry. */
|
||||||
|
|
||||||
|
#define CYGWIN_INFO_CYGNUS_REGISTRY_NAME "Cygnus Solutions"
|
||||||
|
#define CYGWIN_INFO_CYGWIN_REGISTRY_NAME "Cygwin"
|
||||||
|
#define CYGWIN_INFO_PROGRAM_OPTIONS_NAME "Program Options"
|
||||||
|
#define CYGWIN_INFO_CYGWIN_MOUNT_REGISTRY_NAME "mounts v2"
|
||||||
|
|
||||||
|
/* In addition to the above version number strings, the build
|
||||||
|
process adds some strings that may be useful in
|
||||||
|
debugging/identifying a particular Cygwin DLL:
|
||||||
|
|
||||||
|
The mkvers.sh script at the top level produces a .cc file
|
||||||
|
which initializes a cygwin_version structure based on the
|
||||||
|
above version information and creates a string table for
|
||||||
|
grepping via "fgrep '%%%' cygwinwhatever.dll" if you are
|
||||||
|
using GNU grep. Otherwise you may want to do a
|
||||||
|
"strings cygwinwhatever.dll | fgrep '%%%'" instead.
|
||||||
|
|
||||||
|
This will produce output such as:
|
||||||
|
|
||||||
|
%%% Cygwin dll_identifier: cygwin
|
||||||
|
%%% Cygwin api_major: 0
|
||||||
|
%%% Cygwin api_minor: 0
|
||||||
|
%%% Cygwin dll_major: 19
|
||||||
|
%%% Cygwin dll_minor: 6
|
||||||
|
%%% Cygwin shared_data: 1
|
||||||
|
%%% Cygwin registry: b15
|
||||||
|
%%% Cygwin build date: Wed Oct 14 16:26:51 EDT 1998
|
||||||
|
%%% Cygwin shared id: cygwinS1
|
||||||
|
|
||||||
|
This information can also be obtained through a call to
|
||||||
|
cygwin_internal (CW_GETVERSIONINFO).
|
||||||
|
*/
|
||||||
|
|
41
winsup/cygwin/include/dlfcn.h
Normal file
41
winsup/cygwin/include/dlfcn.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/* dlfcn.h
|
||||||
|
|
||||||
|
Copyright 1998 Cygnus Solutions
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#ifndef _DLFCN_H
|
||||||
|
#define _DLFCN_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* declarations used for dynamic linking support routines */
|
||||||
|
extern void *dlopen (const char *, int);
|
||||||
|
extern void *dlsym (void *, const char *);
|
||||||
|
extern int dlclose (void *);
|
||||||
|
extern char *dlerror (void);
|
||||||
|
|
||||||
|
/* specific to CYGWIN */
|
||||||
|
#define FORK_RELOAD 1
|
||||||
|
#define FORK_NO_RELOAD 0
|
||||||
|
|
||||||
|
extern void dlfork (int);
|
||||||
|
|
||||||
|
/* following doesn't exist in Win32 API .... */
|
||||||
|
|
||||||
|
/* valid values for mode argument to dlopen */
|
||||||
|
#define RTLD_LAZY 1 /* lazy function call binding */
|
||||||
|
#define RTLD_NOW 2 /* immediate function call binding */
|
||||||
|
#define RTLD_GLOBAL 4 /* symbols in this dlopen'ed obj are visible to other dlopen'ed objs */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _DLFCN_H */
|
120
winsup/cygwin/include/exceptions.h
Normal file
120
winsup/cygwin/include/exceptions.h
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/* exceptions.h
|
||||||
|
|
||||||
|
Copyright 1996, 1997, 1998 Cygnus Solutions.
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#ifndef _EXCEPTIONS_H
|
||||||
|
#define _EXCEPTIONS_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
/* Documentation on the innards of exception handling (i.e. from the
|
||||||
|
perspective of a compiler implementor) apparently doesn't exist. Sigh.
|
||||||
|
However, the following came from Onno Hovers <onno@stack.urc.tue.nl>
|
||||||
|
|
||||||
|
The first pointer to the chain of handlers is in the thread environment block
|
||||||
|
at FS:[0]. This chain has the following format:
|
||||||
|
|
||||||
|
typedef struct __EXCEPTION_FRAME
|
||||||
|
{
|
||||||
|
struct __EXCEPTION_FRAME *Prev; /-* pointer to the previous frame *-/
|
||||||
|
PEXCEPTION_HANDLER Handler; /-* handler function *-/
|
||||||
|
}
|
||||||
|
|
||||||
|
You register an exception handler in your compiler with this simple ASM
|
||||||
|
sequence:
|
||||||
|
PUSH _MyExceptionHandler
|
||||||
|
PUSH FS:[0]
|
||||||
|
MOV FS:[0],ESP
|
||||||
|
An exception frame MUST be on the stack! The frame may have more fields and
|
||||||
|
both Visual C++ and Borland C++ use more fields for themselves.
|
||||||
|
|
||||||
|
When an exception occurs the system calls all handlers starting with the
|
||||||
|
handler at FS:0, and then the previous etc. until one handler returns
|
||||||
|
ExceptionContinueExecution, which is 0. If a handler does not want to handle
|
||||||
|
the exception it should just return ExceptionContinueSearch, which is 1.
|
||||||
|
|
||||||
|
The handler has the following parameters:
|
||||||
|
ehandler (
|
||||||
|
PEXCEPTION_RECORD erecord,
|
||||||
|
PEXCEPTION_FRAME myframe,
|
||||||
|
PCONTEXT context, /-* context before and after *-/
|
||||||
|
PVOID dispatch ) /-* something *-/
|
||||||
|
|
||||||
|
When a handler wants to handle the exception, it has some alternatives:
|
||||||
|
|
||||||
|
-one is to do do something about the exception condition, like emulating
|
||||||
|
an invalid instruction, mapping memory where there was a page fault, etc.
|
||||||
|
If the handler wants to have the context of the thread that causes the
|
||||||
|
exception changed, it should make that change in the context passed to the
|
||||||
|
handler.
|
||||||
|
|
||||||
|
-the second alternative is to call all exception handlers again, indicating
|
||||||
|
that you want them to clean up. This way all the __finally blocks get
|
||||||
|
executed. After doing that you change the context passed to the handler so
|
||||||
|
the code starts executing in the except block. For this purpose you could
|
||||||
|
call RtlUnwind. This (undocumented) function calls all exception handlers
|
||||||
|
up to but not including the exception frame passed to it. If NULL is passed
|
||||||
|
as exception frame RtlUnwind calls all exception handlers and then exits the
|
||||||
|
process. The parameters to RtlUnwind are:
|
||||||
|
|
||||||
|
RtlUnwind (
|
||||||
|
PEXCEPTION_FRAME endframe,
|
||||||
|
PVOID unusedEip,
|
||||||
|
PEXCEPTION_RECORD erecord,
|
||||||
|
DWORD returnEax)
|
||||||
|
|
||||||
|
You should set unusedEip to the address where RtlUnwind should return like
|
||||||
|
this:
|
||||||
|
PUSH 0
|
||||||
|
PUSH OFFSET ReturnUnwind
|
||||||
|
PUSH 0
|
||||||
|
PUSH 0
|
||||||
|
CALL RtlUnwind
|
||||||
|
ReturnUnwind:
|
||||||
|
.....
|
||||||
|
|
||||||
|
If no EXCEPTION_RECORD is passed, RtlUnwind makes a default exception
|
||||||
|
record. In any case, the ExceptionFlags part of this record has the
|
||||||
|
EH_UNWINDING (=2), flag set. (and EH_EXIT_UNWIND (=4), when NULL is passed as the end
|
||||||
|
frame.).
|
||||||
|
|
||||||
|
The handler for a exception as well as a for unwinds may be executed in the
|
||||||
|
thread causing the exception, but may also be executed in another (special
|
||||||
|
exception) thread. So it is not wise to make any assumptions about that!
|
||||||
|
|
||||||
|
As an alternative you may consider the SetUnhandledExceptionFilter API
|
||||||
|
to install your own exception filter. This one is documented.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* The January 1994 MSJ has an article entitled "Clearer, More Comprehensive
|
||||||
|
Error Processing with Win32 Structured Exception Handling". It goes into
|
||||||
|
a teensy bit of detail of the innards of exception handling (i.e. what we
|
||||||
|
have to do). */
|
||||||
|
|
||||||
|
typedef int (exception_handler)
|
||||||
|
(EXCEPTION_RECORD *, void *, CONTEXT *, void *);
|
||||||
|
|
||||||
|
typedef struct _exception_list
|
||||||
|
{
|
||||||
|
struct _exception_list *prev;
|
||||||
|
exception_handler *handler;
|
||||||
|
|
||||||
|
/* We're apparently free to add more stuff here.
|
||||||
|
At present we don't need any. */
|
||||||
|
} exception_list;
|
||||||
|
|
||||||
|
void init_exceptions (exception_list *);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
};
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif /* _EXCEPTIONS_H */
|
7
winsup/cygwin/include/fcntl.h
Normal file
7
winsup/cygwin/include/fcntl.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#ifndef _FCNTL_H
|
||||||
|
#define _FCNTL_H
|
||||||
|
|
||||||
|
#include <sys/fcntl.h>
|
||||||
|
#define O_NDELAY _FNDELAY
|
||||||
|
|
||||||
|
#endif /* _FCNTL_H */
|
1
winsup/cygwin/include/features.h
Normal file
1
winsup/cygwin/include/features.h
Normal file
@ -0,0 +1 @@
|
|||||||
|
/* features.h */
|
66
winsup/cygwin/include/getopt.h
Normal file
66
winsup/cygwin/include/getopt.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1987, 1993, 1994, 1996
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GETOPT_H__
|
||||||
|
#define __GETOPT_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct option {
|
||||||
|
char * name;
|
||||||
|
int has_arg;
|
||||||
|
int * flag;
|
||||||
|
int val;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int opterr; /* if error message should be printed */
|
||||||
|
extern int optind; /* index into parent argv vector */
|
||||||
|
extern int optopt; /* character checked for validity */
|
||||||
|
extern int optreset; /* reset getopt */
|
||||||
|
extern char *optarg; /* argument associated with option */
|
||||||
|
|
||||||
|
int getopt (int, char * const *, const char *);
|
||||||
|
|
||||||
|
int getopt_long (int, char **, char *, struct option *, int *);
|
||||||
|
|
||||||
|
#define no_argument 0
|
||||||
|
#define required_argument 1
|
||||||
|
#define optional_argument 2
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __GETOPT_H__ */
|
111
winsup/cygwin/include/glob.h
Normal file
111
winsup/cygwin/include/glob.h
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
/* $NetBSD: glob.h,v 1.6.2.2 1997/11/04 23:38:33 thorpej Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1989, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Guido van Rossum.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @(#)glob.h 8.1 (Berkeley) 6/2/93
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _GLOB_H_
|
||||||
|
#define _GLOB_H_
|
||||||
|
|
||||||
|
/* CYGNUS LOCAL: end */
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int gl_pathc; /* Count of total paths so far. */
|
||||||
|
int gl_matchc; /* Count of paths matching pattern. */
|
||||||
|
int gl_offs; /* Reserved at beginning of gl_pathv. */
|
||||||
|
int gl_flags; /* Copy of flags parameter to glob. */
|
||||||
|
char **gl_pathv; /* List of paths matching pattern. */
|
||||||
|
/* Copy of errfunc parameter to glob. */
|
||||||
|
int (*gl_errfunc) __P((const char *, int));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Alternate filesystem access methods for glob; replacement
|
||||||
|
* versions of closedir(3), readdir(3), opendir(3), stat(2)
|
||||||
|
* and lstat(2).
|
||||||
|
*/
|
||||||
|
void (*gl_closedir) __P((void *));
|
||||||
|
struct dirent *(*gl_readdir) __P((void *));
|
||||||
|
void *(*gl_opendir) __P((const char *));
|
||||||
|
#ifdef __LIBC12_SOURCE__
|
||||||
|
int (*gl_lstat) __P((const char *, struct stat12 *));
|
||||||
|
int (*gl_stat) __P((const char *, struct stat12 *));
|
||||||
|
#else
|
||||||
|
int (*gl_lstat) __P((const char *, struct stat *));
|
||||||
|
int (*gl_stat) __P((const char *, struct stat *));
|
||||||
|
#endif
|
||||||
|
} glob_t;
|
||||||
|
|
||||||
|
#define GLOB_APPEND 0x0001 /* Append to output from previous call. */
|
||||||
|
#define GLOB_DOOFFS 0x0002 /* Use gl_offs. */
|
||||||
|
#define GLOB_ERR 0x0004 /* Return on error. */
|
||||||
|
#define GLOB_MARK 0x0008 /* Append / to matching directories. */
|
||||||
|
#define GLOB_NOCHECK 0x0010 /* Return pattern itself if nothing matches. */
|
||||||
|
#define GLOB_NOSORT 0x0020 /* Don't sort. */
|
||||||
|
|
||||||
|
#ifndef _POSIX_SOURCE
|
||||||
|
#define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */
|
||||||
|
#define GLOB_BRACE 0x0080 /* Expand braces ala csh. */
|
||||||
|
#define GLOB_MAGCHAR 0x0100 /* Pattern had globbing characters. */
|
||||||
|
#define GLOB_NOMAGIC 0x0200 /* GLOB_NOCHECK without magic chars (csh). */
|
||||||
|
#define GLOB_QUOTE 0x0400 /* Quote special chars with \. */
|
||||||
|
#define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define GLOB_NOSPACE (-1) /* Malloc call failed. */
|
||||||
|
#define GLOB_ABEND (-2) /* Unignored error. */
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
/* CYGNUS LOCAL: normal protos */
|
||||||
|
|
||||||
|
#undef DLLEXPORT
|
||||||
|
#ifdef __INSIDE_CYGWIN__
|
||||||
|
# define DLLEXPORT
|
||||||
|
#else
|
||||||
|
# define DLLEXPORT __declspec(dllimport)
|
||||||
|
#endif
|
||||||
|
int DLLEXPORT glob(const char *, int, int (*)(const char *, int), glob_t *);
|
||||||
|
void DLLEXPORT globfree(glob_t *);
|
||||||
|
|
||||||
|
#undef DLLEXPORT
|
||||||
|
/* end CYGNUS LOCAL */
|
||||||
|
__END_DECLS
|
||||||
|
|
||||||
|
#endif /* !_GLOB_H_ */
|
1
winsup/cygwin/include/icmp.h
Normal file
1
winsup/cygwin/include/icmp.h
Normal file
@ -0,0 +1 @@
|
|||||||
|
/* icmp.h */
|
28
winsup/cygwin/include/io.h
Normal file
28
winsup/cygwin/include/io.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/* io.h
|
||||||
|
|
||||||
|
Copyright 1999, 2000 Cygnus Solutions.
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#ifndef _IO_H_
|
||||||
|
#define _IO_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function to return a Win32 HANDLE from a fd.
|
||||||
|
*/
|
||||||
|
extern long get_osfhandle(int);
|
||||||
|
extern int setmode (int __fd, int __mode);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
};
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif /* _IO_H_ */
|
12
winsup/cygwin/include/lastlog.h
Normal file
12
winsup/cygwin/include/lastlog.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#ifndef _LASTLOG_H
|
||||||
|
#define _LASTLOG_H
|
||||||
|
|
||||||
|
#include <utmp.h>
|
||||||
|
|
||||||
|
struct lastlog {
|
||||||
|
long ll_time;
|
||||||
|
char ll_line[UT_LINESIZE];
|
||||||
|
char ll_host[UT_HOSTSIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
144
winsup/cygwin/include/limits.h
Normal file
144
winsup/cygwin/include/limits.h
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
/* limits.h
|
||||||
|
|
||||||
|
Copyright 1999, 2000 Cygnus Solutions.
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#ifndef _LIMITS_H___
|
||||||
|
#ifndef _MACH_MACHLIMITS_H_
|
||||||
|
|
||||||
|
/* _MACH_MACHLIMITS_H_ is used on OSF/1. */
|
||||||
|
#define _LIMITS_H___
|
||||||
|
#define _MACH_MACHLIMITS_H_
|
||||||
|
|
||||||
|
/* Number of bits in a `char'. */
|
||||||
|
#undef CHAR_BIT
|
||||||
|
#define CHAR_BIT 8
|
||||||
|
|
||||||
|
/* Maximum length of a multibyte character. */
|
||||||
|
#ifndef MB_LEN_MAX
|
||||||
|
#define MB_LEN_MAX 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Minimum and maximum values a `signed char' can hold. */
|
||||||
|
#undef SCHAR_MIN
|
||||||
|
#define SCHAR_MIN (-128)
|
||||||
|
#undef SCHAR_MAX
|
||||||
|
#define SCHAR_MAX 127
|
||||||
|
|
||||||
|
/* Maximum value an `unsigned char' can hold. (Minimum is 0). */
|
||||||
|
#undef UCHAR_MAX
|
||||||
|
#define UCHAR_MAX 255
|
||||||
|
|
||||||
|
/* Minimum and maximum values a `char' can hold. */
|
||||||
|
#ifdef __CHAR_UNSIGNED__
|
||||||
|
#undef CHAR_MIN
|
||||||
|
#define CHAR_MIN 0
|
||||||
|
#undef CHAR_MAX
|
||||||
|
#define CHAR_MAX 255
|
||||||
|
#else
|
||||||
|
#undef CHAR_MIN
|
||||||
|
#define CHAR_MIN (-128)
|
||||||
|
#undef CHAR_MAX
|
||||||
|
#define CHAR_MAX 127
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Minimum and maximum values a `signed short int' can hold. */
|
||||||
|
#undef SHRT_MIN
|
||||||
|
#define SHRT_MIN (-32768)
|
||||||
|
#undef SHRT_MAX
|
||||||
|
#define SHRT_MAX 32767
|
||||||
|
|
||||||
|
/* Maximum value an `unsigned short int' can hold. (Minimum is 0). */
|
||||||
|
#undef USHRT_MAX
|
||||||
|
#define USHRT_MAX 65535
|
||||||
|
|
||||||
|
/* Minimum and maximum values a `signed int' can hold. */
|
||||||
|
#ifndef __INT_MAX__
|
||||||
|
#define __INT_MAX__ 2147483647
|
||||||
|
#endif
|
||||||
|
#undef INT_MIN
|
||||||
|
#define INT_MIN (-INT_MAX-1)
|
||||||
|
#undef INT_MAX
|
||||||
|
#define INT_MAX __INT_MAX__
|
||||||
|
|
||||||
|
/* Maximum value an `unsigned int' can hold. (Minimum is 0). */
|
||||||
|
#undef UINT_MAX
|
||||||
|
#define UINT_MAX (INT_MAX * 2U + 1)
|
||||||
|
|
||||||
|
/* Minimum and maximum values a `signed long int' can hold.
|
||||||
|
(Same as `int'). */
|
||||||
|
#ifndef __LONG_MAX__
|
||||||
|
#ifndef __alpha__
|
||||||
|
#define __LONG_MAX__ 2147483647L
|
||||||
|
#else
|
||||||
|
#define __LONG_MAX__ 9223372036854775807L
|
||||||
|
# endif /* __alpha__ */
|
||||||
|
#endif
|
||||||
|
#undef LONG_MIN
|
||||||
|
#define LONG_MIN (-LONG_MAX-1)
|
||||||
|
#undef LONG_MAX
|
||||||
|
#define LONG_MAX __LONG_MAX__
|
||||||
|
|
||||||
|
/* Maximum value an `unsigned long int' can hold. (Minimum is 0). */
|
||||||
|
#undef ULONG_MAX
|
||||||
|
#define ULONG_MAX (LONG_MAX * 2UL + 1)
|
||||||
|
|
||||||
|
#if defined (__GNU_LIBRARY__) ? defined (__USE_GNU) : !defined (__STRICT_ANSI__)
|
||||||
|
/* Minimum and maximum values a `signed long long int' can hold. */
|
||||||
|
#ifndef __LONG_LONG_MAX__
|
||||||
|
#define __LONG_LONG_MAX__ 9223372036854775807LL
|
||||||
|
#endif
|
||||||
|
#undef LONG_LONG_MIN
|
||||||
|
#define LONG_LONG_MIN (-LONG_LONG_MAX-1)
|
||||||
|
#undef LONG_LONG_MAX
|
||||||
|
#define LONG_LONG_MAX __LONG_LONG_MAX__
|
||||||
|
|
||||||
|
/* Maximum value an `unsigned long long int' can hold. (Minimum is 0). */
|
||||||
|
#undef ULONG_LONG_MAX
|
||||||
|
#define ULONG_LONG_MAX (LONG_LONG_MAX * 2ULL + 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Maximum number of iovcnt in a writev */
|
||||||
|
#undef IOV_MAX
|
||||||
|
#define IOV_MAX (__INT_MAX__-1)
|
||||||
|
|
||||||
|
/* Maximum size of ssize_t */
|
||||||
|
#undef SSIZE_MAX
|
||||||
|
#define SSIZE_MAX (__LONG_MAX__)
|
||||||
|
|
||||||
|
/* Maximum length of a path */
|
||||||
|
#define PATH_MAX (260 - 1 /*NUL*/)
|
||||||
|
|
||||||
|
/* Max num groups for a user, value taken from NT documentation */
|
||||||
|
/* Must match <sys/param.h> NGROUPS */
|
||||||
|
#define NGROUPS_MAX 16
|
||||||
|
|
||||||
|
/* WaitForMultipleObjects can't handle waiting for more than 64 objects.
|
||||||
|
This limits how many children we can fork/spawn off. */
|
||||||
|
#define CHILD_MAX 63
|
||||||
|
|
||||||
|
/* POSIX values */
|
||||||
|
/* These should never vary from one system type to another */
|
||||||
|
/* They represent the minimum values that POSIX systems must support.
|
||||||
|
POSIX-conforming apps must not require larger values. */
|
||||||
|
#define _POSIX_ARG_MAX 4096
|
||||||
|
#define _POSIX_CHILD_MAX 6
|
||||||
|
#define _POSIX_LINK_MAX 8
|
||||||
|
#define _POSIX_MAX_CANON 255
|
||||||
|
#define _POSIX_MAX_INPUT 255
|
||||||
|
#define _POSIX_NAME_MAX 14
|
||||||
|
#define _POSIX_NGROUPS_MAX 0
|
||||||
|
#define _POSIX_OPEN_MAX 16
|
||||||
|
#define _POSIX_PATH_MAX 255
|
||||||
|
#define _POSIX_PIPE_BUF 512
|
||||||
|
#define _POSIX_SSIZE_MAX 32767
|
||||||
|
#define _POSIX_STREAM_MAX 8
|
||||||
|
#define _POSIX_TZNAME_MAX 3
|
||||||
|
|
||||||
|
#endif /* _MACH_MACHLIMITS_H_ */
|
||||||
|
#endif /* _LIMITS_H___ */
|
102
winsup/cygwin/include/mapi.h
Normal file
102
winsup/cygwin/include/mapi.h
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
/* mapi.h
|
||||||
|
|
||||||
|
Copyright 1997, 1998 Cygnus Solutions.
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#ifndef _MAPI_H
|
||||||
|
#define _MAPI_H
|
||||||
|
|
||||||
|
/* Currently this doesn't include all the definitions. It does cover
|
||||||
|
the parts of Simple MAPI required to send mail. */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* FIXME: should this be elsewhere? */
|
||||||
|
typedef unsigned long FLAGS;
|
||||||
|
|
||||||
|
/* FIXME: should this be elsewhere? */
|
||||||
|
#define SUCCESS_SUCCESS 0
|
||||||
|
|
||||||
|
/* FIXME: should this be elsewhere? */
|
||||||
|
typedef unsigned long LHANDLE, FAR *LPLHANDLE;
|
||||||
|
|
||||||
|
|
||||||
|
#define MAPI_E_AMBIGUOUS_RECIPIENT 0x15
|
||||||
|
#define MAPI_E_ATTACHMENT_NOT_FOUND 0xb
|
||||||
|
#define MAPI_E_ATTACHMENT_OPEN_FAILURE 0xc
|
||||||
|
#define MAPI_E_BAD_RECIPTYPE 0xf
|
||||||
|
#define MAPI_E_FAILURE 0x2
|
||||||
|
#define MAPI_E_INSUFFICIENT_MEMORY 0x5
|
||||||
|
#define MAPI_E_INVALID_RECIPS 0x19
|
||||||
|
#define MAPI_E_LOGIN_FAILURE 0x3
|
||||||
|
#define MAPI_E_TEXT_TOO_LARGE 0x12
|
||||||
|
#define MAPI_E_TOO_MANY_FILES 0x9
|
||||||
|
#define MAPI_E_TOO_MANY_RECIPIENTS 0xa
|
||||||
|
#define MAPI_E_UNKNOWN_RECIPIENT 0xe
|
||||||
|
#define MAPI_E_USER_ABORT 0x1
|
||||||
|
#define MAPI_E_TEXT_TOO_LARGE 0x12
|
||||||
|
#define MAPI_DIALOG 0x8
|
||||||
|
#define MAPI_NEW_SESSION 0x2
|
||||||
|
#define MAPI_LOGON_UI 0x1
|
||||||
|
#define MAPI_RECEIPT_REQUESTED 0x2
|
||||||
|
#define MAPI_SENT 0x4
|
||||||
|
#define MAPI_UNREAD 0x1
|
||||||
|
#define MAPI_OLE 0x1
|
||||||
|
#define MAPI_OLE_STATIC 0x2
|
||||||
|
|
||||||
|
#define MAPI_ORIG 0
|
||||||
|
#define MAPI_TO 1
|
||||||
|
#define MAPI_CC 2
|
||||||
|
#define MAPI_BCC 3
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ULONG ulReserved;
|
||||||
|
ULONG flFlags;
|
||||||
|
ULONG nPosition;
|
||||||
|
LPTSTR lpszPathName;
|
||||||
|
LPTSTR lpszFileName;
|
||||||
|
LPVOID lpFileType;
|
||||||
|
} MapiFileDesc, FAR *lpMapiFileDesc;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ULONG ulReserved;
|
||||||
|
ULONG ulRecipClass;
|
||||||
|
LPTSTR lpszName;
|
||||||
|
LPTSTR lpszAddress;
|
||||||
|
ULONG ulEIDSize;
|
||||||
|
LPVOID lpEntryID;
|
||||||
|
} MapiRecipDesc, FAR *lpMapiRecipDesc;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ULONG ulReserved;
|
||||||
|
LPTSTR lpszSubject;
|
||||||
|
LPTSTR lpszNoteText;
|
||||||
|
LPTSTR lpszMessageType;
|
||||||
|
LPTSTR lpszDateReceived;
|
||||||
|
LPTSTR lpszConversationID;
|
||||||
|
FLAGS flFlags;
|
||||||
|
lpMapiRecipDesc lpOriginator;
|
||||||
|
ULONG nRecipCount;
|
||||||
|
lpMapiRecipDesc lpRecips;
|
||||||
|
ULONG nFileCount;
|
||||||
|
lpMapiFileDesc lpFiles;
|
||||||
|
} MapiMessage, FAR *lpMapiMessage;
|
||||||
|
|
||||||
|
ULONG FAR PASCAL MAPISendMail (LHANDLE, ULONG, lpMapiMessage, FLAGS, ULONG);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _MAPI_H */
|
7
winsup/cygwin/include/memory.h
Normal file
7
winsup/cygwin/include/memory.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#ifndef _MEMORY_H
|
||||||
|
#define _MEMORY_H
|
||||||
|
|
||||||
|
/* This allows more things to compile. */
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#endif /* _MEMORY_H */
|
35
winsup/cygwin/include/mntent.h
Normal file
35
winsup/cygwin/include/mntent.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef _MNTENT_H
|
||||||
|
#define _MNTENT_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct mntent
|
||||||
|
{
|
||||||
|
char *mnt_fsname;
|
||||||
|
char *mnt_dir;
|
||||||
|
char *mnt_type;
|
||||||
|
char *mnt_opts;
|
||||||
|
int mnt_freq;
|
||||||
|
int mnt_passno;
|
||||||
|
};
|
||||||
|
|
||||||
|
FILE *setmntent (const char *__filep, const char *__type);
|
||||||
|
struct mntent *getmntent (FILE *__filep);
|
||||||
|
int addmntent (FILE *__filep, const struct mntent *__mnt);
|
||||||
|
int endmntent (FILE *__filep);
|
||||||
|
char *hasmntopt (const struct mntent *__mnt, const char *__opt);
|
||||||
|
|
||||||
|
/* This next file doesn't exist, it is in the registry,
|
||||||
|
however applications need the define to pass to
|
||||||
|
the above calls.
|
||||||
|
*/
|
||||||
|
#ifndef MOUNTED
|
||||||
|
#define MOUNTED "/etc/mtab"
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _MNTENT_H */
|
6
winsup/cygwin/include/net/if.h
Normal file
6
winsup/cygwin/include/net/if.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _NET_IF_H
|
||||||
|
#define _NET_IF_H
|
||||||
|
|
||||||
|
#include <cygwin/if.h>
|
||||||
|
|
||||||
|
#endif /* _NET_IF_H */
|
167
winsup/cygwin/include/netdb.h
Normal file
167
winsup/cygwin/include/netdb.h
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
/* Original linux netdb.h merged with winsock.h types */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1980, 1983, 1988, 1993
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @(#)netdb.h 8.1 (Berkeley) 6/2/93
|
||||||
|
* netdb.h,v 1.1.1.1 1995/02/18 05:34:07 hjl Exp
|
||||||
|
* -
|
||||||
|
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies, and that
|
||||||
|
* the name of Digital Equipment Corporation not be used in advertising or
|
||||||
|
* publicity pertaining to distribution of the document or software without
|
||||||
|
* specific, written prior permission.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
|
||||||
|
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
|
||||||
|
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, 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.
|
||||||
|
* -
|
||||||
|
* --Copyright--
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _NETDB_H_
|
||||||
|
#define _NETDB_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structures returned by network data base library. All addresses are
|
||||||
|
* supplied in host order, and returned in network order (suitable for
|
||||||
|
* use in system calls).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Different from the linux versions - note the shorts.. */
|
||||||
|
struct hostent {
|
||||||
|
const char *h_name; /* official name of host */
|
||||||
|
char **h_aliases; /* alias list */
|
||||||
|
short h_addrtype; /* host address type */
|
||||||
|
short h_length; /* length of address */
|
||||||
|
char **h_addr_list; /* list of addresses from name server */
|
||||||
|
#define h_addr h_addr_list[0] /* address, for backward compatiblity */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Assumption here is that a network number
|
||||||
|
* fits in an unsigned long -- probably a poor one.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct netent {
|
||||||
|
char *n_name; /* official name of net */
|
||||||
|
char **n_aliases; /* alias list */
|
||||||
|
short n_addrtype; /* net address type */
|
||||||
|
unsigned long n_net; /* network # */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct servent {
|
||||||
|
char *s_name; /* official service name */
|
||||||
|
char **s_aliases; /* alias list */
|
||||||
|
short s_port; /* port # */
|
||||||
|
char *s_proto; /* protocol to use */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct protoent
|
||||||
|
{
|
||||||
|
char *p_name; /* official protocol name */
|
||||||
|
char **p_aliases; /* alias list */
|
||||||
|
short p_proto; /* protocol # */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rpcent {
|
||||||
|
char *r_name; /* name of server for this rpc program */
|
||||||
|
char **r_aliases; /* alias list */
|
||||||
|
int r_number; /* rpc program number */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Error return codes from gethostbyname() and gethostbyaddr()
|
||||||
|
* (left in extern int h_errno).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __INSIDE_CYGWIN_NET__
|
||||||
|
extern int h_errno;
|
||||||
|
#else
|
||||||
|
extern __declspec(dllimport) int h_errno;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define NETDB_INTERNAL -1 /* see errno */
|
||||||
|
#define NETDB_SUCCESS 0 /* no problem */
|
||||||
|
#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */
|
||||||
|
#define TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */
|
||||||
|
#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
|
||||||
|
#define NO_DATA 4 /* Valid name, no data record of requested type */
|
||||||
|
#define NO_ADDRESS NO_DATA /* no address, look for MX record */
|
||||||
|
|
||||||
|
#ifndef __INSIDE_CYGWIN_NET__
|
||||||
|
void endhostent (void);
|
||||||
|
void endnetent (void);
|
||||||
|
void endprotoent (void);
|
||||||
|
void endservent (void);
|
||||||
|
void endrpcent (void);
|
||||||
|
struct hostent *gethostbyaddr (const char *, int, int);
|
||||||
|
struct hostent *gethostbyname (const char *);
|
||||||
|
struct hostent *gethostent (void);
|
||||||
|
struct netent *getnetbyaddr (long, int); /* u_long? */
|
||||||
|
struct netent *getnetbyname (const char *);
|
||||||
|
struct netent *getnetent (void);
|
||||||
|
struct protoent *getprotobyname (const char *);
|
||||||
|
struct protoent *getprotobynumber (int);
|
||||||
|
struct protoent *getprotoent (void);
|
||||||
|
struct servent *getservbyname (const char *, const char *);
|
||||||
|
struct servent *getservbyport (int, const char *);
|
||||||
|
struct servent *getservent (void);
|
||||||
|
struct rpcent *getrpcent (void);
|
||||||
|
struct rpcent *getrpcbyname (const char *);
|
||||||
|
struct rpcent *getrpcbynumber (int);
|
||||||
|
void herror (const char *);
|
||||||
|
void sethostent (int);
|
||||||
|
void setnetent (int);
|
||||||
|
void setprotoent (int);
|
||||||
|
void setservent (int);
|
||||||
|
void setrpcent (int);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !_NETDB_H_ */
|
||||||
|
|
6
winsup/cygwin/include/netinet/in.h
Normal file
6
winsup/cygwin/include/netinet/in.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _NETINET_IN_H
|
||||||
|
#define _NETINET_IN_H
|
||||||
|
|
||||||
|
#include <cygwin/in.h>
|
||||||
|
|
||||||
|
#endif /* _NETINET_IN_H */
|
6
winsup/cygwin/include/netinet/ip.h
Normal file
6
winsup/cygwin/include/netinet/ip.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _NETINET_IP_H
|
||||||
|
#define _NETINET_IP_H
|
||||||
|
|
||||||
|
#include <cygwin/ip.h>
|
||||||
|
|
||||||
|
#endif /* _NETINET_IP_H */
|
6
winsup/cygwin/include/netinet/ip_icmp.h
Normal file
6
winsup/cygwin/include/netinet/ip_icmp.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _NETINET_IP_ICMP_H
|
||||||
|
#define _NETINET_IP_ICMP_H
|
||||||
|
|
||||||
|
#include <cygwin/icmp.h>
|
||||||
|
|
||||||
|
#endif /* _NETINET_IP_ICMP_H */
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user