Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcvs2svn <>2003-09-01 20:47:04 +0400
committercvs2svn <>2003-09-01 20:47:04 +0400
commit2faac9e9f361dae261d6bf838321648816076061 (patch)
tree2f5f8a1b0d52c08bcc76299791878d4f3fa0f54c
parent1910279d014b6b850d52c84d07c6e1bfb570e6e9 (diff)
This commit was manufactured by cvs2svn to create tag 'cr-0x99'.cr-0x99
Sprout from Z-emcb-cygwin_daemon 2003-08-29 08:01:10 UTC cvs2svn 'This commit was manufactured by cvs2svn to create branch 'Z-emcb-' Cherrypick from master 2003-09-01 16:47:03 UTC Christopher Faylor <me@cgf.cx> '* net.cc (dup_ent): Restore check for NULL input.': winsup/cygserver/ChangeLog winsup/cygserver/Makefile.in winsup/cygserver/msg.cc winsup/cygserver/sem.cc winsup/cygserver/threaded_queue.h winsup/cygwin/ChangeLog winsup/cygwin/Makefile.in winsup/cygwin/configure winsup/cygwin/configure.in winsup/cygwin/cygheap.cc winsup/cygwin/cygheap.h winsup/cygwin/dlmalloc.c winsup/cygwin/dlmalloc.h winsup/cygwin/exceptions.cc winsup/cygwin/fhandler.cc winsup/cygwin/heap.cc winsup/cygwin/include/sys/cygwin.h winsup/cygwin/libc/fnmatch.c winsup/cygwin/malloc.cc winsup/cygwin/net.cc winsup/cygwin/path.cc winsup/cygwin/pinfo.h winsup/cygwin/shm.cc winsup/cygwin/signal.cc winsup/cygwin/sigproc.cc winsup/cygwin/sigproc.h winsup/doc/ChangeLog winsup/doc/pathnames.sgml winsup/utils/ChangeLog winsup/utils/Makefile.in winsup/utils/kill.cc Delete: winsup/cygwin/cygserver.cc winsup/cygwin/cygserver_client.cc winsup/cygwin/cygserver_ipc.h winsup/cygwin/cygserver_process.cc winsup/cygwin/cygserver_shm.cc winsup/cygwin/cygserver_shm.h winsup/cygwin/cygserver_transport.cc winsup/cygwin/cygserver_transport_pipes.cc winsup/cygwin/cygserver_transport_sockets.cc winsup/cygwin/threaded_queue.cc winsup/cygwin/threaded_queue.h
-rw-r--r--winsup/cygserver/ChangeLog9
-rw-r--r--winsup/cygserver/Makefile.in4
-rw-r--r--winsup/cygserver/msg.cc47
-rw-r--r--winsup/cygserver/sem.cc40
-rw-r--r--[-rwxr-xr-x]winsup/cygserver/threaded_queue.h (renamed from winsup/cygwin/threaded_queue.h)0
-rw-r--r--winsup/cygwin/ChangeLog104
-rw-r--r--winsup/cygwin/Makefile.in2
-rwxr-xr-xwinsup/cygwin/configure2
-rw-r--r--winsup/cygwin/configure.in2
-rw-r--r--winsup/cygwin/cygheap.cc3
-rw-r--r--winsup/cygwin/cygheap.h2
-rwxr-xr-xwinsup/cygwin/cygserver.cc773
-rwxr-xr-xwinsup/cygwin/cygserver_client.cc528
-rw-r--r--winsup/cygwin/cygserver_ipc.h84
-rwxr-xr-xwinsup/cygwin/cygserver_process.cc431
-rwxr-xr-xwinsup/cygwin/cygserver_shm.cc896
-rw-r--r--winsup/cygwin/cygserver_shm.h147
-rwxr-xr-xwinsup/cygwin/cygserver_transport.cc51
-rwxr-xr-xwinsup/cygwin/cygserver_transport_pipes.cc362
-rwxr-xr-xwinsup/cygwin/cygserver_transport_sockets.cc387
-rw-r--r--winsup/cygwin/dlmalloc.c79
-rw-r--r--winsup/cygwin/dlmalloc.h29
-rw-r--r--winsup/cygwin/exceptions.cc12
-rw-r--r--winsup/cygwin/fhandler.cc2
-rw-r--r--winsup/cygwin/heap.cc3
-rw-r--r--winsup/cygwin/include/sys/cygwin.h6
-rw-r--r--winsup/cygwin/libc/fnmatch.c12
-rw-r--r--winsup/cygwin/malloc.cc2
-rw-r--r--winsup/cygwin/net.cc383
-rw-r--r--winsup/cygwin/path.cc2
-rw-r--r--winsup/cygwin/pinfo.h7
-rw-r--r--winsup/cygwin/shm.cc2
-rw-r--r--winsup/cygwin/signal.cc6
-rw-r--r--winsup/cygwin/sigproc.cc39
-rw-r--r--winsup/cygwin/sigproc.h1
-rwxr-xr-xwinsup/cygwin/threaded_queue.cc408
-rw-r--r--winsup/doc/ChangeLog6
-rw-r--r--winsup/doc/pathnames.sgml69
-rw-r--r--winsup/utils/ChangeLog15
-rw-r--r--winsup/utils/Makefile.in2
-rw-r--r--winsup/utils/kill.cc12
41 files changed, 539 insertions, 4432 deletions
diff --git a/winsup/cygserver/ChangeLog b/winsup/cygserver/ChangeLog
index fcc3b28a5..813192a49 100644
--- a/winsup/cygserver/ChangeLog
+++ b/winsup/cygserver/ChangeLog
@@ -1,3 +1,12 @@
+2003-08-30 Christopher Faylor <cgf@redhat.com>
+
+ * msg.cc: New file.
+ * sem.cc: Ditto.
+
+2003-08-30 Christopher Faylor <cgf@redhat.com>
+
+ * threaded_queue.h: New file.
+
2003-08-25 Christopher Faylor <cgf@redhat.com>
* Makefile.in: Build libcygserver.a.
diff --git a/winsup/cygserver/Makefile.in b/winsup/cygserver/Makefile.in
index b0396340a..5780dab99 100644
--- a/winsup/cygserver/Makefile.in
+++ b/winsup/cygserver/Makefile.in
@@ -37,8 +37,8 @@ override CXXFLAGS+=-fno-exceptions -fno-rtti -DHAVE_DECL_GETOPT=0 -D__OUTSIDE_CY
include $(srcdir)/../Makefile.common
-OBJS:= cygserver.o client.o process.o shm.o threaded_queue.o transport.o \
- transport_pipes.o transport_sockets.o
+OBJS:= cygserver.o client.o process.o msg.o sem.o shm.o threaded_queue.o \
+ transport.o transport_pipes.o transport_sockets.o
LIBOBJS:=${patsubst %.o,lib%.o,$(OBJS)}
CYGWIN_OBJS:=$(cygwin_build)/smallprint.o $(cygwin_build)/version.o \
diff --git a/winsup/cygserver/msg.cc b/winsup/cygserver/msg.cc
new file mode 100644
index 000000000..fecaa068a
--- /dev/null
+++ b/winsup/cygserver/msg.cc
@@ -0,0 +1,47 @@
+/* msg.cc: Single unix specification IPC interface for Cygwin.
+
+ Copyright 2002 Red Hat, Inc.
+
+ Written by Conrad Scott <conrad.scott@dsl.pipex.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 <sys/types.h>
+#include <cygwin/msg.h>
+
+
+#include "cygerrno.h"
+
+extern "C" int
+msgctl (int msqid, int cmd, struct msqid_ds *buf)
+{
+ set_errno (ENOSYS);
+ return -1;
+}
+
+extern "C" int
+msgget (key_t key, int msgflg)
+{
+ set_errno (ENOSYS);
+ return -1;
+}
+
+extern "C" ssize_t
+msgrcv (int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
+{
+ set_errno (ENOSYS);
+ return -1;
+}
+
+extern "C" int
+msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg)
+{
+ set_errno (ENOSYS);
+ return -1;
+}
diff --git a/winsup/cygserver/sem.cc b/winsup/cygserver/sem.cc
new file mode 100644
index 000000000..97d91a354
--- /dev/null
+++ b/winsup/cygserver/sem.cc
@@ -0,0 +1,40 @@
+/* sem.cc: Single unix specification IPC interface for Cygwin.
+
+ Copyright 2002 Red Hat, Inc.
+
+ Written by Conrad Scott <conrad.scott@dsl.pipex.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 <sys/types.h>
+#include <cygwin/sem.h>
+
+
+#include "cygerrno.h"
+
+extern "C" int
+semctl (int semid, int semnum, int cmd, ...)
+{
+ set_errno (ENOSYS);
+ return -1;
+}
+
+extern "C" int
+semget (key_t key, int nsems, int semflg)
+{
+ set_errno (ENOSYS);
+ return -1;
+}
+
+extern "C" int
+semop (int semid, struct sembuf *sops, size_t nsops)
+{
+ set_errno (ENOSYS);
+ return -1;
+}
diff --git a/winsup/cygwin/threaded_queue.h b/winsup/cygserver/threaded_queue.h
index 5b6fddc42..5b6fddc42 100755..100644
--- a/winsup/cygwin/threaded_queue.h
+++ b/winsup/cygserver/threaded_queue.h
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 8810d54cd..3d4140afb 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,107 @@
+2003-09-01 Christopher Faylor <cgf@redhat.com>
+
+ * net.cc (dup_ent): Restore check for NULL input.
+
+2003-08-31 Christopher Faylor <cgf@redhat.com>
+
+ * include/sys/cygwin.h: Don't define cygwin-specific things if
+ !__CYGWIN__.
+
+2003-08-31 Christopher Faylor <cgf@redhat.com>
+
+ * cygheap.cc (cygheap_init): Allocate space for sigaction array in
+ cygheap.
+ * cygheap.h (cygheap_types): Add HEAP_SIGS.
+ * exceptions.cc (signal_fixup_after_exec): Remove from this file.
+ * pinfo.h (pinfo::getsig): Just return global_sigs array.
+ (pinfo::sigs): Delete.
+ * sigproc.cc (signal_fixup_after_exec): Move it here.
+ (global_sigs): New global array, moved from pinfo structure.
+ (sigalloc): New function. Allocate global sigaction array here.
+ (proc_subproc): Remove copysigs call. It's automatic now.
+ * include/sys/cygwin.h (PID_NOCLDSTOP): New value.
+ * signal.cc (sigaction): Set myself->PID_NODCLDSTOP when appropriate.
+ * sigproc.h (sigalloc): Declare.
+
+ * fnmatch.c (fnmatch): Use C90 parameters.
+ (rangematch): Ditto.
+
+ * fhandler.cc (fhandler_base::raw_read): Use right coercion to avoid a
+ compiler warning.
+
+2003-08-31 Christopher Faylor <cgf@redhat.com>
+
+ * net.cc (dup_ent): Make debugging output consistent.
+
+2003-08-31 Christopher Faylor <cgf@redhat.com>
+
+ Use dup_ent rather than specific dup_*_ptr functions throughout.
+ * (gen_ent): Delete.
+ (dup_ent): Subsume gen_ent functionality.
+ (dup_host_ptr): Delete.
+ (dup_proto_ptr): Ditto.
+ (dup_servent_ptr): Ditto.
+
+2003-08-31 Christopher Faylor <cgf@redhat.com>
+
+ * net.cc (gen_ent): Invert sense of null check so that debug output
+ makes sense.
+
+2003-08-31 Christopher Faylor <cgf@redhat.com>
+
+ * net.cc (free_char_list): Delete.
+ (dup_addr_list): Delete.
+ (dup_char_list): Delete.
+ (free_hostent_ptr): Delete.
+ (free_protoent_ptr): Delete.
+ (free_servent_ptr): Delete.
+ (DWORD_round): New function.
+ (strlen_round): New function. Returns strlen rounded up to word size.
+ (dup_ent): New, generic function to duplicate a {host,proto,serv}ent
+ structure.
+ (gen_ent): New macro. Generates a generic dup_{host,proto,serv}ent_ptr
+ function.
+ (cygwin_getservbyname): Remove call to free_servent_ptr, pass
+ servent_buf to dup_servent_ptr.
+ (cygwin_getservbyport): Ditto.
+ (cygwin_gethostbyname): Ditto for hostent.
+ (cygwin_gethostbyaddr): Ditto.
+ (cygwin_getprotobyname): Ditto for protoent.
+ (cygwin_getprotobynumber): Ditto.
+
+2003-08-31 Christopher Faylor <cgf@redhat.com>
+
+ * Makefile.in (MALLOC_OFILES): Always fill in with correct malloc
+ object.
+ * configure.in: Fill in MALLOC_OFILES with either debugging or regular
+ malloc.
+ * configure: Regenerate.
+ * dlmalloc.c: Make various fruitless changes to attempt to get to work.
+ * dlmalloc.h: Ditto.
+ * malloc.cc (free): Check malloc pool when debugging.
+
+ * path.cc (win32_device_name): Eliminate compiler warning.
+
+ * sigproc.cc (sig_dispatch_pending): Remove use of was_pending. Let
+ thisframe.call_signal_handler decide if handler should be called rather
+ than using bogus was_pending check.
+
+ * exceptions.cc (interrupt_setup): Remove accidentally checked in
+ debugging code.
+
+2003-08-30 Christopher Faylor <cgf@redhat.com>
+
+ * heap.cc (sbrk): Save rounded addess in user_heap_max.
+
+2003-08-30 Christopher Faylor <cgf@redhat.com>
+
+ * sigproc.cc (sig_dispatch_pending): Remove explicit call to
+ thisframe.call_signal_handler.
+
+2003-08-30 Christopher Faylor <cgf@redhat.com>
+
+ Remove some cygserver files.
+
2003-08-28 Christopher Faylor <cgf@redhat.com>
* sigproc.h: Make some functions regparm.
diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in
index 6a54a1cc3..41dad9621 100644
--- a/winsup/cygwin/Makefile.in
+++ b/winsup/cygwin/Makefile.in
@@ -152,7 +152,7 @@ DLL_OFILES:=assert.o autoload.o cxx.o cygheap.o cygthread.o dcrt0.o debug.o \
fhandler_socket.o fhandler_tape.o fhandler_termios.o \
fhandler_tty.o fhandler_virtual.o fhandler_windows.o \
fhandler_zero.o fnmatch.o fork.o glob.o grp.o heap.o init.o ioctl.o \
- ipc.o localtime.o malloc.o malloc_wrapper.o miscfuncs.o mmap.o msg.o \
+ ipc.o localtime.o malloc_wrapper.o miscfuncs.o mmap.o msg.o \
net.o netdb.o ntea.o passwd.o path.o pinfo.o pipe.o poll.o pthread.o \
regcomp.o regerror.o regexec.o regfree.o registry.o resource.o \
scandir.o sched.o sec_acl.o sec_helper.o security.o select.o sem.o \
diff --git a/winsup/cygwin/configure b/winsup/cygwin/configure
index 3500fad38..eb1b6889a 100755
--- a/winsup/cygwin/configure
+++ b/winsup/cygwin/configure
@@ -1916,7 +1916,7 @@ esac
fi
-MALLOC_OFILES=
+MALLOC_OFILES=malloc.o
# Check whether --enable-malloc-debugging or --disable-malloc-debugging was given.
if test "${enable_malloc_debugging+set}" = set; then
enableval="$enable_malloc_debugging"
diff --git a/winsup/cygwin/configure.in b/winsup/cygwin/configure.in
index c0ad97682..d47b4084f 100644
--- a/winsup/cygwin/configure.in
+++ b/winsup/cygwin/configure.in
@@ -145,7 +145,7 @@ no) LIBSERVER=;;
esac
])
-MALLOC_OFILES=
+MALLOC_OFILES=malloc.o
AC_ARG_ENABLE(malloc-debugging,
[ --enable-malloc-debugging Build a cygwin DLL with heap sanity checking (this is very slow, use only if you have heap corruption problems)],
[case "${enableval}" in
diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc
index c79b0017c..07151e960 100644
--- a/winsup/cygwin/cygheap.cc
+++ b/winsup/cygwin/cygheap.cc
@@ -22,6 +22,7 @@
#include "heap.h"
#include "sync.h"
#include "shared_info.h"
+#include "sigproc.h"
init_cygheap NO_COPY *cygheap;
void NO_COPY *cygheap_max;
@@ -203,6 +204,8 @@ cygheap_init ()
}
if (!cygheap->fdtab)
cygheap->fdtab.init ();
+ if (!cygheap->sigs)
+ sigalloc ();
}
/* Copyright (C) 1997, 2000 DJ Delorie */
diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h
index 2211af2be..7a637fa04 100644
--- a/winsup/cygwin/cygheap.h
+++ b/winsup/cygwin/cygheap.h
@@ -17,6 +17,7 @@ enum cygheap_types
HEAP_ARGV,
HEAP_BUF,
HEAP_MOUNT,
+ HEAP_SIGS,
HEAP_1_START,
HEAP_1_STR,
HEAP_1_ARGV,
@@ -255,6 +256,7 @@ struct init_cygheap
#ifdef DEBUGGING
cygheap_debug debug;
#endif
+ struct sigaction *sigs;
};
#define CYGHEAPSIZE (sizeof (init_cygheap) + (16000 * sizeof (fhandler_union)) + (5 * 65536))
diff --git a/winsup/cygwin/cygserver.cc b/winsup/cygwin/cygserver.cc
deleted file mode 100755
index 137730f9e..000000000
--- a/winsup/cygwin/cygserver.cc
+++ /dev/null
@@ -1,773 +0,0 @@
-/* cygserver.cc
-
- Copyright 2001, 2002 Red Hat Inc.
-
- Written by Egor Duda <deo@logos-m.ru>
-
-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 "woutsup.h"
-
-#include <sys/types.h>
-
-#include <assert.h>
-#include <ctype.h>
-#include <getopt.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "cygerrno.h"
-#include "cygwin_version.h"
-
-#include "cygwin/cygserver.h"
-#include "cygwin/cygserver_process.h"
-#include "cygwin/cygserver_transport.h"
-
-// Version string.
-static const char version[] = "$Revision$";
-
-/*
- * Support function for the XXX_printf () macros in "woutsup.h".
- * Copied verbatim from "strace.cc".
- */
-static int
-getfunc (char *in_dst, const char *func)
-{
- const char *p;
- const char *pe;
- char *dst = in_dst;
- for (p = func; (pe = strchr (p, '(')); p = pe + 1)
- if (isalnum ((int)pe[-1]) || pe[-1] == '_')
- break;
- else if (isspace ((int)pe[-1]))
- {
- pe--;
- break;
- }
- if (!pe)
- pe = strchr (func, '\0');
- for (p = pe; p > func; p--)
- if (p != pe && *p == ' ')
- {
- p++;
- break;
- }
- if (*p == '*')
- p++;
- while (p < pe)
- *dst++ = *p++;
-
- *dst++ = ':';
- *dst++ = ' ';
- *dst = '\0';
-
- return dst - in_dst;
-}
-
-/*
- * Support function for the XXX_printf () macros in "woutsup.h".
- */
-extern "C" void
-__cygserver__printf (const char *const function, const char *const fmt, ...)
-{
- const DWORD lasterror = GetLastError ();
- const int lasterrno = errno;
-
- va_list ap;
-
- char *const buf = (char *) alloca (BUFSIZ);
-
- assert (buf);
-
- int len = 0;
-
- if (function)
- len += getfunc (buf, function);
-
- va_start (ap, fmt);
- len += vsnprintf (buf + len, BUFSIZ - len, fmt, ap);
- va_end (ap);
-
- len += snprintf (buf + len, BUFSIZ - len, "\n");
-
- const int actual = (len > BUFSIZ ? BUFSIZ : len);
-
- write (2, buf, actual);
-
- errno = lasterrno;
- SetLastError (lasterror);
-
- return;
-}
-
-#ifdef DEBUGGING
-
-int __stdcall
-__set_errno (const char *func, int ln, int val)
-{
- debug_printf ("%s:%d val %d", func, ln, val);
- return _impure_ptr->_errno = val;
-}
-
-#endif /* DEBUGGING */
-
-GENERIC_MAPPING access_mapping;
-
-static BOOL
-setup_privileges ()
-{
- BOOL rc, ret_val;
- HANDLE hToken = NULL;
- TOKEN_PRIVILEGES sPrivileges;
-
- rc = OpenProcessToken (GetCurrentProcess () , TOKEN_ALL_ACCESS , &hToken) ;
- if (!rc)
- {
- system_printf ("error opening process token (%lu)", GetLastError ());
- ret_val = FALSE;
- goto out;
- }
- rc = LookupPrivilegeValue (NULL, SE_DEBUG_NAME, &sPrivileges.Privileges[0].Luid);
- if (!rc)
- {
- system_printf ("error getting privilege luid (%lu)", GetLastError ());
- ret_val = FALSE;
- goto out;
- }
- sPrivileges.PrivilegeCount = 1 ;
- sPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED ;
- rc = AdjustTokenPrivileges (hToken, FALSE, &sPrivileges, 0, NULL, NULL) ;
- if (!rc)
- {
- system_printf ("error adjusting privilege level. (%lu)",
- GetLastError ());
- ret_val = FALSE;
- goto out;
- }
-
- access_mapping.GenericRead = FILE_READ_DATA;
- access_mapping.GenericWrite = FILE_WRITE_DATA;
- access_mapping.GenericExecute = 0;
- access_mapping.GenericAll = FILE_READ_DATA | FILE_WRITE_DATA;
-
- ret_val = TRUE;
-
-out:
- CloseHandle (hToken);
- return ret_val;
-}
-
-int
-check_and_dup_handle (HANDLE from_process, HANDLE to_process,
- HANDLE from_process_token,
- DWORD access,
- HANDLE from_handle,
- HANDLE *to_handle_ptr, BOOL bInheritHandle = FALSE)
-{
- HANDLE local_handle = NULL;
- int ret_val = EACCES;
-
- if (from_process != GetCurrentProcess ())
- {
- if (!DuplicateHandle (from_process, from_handle,
- GetCurrentProcess (), &local_handle,
- 0, bInheritHandle,
- DUPLICATE_SAME_ACCESS))
- {
- system_printf ("error getting handle(%u) to server (%lu)",
- (unsigned int)from_handle, GetLastError ());
- goto out;
- }
- } else
- local_handle = from_handle;
-
- if (!wincap.has_security ())
- assert (!from_process_token);
- else
- {
- char sd_buf [1024];
- PSECURITY_DESCRIPTOR sd = (PSECURITY_DESCRIPTOR) &sd_buf;
- DWORD bytes_needed;
- PRIVILEGE_SET ps;
- DWORD ps_len = sizeof (ps);
- BOOL status;
-
- if (!GetKernelObjectSecurity (local_handle,
- (OWNER_SECURITY_INFORMATION
- | GROUP_SECURITY_INFORMATION
- | DACL_SECURITY_INFORMATION),
- sd, sizeof (sd_buf), &bytes_needed))
- {
- system_printf ("error getting handle SD (%lu)", GetLastError ());
- goto out;
- }
-
- MapGenericMask (&access, &access_mapping);
-
- if (!AccessCheck (sd, from_process_token, access, &access_mapping,
- &ps, &ps_len, &access, &status))
- {
- system_printf ("error checking access rights (%lu)",
- GetLastError ());
- goto out;
- }
-
- if (!status)
- {
- system_printf ("access to object denied");
- goto out;
- }
- }
-
- if (!DuplicateHandle (from_process, from_handle,
- to_process, to_handle_ptr,
- access, bInheritHandle, 0))
- {
- system_printf ("error getting handle to client (%lu)", GetLastError ());
- goto out;
- }
-
- // verbose: debug_printf ("Duplicated %p to %p", from_handle, *to_handle_ptr);
-
- ret_val = 0;
-
- out:
- if (local_handle && from_process != GetCurrentProcess ())
- CloseHandle (local_handle);
-
- return (ret_val);
-}
-
-/*
- * client_request_attach_tty::serve ()
- */
-
-void
-client_request_attach_tty::serve (transport_layer_base *const conn,
- process_cache *)
-{
- assert (conn);
-
- assert (!error_code ());
-
- if (!wincap.has_security ())
- {
- syscall_printf ("operation only supported on systems with security");
- error_code (EINVAL);
- msglen (0);
- return;
- }
-
- if (msglen () != sizeof (req))
- {
- syscall_printf ("bad request body length: expecting %lu bytes, got %lu",
- sizeof (req), msglen ());
- error_code (EINVAL);
- msglen (0);
- return;
- }
-
- msglen (0); // Until we fill in some fields.
-
- // verbose: debug_printf ("pid %ld:(%p,%p) -> pid %ld",
- // req.master_pid, req.from_master, req.to_master,
- // req.pid);
-
- // verbose: debug_printf ("opening process %ld", req.master_pid);
-
- const HANDLE from_process_handle =
- OpenProcess (PROCESS_DUP_HANDLE, FALSE, req.master_pid);
-
- if (!from_process_handle)
- {
- system_printf ("error opening `from' process, error = %lu",
- GetLastError ());
- error_code (EACCES);
- return;
- }
-
- // verbose: debug_printf ("opening process %ld", req.pid);
-
- const HANDLE to_process_handle =
- OpenProcess (PROCESS_DUP_HANDLE, FALSE, req.pid);
-
- if (!to_process_handle)
- {
- system_printf ("error opening `to' process, error = %lu",
- GetLastError ());
- CloseHandle (from_process_handle);
- error_code (EACCES);
- return;
- }
-
- // verbose: debug_printf ("Impersonating client");
- conn->impersonate_client ();
-
- HANDLE token_handle = NULL;
-
- // verbose: debug_printf ("about to open thread token");
- const DWORD rc = OpenThreadToken (GetCurrentThread (),
- TOKEN_QUERY,
- TRUE,
- &token_handle);
-
- // verbose: debug_printf ("opened thread token, rc=%lu", rc);
- conn->revert_to_self ();
-
- if (!rc)
- {
- system_printf ("error opening thread token, error = %lu",
- GetLastError ());
- CloseHandle (from_process_handle);
- CloseHandle (to_process_handle);
- error_code (EACCES);
- return;
- }
-
- // From this point on, a reply body is returned to the client.
-
- const HANDLE from_master = req.from_master;
- const HANDLE to_master = req.to_master;
-
- req.from_master = NULL;
- req.to_master = NULL;
-
- msglen (sizeof (req));
-
- if (from_master)
- if (check_and_dup_handle (from_process_handle, to_process_handle,
- token_handle,
- GENERIC_READ,
- from_master,
- &req.from_master, TRUE) != 0)
- {
- system_printf ("error duplicating from_master handle, error = %lu",
- GetLastError ());
- error_code (EACCES);
- }
-
- if (to_master)
- if (check_and_dup_handle (from_process_handle, to_process_handle,
- token_handle,
- GENERIC_WRITE,
- to_master,
- &req.to_master, TRUE) != 0)
- {
- system_printf ("error duplicating to_master handle, error = %lu",
- GetLastError ());
- error_code (EACCES);
- }
-
- CloseHandle (from_process_handle);
- CloseHandle (to_process_handle);
- CloseHandle (token_handle);
-
- debug_printf ("%lu(%lu, %lu) -> %lu(%lu,%lu)",
- req.master_pid, from_master, to_master,
- req.pid, req.from_master, req.to_master);
-
- return;
-}
-
-void
-client_request_get_version::serve (transport_layer_base *, process_cache *)
-{
- assert (!error_code ());
-
- if (msglen ())
- syscall_printf ("unexpected request body ignored: %lu bytes", msglen ());
-
- msglen (sizeof (version));
-
- version.major = CYGWIN_SERVER_VERSION_MAJOR;
- version.api = CYGWIN_SERVER_VERSION_API;
- version.minor = CYGWIN_SERVER_VERSION_MINOR;
- version.patch = CYGWIN_SERVER_VERSION_PATCH;
-}
-
-class server_request : public queue_request
-{
-public:
- server_request (transport_layer_base *const conn, process_cache *const cache)
- : _conn (conn), _cache (cache)
- {}
-
- virtual ~server_request ()
- {
- safe_delete (_conn);
- }
-
- virtual void process ()
- {
- client_request::handle_request (_conn, _cache);
- }
-
-private:
- transport_layer_base *const _conn;
- process_cache *const _cache;
-};
-
-class server_submission_loop : public queue_submission_loop
-{
-public:
- server_submission_loop (threaded_queue *const queue,
- transport_layer_base *const transport,
- process_cache *const cache)
- : queue_submission_loop (queue, false),
- _transport (transport),
- _cache (cache)
- {
- assert (_transport);
- assert (_cache);
- }
-
-private:
- transport_layer_base *const _transport;
- process_cache *const _cache;
-
- virtual void request_loop ();
-};
-
-/* FIXME: this is a little ugly. What we really want is to wait on
- * two objects: one for the pipe/socket, and one for being told to
- * shutdown. Otherwise this will stay a problem (we won't actually
- * shutdown until the request _AFTER_ the shutdown request. And
- * sending ourselves a request is ugly
- */
-void
-server_submission_loop::request_loop ()
-{
- /* I'd like the accepting thread's priority to be above any "normal"
- * thread in the system to avoid overflowing the listen queue (for
- * sockets; similar issues exist for named pipes); but, for example,
- * a normal priority thread in a foregrounded process is boosted to
- * THREAD_PRIORITY_HIGHEST (AFAICT). Thus try to set the current
- * thread's priority to a level one above that. This fails on
- * win9x/ME so assume any failure in that call is due to that and
- * simply call again at one priority level lower.
- */
- if (!SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST + 1))
- if (!SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST))
- debug_printf ("failed to raise accept thread priority, error = %lu",
- GetLastError ());
-
- while (_running)
- {
- bool recoverable = false;
- transport_layer_base *const conn = _transport->accept (&recoverable);
- if (!conn && !recoverable)
- {
- system_printf ("fatal error on IPC transport: closing down");
- return;
- }
- // EINTR probably implies a shutdown request; so back off for a
- // moment to let the main thread take control, otherwise the
- // server spins here receiving EINTR repeatedly since the signal
- // handler in the main thread doesn't get a chance to be called.
- if (!conn && errno == EINTR)
- {
- if (!SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_NORMAL))
- debug_printf ("failed to reset thread priority, error = %lu",
- GetLastError ());
-
- Sleep (0);
- if (!SetThreadPriority (GetCurrentThread (),
- THREAD_PRIORITY_HIGHEST + 1))
- if (!SetThreadPriority (GetCurrentThread (),
- THREAD_PRIORITY_HIGHEST))
- debug_printf ("failed to raise thread priority, error = %lu",
- GetLastError ());
- }
- if (conn)
- _queue->add (safe_new (server_request, conn, _cache));
- }
-}
-
-client_request_shutdown::client_request_shutdown ()
- : client_request (CYGSERVER_REQUEST_SHUTDOWN)
-{
- // verbose: syscall_printf ("created");
-}
-
-void
-client_request_shutdown::serve (transport_layer_base *, process_cache *)
-{
- assert (!error_code ());
-
- if (msglen ())
- syscall_printf ("unexpected request body ignored: %lu bytes", msglen ());
-
- /* FIXME: link upwards, and then this becomes a trivial method call to
- * only shutdown _this queue_
- */
-
- kill (getpid (), SIGINT);
-
- msglen (0);
-}
-
-static sig_atomic_t shutdown_server = false;
-
-static void
-handle_signal (const int signum)
-{
- /* any signal makes us die :} */
-
- shutdown_server = true;
-}
-
-/*
- * print_usage ()
- */
-
-static void
-print_usage (const char *const pgm)
-{
- printf ("Usage: %s [OPTIONS]\n", pgm);
- printf (" -c, --cleanup-threads number of cleanup threads to use\n");
- printf (" -h, --help output usage information and exit\n");
- printf (" -r, --request-threads number of request threads to use\n");
- printf (" -s, --shutdown shutdown the daemon\n");
- printf (" -v, --version output version information and exit\n");
-}
-
-/*
- * print_version ()
- */
-
-static void
-print_version (const char *const pgm)
-{
- char *vn = NULL;
-
- const char *const colon = strchr (version, ':');
-
- if (!colon)
- {
- vn = strdup ("?");
- }
- else
- {
- vn = strdup (colon + 2); // Skip ": "
-
- char *const spc = strchr (vn, ' ');
-
- if (spc)
- *spc = '\0';
- }
-
- char buf[200];
- snprintf (buf, sizeof (buf), "%d.%d.%d(%d.%d/%d/%d)-(%d.%d.%d.%d) %s",
- cygwin_version.dll_major / 1000,
- cygwin_version.dll_major % 1000,
- cygwin_version.dll_minor,
- cygwin_version.api_major,
- cygwin_version.api_minor,
- cygwin_version.shared_data,
- CYGWIN_SERVER_VERSION_MAJOR,
- CYGWIN_SERVER_VERSION_API,
- CYGWIN_SERVER_VERSION_MINOR,
- CYGWIN_SERVER_VERSION_PATCH,
- cygwin_version.mount_registry,
- cygwin_version.dll_build_date);
-
- printf ("%s (cygwin) %s\n", pgm, vn);
- printf ("API version %s\n", buf);
- printf ("Copyright 2001, 2002 Red Hat, Inc.\n");
- printf ("Compiled on %s\n", __DATE__);
-
- free (vn);
-}
-
-/*
- * main ()
- */
-
-int
-main (const int argc, char *argv[])
-{
- const struct option longopts[] = {
- {"cleanup-threads", required_argument, NULL, 'c'},
- {"help", no_argument, NULL, 'h'},
- {"request-threads", required_argument, NULL, 'r'},
- {"shutdown", no_argument, NULL, 's'},
- {"version", no_argument, NULL, 'v'},
- {0, no_argument, NULL, 0}
- };
-
- const char opts[] = "c:hr:sv";
-
- int cleanup_threads = 2;
- int request_threads = 10;
- bool shutdown = false;
-
- const char *pgm = NULL;
-
- if (!(pgm = strrchr (*argv, '\\')) && !(pgm = strrchr (*argv, '/')))
- pgm = *argv;
- else
- pgm++;
-
- wincap.init ();
- if (wincap.has_security ())
- setup_privileges ();
-
- int opt;
-
- while ((opt = getopt_long (argc, argv, opts, longopts, NULL)) != EOF)
- switch (opt)
- {
- case 'c':
- cleanup_threads = atoi (optarg);
- if (cleanup_threads <= 0)
- {
- fprintf (stderr,
- "%s: number of cleanup threads must be positive\n",
- pgm);
- exit (1);
- }
- break;
-
- case 'h':
- print_usage (pgm);
- return 0;
-
- case 'r':
- request_threads = atoi (optarg);
- if (request_threads <= 0)
- {
- fprintf (stderr,
- "%s: number of request threads must be positive\n",
- pgm);
- exit (1);
- }
- break;
-
- case 's':
- shutdown = true;
- break;
-
- case 'v':
- print_version (pgm);
- return 0;
-
- case '?':
- fprintf (stderr, "Try `%s --help' for more information.\n", pgm);
- exit (1);
- }
-
- if (optind != argc)
- {
- fprintf (stderr, "%s: too many arguments\n", pgm);
- exit (1);
- }
-
- if (shutdown)
- {
- /* Setting `cygserver_running' stops the request code making a
- * version request, which is not much to the point.
- */
- cygserver_running = CYGSERVER_OK;
-
- client_request_shutdown req;
-
- if (req.make_request () == -1 || req.error_code ())
- {
- fprintf (stderr, "%s: shutdown request failed: %s\n",
- pgm, strerror (req.error_code ()));
- exit (1);
- }
-
- // FIXME: It would be nice to wait here for the daemon to exit.
-
- return 0;
- }
-
-#define SIGHANDLE(SIG) \
- do \
- { \
- struct sigaction act; \
- \
- act.sa_handler = &handle_signal; \
- act.sa_mask = 0; \
- act.sa_flags = 0; \
- \
- if (sigaction (SIG, &act, NULL) == -1) \
- { \
- system_printf ("failed to install handler for " #SIG ": %s", \
- strerror (errno)); \
- exit (1); \
- } \
- } while (false)
-
- SIGHANDLE (SIGHUP);
- SIGHANDLE (SIGINT);
- SIGHANDLE (SIGTERM);
-
- print_version (pgm);
- setbuf (stdout, NULL);
- printf ("daemon starting up");
-
- threaded_queue request_queue (request_threads);
- printf (".");
-
- transport_layer_base *const transport = create_server_transport ();
- assert (transport);
- printf (".");
-
- process_cache cache (cleanup_threads);
- printf (".");
-
- server_submission_loop submission_loop (&request_queue, transport, &cache);
- printf (".");
-
- request_queue.add_submission_loop (&submission_loop);
- printf (".");
-
- if (transport->listen () == -1)
- {
- exit (1);
- }
- printf (".");
-
- cache.start ();
- printf (".");
-
- request_queue.start ();
- printf (".");
-
- printf ("complete\n");
-
- /* TODO: wait on multiple objects - the thread handle for each
- * request loop + all the process handles. This should be done by
- * querying the request_queue and the process cache for all their
- * handles, and then waiting for (say) 30 seconds. after that we
- * recreate the list of handles to wait on, and wait again. the
- * point of all this abstraction is that we can trivially server
- * both sockets and pipes simply by making a new transport, and then
- * calling request_queue.process_requests (transport2);
- */
- /* WaitForMultipleObjects abort && request_queue && process_queue && signal
- -- if signal event then retrigger it
- */
- while (!shutdown_server && request_queue.running () && cache.running ())
- pause ();
-
- printf ("\nShutdown request received - new requests will be denied\n");
- request_queue.stop ();
- printf ("All pending requests processed\n");
- safe_delete (transport);
- printf ("No longer accepting requests - cygwin will operate in daemonless mode\n");
- cache.stop ();
- printf ("All outstanding process-cache activities completed\n");
- printf ("daemon shutdown\n");
-
- return 0;
-}
diff --git a/winsup/cygwin/cygserver_client.cc b/winsup/cygwin/cygserver_client.cc
deleted file mode 100755
index f6683182d..000000000
--- a/winsup/cygwin/cygserver_client.cc
+++ /dev/null
@@ -1,528 +0,0 @@
-/* cygserver_client.cc
-
- Copyright 2001, 2002 Red Hat Inc.
-
- Written by Egor Duda <deo@logos-m.ru>
-
-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. */
-
-/* to allow this to link into cygwin and the .dll, a little magic is needed. */
-#ifdef __OUTSIDE_CYGWIN__
-#include "woutsup.h"
-#else
-#include "winsup.h"
-#endif
-
-#include <assert.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include "cygerrno.h"
-#include "cygserver_shm.h"
-#include "safe_memory.h"
-
-#include "cygwin/cygserver.h"
-#include "cygwin/cygserver_transport.h"
-
-int cygserver_running = CYGSERVER_UNKNOWN; // Nb: inherited by children.
-
-/* On by default during development. For release, we probably want off
- * by default.
- */
-bool allow_daemon = true; // Nb: inherited by children.
-
-client_request_get_version::client_request_get_version ()
- : client_request (CYGSERVER_REQUEST_GET_VERSION, &version, sizeof (version))
-{
- msglen (0); // No parameters for request.
-
- // verbose: syscall_printf ("created");
-}
-
-/*
- * client_request_get_version::check_version ()
- *
- * The major version and API version numbers must match exactly. An
- * older than expected minor version number is accepted (as long as
- * the first numbers match, that is).
- */
-
-bool
-client_request_get_version::check_version () const
-{
- const bool ok = (version.major == CYGWIN_SERVER_VERSION_MAJOR
- && version.api == CYGWIN_SERVER_VERSION_API
- && version.minor <= CYGWIN_SERVER_VERSION_MINOR);
-
- if (!ok)
- syscall_printf (("incompatible version of cygwin server: "
- "client version %d.%d.%d.%d, "
- "server version %ld.%ld.%ld.%ld"),
- CYGWIN_SERVER_VERSION_MAJOR,
- CYGWIN_SERVER_VERSION_API,
- CYGWIN_SERVER_VERSION_MINOR,
- CYGWIN_SERVER_VERSION_PATCH,
- version.major,
- version.api,
- version.minor,
- version.patch);
-
- return ok;
-}
-
-#ifdef __INSIDE_CYGWIN__
-
-client_request_attach_tty::client_request_attach_tty (DWORD nmaster_pid,
- HANDLE nfrom_master,
- HANDLE nto_master)
- : client_request (CYGSERVER_REQUEST_ATTACH_TTY, &req, sizeof (req))
-{
- req.pid = GetCurrentProcessId ();
- req.master_pid = nmaster_pid;
- req.from_master = nfrom_master;
- req.to_master = nto_master;
-
- syscall_printf (("created: pid = %lu, master_pid = %lu, "
- "from_master = %lu, to_master = %lu"),
- req.pid, req.master_pid, req.from_master, req.to_master);
-}
-
-#else /* !__INSIDE_CYGWIN__ */
-
-client_request_attach_tty::client_request_attach_tty ()
- : client_request (CYGSERVER_REQUEST_ATTACH_TTY, &req, sizeof (req))
-{
- // verbose: syscall_printf ("created");
-}
-
-#endif /* __INSIDE_CYGWIN__ */
-
-/*
- * client_request_attach_tty::send ()
- *
- * Wraps the base method to provide error handling support. If the
- * reply contains a body but is flagged as an error, close any handles
- * that have been returned by cygserver and then discard the message
- * body, i.e. the client either sees a successful result with handles
- * or an unsuccessful result with no handles.
- */
-
-void
-client_request_attach_tty::send (transport_layer_base * const conn)
-{
- client_request::send (conn);
-
- if (msglen () && error_code ())
- {
- if (from_master ())
- CloseHandle (from_master ());
- if (to_master ())
- CloseHandle (to_master ());
- msglen (0);
- }
-}
-
-client_request::header_t::header_t (const request_code_t request_code,
- const size_t msglen)
- : msglen (msglen),
- request_code (request_code)
-{
- assert (request_code >= 0 && request_code < CYGSERVER_REQUEST_LAST);
-}
-
-// FIXME: also check write and read result for -1.
-
-void
-client_request::send (transport_layer_base * const conn)
-{
- assert (conn);
- assert (!(msglen () && !_buf)); // i.e., msglen () implies _buf
- assert (msglen () <= _buflen);
-
- {
- const ssize_t count = conn->write (&_header, sizeof (_header));
-
- if (count != sizeof (_header))
- {
- assert (errno);
- error_code (errno);
- syscall_printf (("request header write failure: "
- "only %ld bytes sent of %ld, "
- "error = %d(%lu)"),
- count, sizeof (_header),
- errno, GetLastError ());
- return;
- }
- }
-
- if (msglen ())
- {
- const ssize_t count = conn->write (_buf, msglen ());
-
- if (count == -1 || (size_t) count != msglen ())
- {
- assert (errno);
- error_code (errno);
- syscall_printf (("request body write failure: "
- "only %ld bytes sent of %ld, "
- "error = %d(%lu)"),
- count, msglen (),
- errno, GetLastError ());
- return;
- }
- }
-
- // verbose: syscall_printf ("request sent (%ld + %ld bytes)",
- // sizeof (_header), msglen ());
-
- {
- const ssize_t count = conn->read (&_header, sizeof (_header));
-
- if (count != sizeof (_header))
- {
- assert (errno);
- error_code (errno);
- syscall_printf (("reply header read failure: "
- "only %ld bytes received of %ld, "
- "error = %d(%lu)"),
- count, sizeof (_header),
- errno, GetLastError ());
- return;
- }
- }
-
- if (msglen () && !_buf)
- {
- system_printf ("no client buffer for reply body: %ld bytes needed",
- msglen ());
- error_code (EINVAL);
- return;
- }
-
- if (msglen () > _buflen)
- {
- system_printf (("client buffer too small for reply body: "
- "have %ld bytes and need %ld"),
- _buflen, msglen ());
- error_code (EINVAL);
- return;
- }
-
- if (msglen ())
- {
- const ssize_t count = conn->read (_buf, msglen ());
-
- if (count == -1 || (size_t) count != msglen ())
- {
- assert (errno);
- error_code (errno);
- syscall_printf (("reply body read failure: "
- "only %ld bytes received of %ld, "
- "error = %d(%lu)"),
- count, msglen (),
- errno, GetLastError ());
- return;
- }
- }
-
- // verbose: syscall_printf ("reply received (%ld + %ld bytes)",
- // sizeof (_header), msglen ());
-}
-
-#ifndef __INSIDE_CYGWIN__
-
-/*
- * client_request::handle_request ()
- *
- * A server-side method.
- *
- * This is a factory method for the client_request subclasses. It
- * reads the incoming request header and, based on its request code,
- * creates an instance of the appropriate class.
- *
- * FIXME: If the incoming packet is malformed, the server drops it on
- * the floor. Should it try and generate some sort of reply for the
- * client? As it is, the client will simply get a broken connection.
- *
- * FIXME: also check write and read result for -1.
- */
-
-/* static */ void
-client_request::handle_request (transport_layer_base *const conn,
- process_cache *const cache)
-{
- // verbose: debug_printf ("about to read");
-
- header_t header;
-
- {
- const ssize_t count = conn->read (&header, sizeof (header));
-
- if (count != sizeof (header))
- {
- syscall_printf (("request header read failure: "
- "only %ld bytes received of %ld, "
- "error = %d(%lu)"),
- count, sizeof (header),
- errno, GetLastError ());
- return;
- }
-
- // verbose: debug_printf ("got header (%ld)", count);
- }
-
- client_request *req = NULL;
-
- switch (header.request_code)
- {
- case CYGSERVER_REQUEST_GET_VERSION:
- req = safe_new0 (client_request_get_version);
- break;
- case CYGSERVER_REQUEST_SHUTDOWN:
- req = safe_new0 (client_request_shutdown);
- break;
- case CYGSERVER_REQUEST_ATTACH_TTY:
- req = safe_new0 (client_request_attach_tty);
- break;
- case CYGSERVER_REQUEST_SHM:
- req = safe_new0 (client_request_shm);
- break;
- default:
- syscall_printf ("unknown request code %d received: request ignored",
- header.request_code);
- return;
- }
-
- assert (req);
-
- req->msglen (header.msglen);
- req->handle (conn, cache);
-
- safe_delete (req);
-
-#ifndef DEBUGGING
- printf ("."); // A little noise when we're being quiet.
-#endif
-}
-
-#endif /* !__INSIDE_CYGWIN__ */
-
-client_request::client_request (request_code_t const id,
- void * const buf,
- size_t const buflen)
- : _header (id, buflen),
- _buf (buf),
- _buflen (buflen)
-{
- assert ((!_buf && !_buflen) || (_buf && _buflen));
-}
-
-client_request::~client_request ()
-{}
-
-int
-client_request::make_request ()
-{
- assert (cygserver_running == CYGSERVER_UNKNOWN \
- || cygserver_running == CYGSERVER_OK \
- || cygserver_running == CYGSERVER_UNAVAIL);
-
- if (cygserver_running == CYGSERVER_UNKNOWN)
- cygserver_init ();
-
- assert (cygserver_running == CYGSERVER_OK \
- || cygserver_running == CYGSERVER_UNAVAIL);
-
- /* Don't retry every request if the server's not there */
- if (cygserver_running == CYGSERVER_UNAVAIL)
- {
- syscall_printf ("cygserver un-available");
- error_code (ENOSYS);
- return -1;
- }
-
- transport_layer_base *const transport = create_server_transport ();
-
- assert (transport);
-
- if (transport->connect () == -1)
- {
- if (errno)
- error_code (errno);
- else
- error_code (ENOSYS);
- safe_delete (transport);
- return -1;
- }
-
- // verbose: debug_printf ("connected to server %p", transport);
-
- send (transport);
-
- safe_delete (transport);
-
- return 0;
-}
-
-#ifndef __INSIDE_CYGWIN__
-
-/*
- * client_request::handle ()
- *
- * A server-side method.
- *
- * At this point, the header of an incoming request has been read and
- * an appropriate client_request object constructed. This method has
- * to read the request body into its buffer, if there is such a body,
- * then perform the request and send back the results to the client.
- *
- * FIXME: If the incoming packet is malformed, the server drops it on
- * the floor. Should it try and generate some sort of reply for the
- * client? As it is, the client will simply get a broken connection.
- *
- * FIXME: also check write and read result for -1.
- */
-
-void
-client_request::handle (transport_layer_base *const conn,
- process_cache *const cache)
-{
- if (msglen () && !_buf)
- {
- system_printf ("no buffer for request body: %ld bytes needed",
- msglen ());
- error_code (EINVAL);
- return;
- }
-
- if (msglen () > _buflen)
- {
- system_printf (("buffer too small for request body: "
- "have %ld bytes and need %ld"),
- _buflen, msglen ());
- error_code (EINVAL);
- return;
- }
-
- if (msglen ())
- {
- const ssize_t count = conn->read (_buf, msglen ());
-
- if (count == -1 || (size_t) count != msglen ())
- {
- assert (errno);
- error_code (errno);
- syscall_printf (("request body read failure: "
- "only %ld bytes received of %ld, "
- "error = %d(%lu)"),
- count, msglen (),
- errno, GetLastError ());
- return;
- }
- }
-
- // verbose: syscall_printf ("request received (%ld + %ld bytes)",
- // sizeof (_header), msglen ());
-
- error_code (0); // Overwrites the _header.request_code field.
-
- /*
- * This is not allowed to fail. We must return ENOSYS at a minimum
- * to the client.
- */
- serve (conn, cache);
-
- {
- const ssize_t count = conn->write (&_header, sizeof (_header));
-
- if (count != sizeof (_header))
- {
- assert (errno);
- error_code (errno);
- syscall_printf (("reply header write failure: "
- "only %ld bytes sent of %ld, "
- "error = %d(%lu)"),
- count, sizeof (_header),
- errno, GetLastError ());
- return;
- }
- }
-
- if (msglen ())
- {
- const ssize_t count = conn->write (_buf, msglen ());
-
- if (count == -1 || (size_t) count != msglen ())
- {
- assert (errno);
- error_code (errno);
- syscall_printf (("reply body write failure: "
- "only %ld bytes sent of %ld, "
- "error = %d(%lu)"),
- count, msglen (),
- errno, GetLastError ());
- return;
- }
- }
-
- // verbose: syscall_printf ("reply sent (%ld + %ld bytes)",
- // sizeof (_header), msglen ());
-}
-
-#endif /* !__INSIDE_CYGWIN__ */
-
-bool
-check_cygserver_available ()
-{
- assert (cygserver_running == CYGSERVER_UNKNOWN \
- || cygserver_running == CYGSERVER_UNAVAIL);
-
- cygserver_running = CYGSERVER_OK; // For make_request ().
-
- client_request_get_version req;
-
- /* This indicates that we failed to connect to cygserver at all but
- * that's fine as cygwin doesn't need it to be running.
- */
- if (req.make_request () == -1)
- return false;
-
- /* We connected to the server but something went wrong after that
- * (in sending the message, in cygserver itself, or in receiving the
- * reply).
- */
- if (req.error_code ())
- {
- syscall_printf ("failure in cygserver version request: %d",
- req.error_code ());
- syscall_printf ("process will continue without cygserver support");
- return false;
- }
-
- return req.check_version ();
-}
-
-void
-cygserver_init ()
-{
- if (!allow_daemon)
- {
- syscall_printf ("cygserver use disabled in client");
- cygserver_running = CYGSERVER_UNAVAIL;
- return;
- }
-
- assert (cygserver_running == CYGSERVER_UNKNOWN \
- || cygserver_running == CYGSERVER_OK \
- || cygserver_running == CYGSERVER_UNAVAIL);
-
- if (cygserver_running == CYGSERVER_OK)
- return;
-
- if (!check_cygserver_available ())
- cygserver_running = CYGSERVER_UNAVAIL;
-}
diff --git a/winsup/cygwin/cygserver_ipc.h b/winsup/cygwin/cygserver_ipc.h
deleted file mode 100644
index 0d0ebbc76..000000000
--- a/winsup/cygwin/cygserver_ipc.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* cygserver_ipc.h
-
- Copyright 2002 Red Hat, Inc.
-
- Originally written by Conrad Scott <conrad.scott@dsl.pipex.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. */
-
-#ifndef __CYGSERVER_IPC_H__
-#define __CYGSERVER_IPC_H__
-
-#include <assert.h>
-#include <limits.h> /* For OPEN_MAX. */
-
-/*
- * The sysv ipc id's (msgid, semid, shmid) are integers arranged such
- * that they no subsystem will generate the same id as some other
- * subsystem; nor do these ids overlap file descriptors (the other
- * common integer ids). Since Cygwin can allocate more than OPEN_MAX
- * file descriptors, it can't be guaranteed not to overlap, but it
- * should help catch some errors.
- *
- * msgid's: OPEN_MAX, OPEN_MAX + 3, OPEN_MAX + 6, . . .
- * semid's: OPEN_MAX + 1, OPEN_MAX + 4, OPEN_MAX + 7, . . .
- * shmid's: OPEN_MAX + 2, OPEN_MAX + 5, OPEN_MAX + 8, . . .
- *
- * To further ensure that ids are unique, if ipc objects are created
- * and destroyed and then re-created, they are given new ids by
- * munging the basic id (as above) with a sequence number.
- *
- * Internal ipc id's, which are 0, 1, ... within each subsystem (and
- * not munged with a sequence number), are used solely by the ipcs(8)
- * interface.
- */
-
-enum ipc_subsys_t
- {
- IPC_MSGOP = 0,
- IPC_SEMOP = 1,
- IPC_SHMOP = 2,
- IPC_SUBSYS_COUNT
- };
-
-/*
- * IPCMNI - The absolute maximum number of simultaneous ipc ids for
- * any one subsystem.
- */
-
-enum
- {
- IPCMNI = 0x10000 // Must be a power of two.
- };
-
-inline int
-ipc_int2ext (const int intid, const ipc_subsys_t subsys, long & sequence)
-{
- assert (0 <= intid && intid < IPCMNI);
-
- const long tmp = InterlockedIncrement (&sequence);
-
- return (((tmp & 0x7fff) << 16)
- | (OPEN_MAX + (intid * IPC_SUBSYS_COUNT) + subsys));
-}
-
-inline int
-ipc_ext2int_subsys (const int extid)
-{
- return ((extid & (IPCMNI - 1)) - OPEN_MAX) % IPC_SUBSYS_COUNT;
-}
-
-inline int
-ipc_ext2int (const int extid, const ipc_subsys_t subsys)
-{
- if (ipc_ext2int_subsys (extid) != subsys)
- return -1;
- else
- return ((extid & (IPCMNI - 1)) - OPEN_MAX) / IPC_SUBSYS_COUNT;
-}
-
-#endif /* __CYGSERVER_IPC_H__ */
diff --git a/winsup/cygwin/cygserver_process.cc b/winsup/cygwin/cygserver_process.cc
deleted file mode 100755
index 2cc7be19c..000000000
--- a/winsup/cygwin/cygserver_process.cc
+++ /dev/null
@@ -1,431 +0,0 @@
-/* cygserver_process.cc
-
- Copyright 2001, 2002 Red Hat Inc.
-
- Written by Robert Collins <rbtcollins@hotmail.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 "woutsup.h"
-
-#include <sys/types.h>
-
-#include <assert.h>
-#include <stdlib.h>
-
-#include "cygerrno.h"
-
-#include "cygwin/cygserver_process.h"
-
-/*****************************************************************************/
-
-#define elements(ARRAY) (sizeof (ARRAY) / sizeof (*ARRAY))
-
-/*****************************************************************************/
-
-process_cleanup::~process_cleanup ()
-{
- safe_delete (_process);
-}
-
-void
-process_cleanup::process ()
-{
- _process->cleanup ();
-}
-
-/*****************************************************************************/
-
-/* cleanup_routine */
-cleanup_routine::~cleanup_routine ()
-{
-}
-
-/*****************************************************************************/
-
-process::process (const pid_t cygpid, const DWORD winpid)
- : _cygpid (cygpid),
- _winpid (winpid),
- _hProcess (NULL),
- _cleaning_up (false),
- _exit_status (STILL_ACTIVE),
- _routines_head (NULL),
- _next (NULL)
-{
- _hProcess = OpenProcess (PROCESS_ALL_ACCESS, FALSE, winpid);
- if (!_hProcess)
- {
- system_printf ("unable to obtain handle for new cache process %d(%lu)",
- _cygpid, _winpid);
- _hProcess = INVALID_HANDLE_VALUE;
- _exit_status = 0;
- }
- else
- debug_printf ("got handle %p for new cache process %d(%lu)",
- _hProcess, _cygpid, _winpid);
- InitializeCriticalSection (&_access);
-}
-
-process::~process ()
-{
- DeleteCriticalSection (&_access);
- (void) CloseHandle (_hProcess);
-}
-
-/* No need to be thread-safe as this is only ever called by
- * process_cache::remove_process (). If it has to be made thread-safe
- * later on, it should not use the `access' critical section as that
- * is held by the client request handlers for an arbitrary length of
- * time, i.e. while they do whatever processing is required for a
- * client request.
- */
-DWORD
-process::check_exit_code ()
-{
- if (_hProcess && _hProcess != INVALID_HANDLE_VALUE
- && _exit_status == STILL_ACTIVE
- && !GetExitCodeProcess (_hProcess, &_exit_status))
- {
- system_printf ("failed to retrieve exit code for %d(%lu), error = %lu",
- _cygpid, _winpid, GetLastError ());
- _hProcess = INVALID_HANDLE_VALUE;
- }
- return _exit_status;
-}
-
-bool
-process::add (cleanup_routine *const entry)
-{
- assert (entry);
-
- bool res = false;
- EnterCriticalSection (&_access);
-
- if (!_cleaning_up)
- {
- entry->_next = _routines_head;
- _routines_head = entry;
- res = true;
- }
-
- LeaveCriticalSection (&_access);
- return res;
-}
-
-bool
-process::remove (const cleanup_routine *const entry)
-{
- assert (entry);
-
- bool res = false;
- EnterCriticalSection (&_access);
-
- if (!_cleaning_up)
- {
- cleanup_routine *previous = NULL;
-
- for (cleanup_routine *ptr = _routines_head;
- ptr;
- previous = ptr, ptr = ptr->_next)
- {
- if (*ptr == *entry)
- {
- if (previous)
- previous->_next = ptr->_next;
- else
- _routines_head = ptr->_next;
-
- safe_delete (ptr);
- res = true;
- break;
- }
- }
- }
-
- LeaveCriticalSection (&_access);
- return res;
-}
-
-/* This is single threaded. It's called after the process is removed
- * from the cache, but inserts may be attemped by worker threads that
- * have a pointer to it.
- */
-void
-process::cleanup ()
-{
- EnterCriticalSection (&_access);
- assert (!is_active ());
- assert (!_cleaning_up);
- InterlockedExchange (&_cleaning_up, true);
- cleanup_routine *entry = _routines_head;
- _routines_head = NULL;
- LeaveCriticalSection (&_access);
-
- while (entry)
- {
- cleanup_routine *const ptr = entry;
- entry = entry->_next;
- ptr->cleanup (this);
- safe_delete (ptr);
- }
-}
-
-/*****************************************************************************/
-
-void
-process_cache::submission_loop::request_loop ()
-{
- assert (this);
- assert (_cache);
- assert (_interrupt_event);
-
- while (_running)
- _cache->wait_for_processes (_interrupt_event);
-}
-
-/*****************************************************************************/
-
-process_cache::process_cache (const unsigned int initial_workers)
- : _queue (initial_workers),
- _submitter (this, &_queue), // true == interruptible
- _processes_count (0),
- _processes_head (NULL),
- _cache_add_trigger (NULL)
-{
- /* there can only be one */
- InitializeCriticalSection (&_cache_write_access);
-
- _cache_add_trigger = CreateEvent (NULL, // SECURITY_ATTRIBUTES
- FALSE, // Auto-reset
- FALSE, // Initially non-signalled
- NULL); // Anonymous
-
- if (!_cache_add_trigger)
- {
- system_printf ("failed to create cache add trigger, error = %lu",
- GetLastError ());
- abort ();
- }
-
- _queue.add_submission_loop (&_submitter);
-}
-
-process_cache::~process_cache ()
-{
- (void) CloseHandle (_cache_add_trigger);
- DeleteCriticalSection (&_cache_write_access);
-}
-
-/* This returns the process object to the caller already locked, that
- * is, with the object's `access' critical region entered. Thus the
- * caller must unlock the object when it's finished with it (via
- * process::release ()). It must then not try to access the object
- * afterwards, except by going through this routine again, as it may
- * have been deleted once it has been unlocked.
- */
-class process *
-process_cache::process (const pid_t cygpid, const DWORD winpid)
-{
- /* TODO: make this more granular, so a search doesn't involve the
- * write lock.
- */
- EnterCriticalSection (&_cache_write_access);
- class process *previous = NULL;
- class process *entry = find (winpid, &previous);
-
- if (!entry)
- {
- if (_processes_count + SPECIALS_COUNT >= MAXIMUM_WAIT_OBJECTS)
- {
- LeaveCriticalSection (&_cache_write_access);
- system_printf (("process limit (%d processes) reached; "
- "new connection refused for %d(%lu)"),
- MAXIMUM_WAIT_OBJECTS - SPECIALS_COUNT,
- cygpid, winpid);
- set_errno (EAGAIN);
- return NULL;
- }
-
- entry = safe_new (class process, cygpid, winpid);
- if (!entry->is_active ())
- {
- LeaveCriticalSection (&_cache_write_access);
- safe_delete (entry);
- set_errno (ESRCH);
- return NULL;
- }
-
- if (previous)
- {
- entry->_next = previous->_next;
- previous->_next = entry;
- }
- else
- {
- entry->_next = _processes_head;
- _processes_head = entry;
- }
-
- _processes_count += 1;
- SetEvent (_cache_add_trigger);
- }
-
- EnterCriticalSection (&entry->_access); // To be released by the caller.
- LeaveCriticalSection (&_cache_write_access);
- assert (entry);
- assert (entry->_winpid == winpid);
- return entry;
-}
-
-void
-process_cache::wait_for_processes (const HANDLE interrupt_event)
-{
- // Update `_wait_array' with handles of all current processes.
- const size_t count = sync_wait_array (interrupt_event);
-
- debug_printf ("waiting on %u objects in total (%u processes)",
- count, _processes_count);
-
- const DWORD rc = WaitForMultipleObjects (count, _wait_array,
- FALSE, INFINITE);
-
- if (rc == WAIT_FAILED)
- {
- system_printf ("could not wait on the process handles, error = %lu",
- GetLastError ());
- abort ();
- }
-
- const size_t start = rc - WAIT_OBJECT_0;
-
- if (rc < WAIT_OBJECT_0 || start > count)
- {
- system_printf (("unexpected return code %rc "
- "from WaitForMultipleObjects: "
- "expected [%u .. %u)"),
- rc, WAIT_OBJECT_0, WAIT_OBJECT_0 + count);
- abort ();
- }
-
- // Tell all the processes, from the signalled point up, the bad news.
- for (size_t index = start; index != count; index++)
- if (_process_array[index])
- check_and_remove_process (index);
-}
-
-/*
- * process_cache::sync_wait_array ()
- *
- * Fill-in the wait array with the handles that the cache needs to wait on.
- * These handles are:
- * - the process_process_param's interrupt event
- * - the process_cache's cache_add_trigger event
- * - the handle for each live process in the cache.
- *
- * Return value: the number of live handles in the array.
- */
-
-size_t
-process_cache::sync_wait_array (const HANDLE interrupt_event)
-{
- assert (this);
- assert (_cache_add_trigger && _cache_add_trigger != INVALID_HANDLE_VALUE);
- assert (interrupt_event && interrupt_event != INVALID_HANDLE_VALUE);
-
- EnterCriticalSection (&_cache_write_access);
-
- assert (_processes_count + SPECIALS_COUNT <= elements (_wait_array));
-
- size_t index = 0;
-
- for (class process *ptr = _processes_head; ptr; ptr = ptr->_next)
- {
- assert (ptr->_hProcess && ptr->_hProcess != INVALID_HANDLE_VALUE);
- assert (ptr->is_active ());
-
- _wait_array[index] = ptr->handle ();
- _process_array[index++] = ptr;
-
- assert (index <= elements (_wait_array));
- }
-
- /* Sorry for shouting, but THESE MUST BE ADDED AT THE END! */
- /* Well, not strictly `must', but it's more efficient if they are :-) */
-
- _wait_array[index] = interrupt_event;
- _process_array[index++] = NULL;
-
- _wait_array[index] = _cache_add_trigger;
- _process_array[index++] = NULL;
-
- /* Phew, back to normal volume now. */
-
- assert (index <= elements (_wait_array));
-
- LeaveCriticalSection (&_cache_write_access);
-
- return index;
-}
-
-void
-process_cache::check_and_remove_process (const size_t index)
-{
- assert (this);
- assert (index < elements (_wait_array) - SPECIALS_COUNT);
-
- class process *const process = _process_array[index];
-
- assert (process);
- assert (process->handle () == _wait_array[index]);
-
- if (process->check_exit_code () == STILL_ACTIVE)
- return;
-
- debug_printf ("process %d(%lu) has left the building ($? = %lu)",
- process->_cygpid, process->_winpid, process->_exit_status);
-
- /* Unlink the process object from the process list. */
-
- EnterCriticalSection (&_cache_write_access);
-
- class process *previous = NULL;
-
- const class process *const tmp = find (process->_winpid, &previous);
-
- assert (tmp == process);
- assert (previous ? previous->_next == process : _processes_head == process);
-
- if (previous)
- previous->_next = process->_next;
- else
- _processes_head = process->_next;
-
- _processes_count -= 1;
- LeaveCriticalSection (&_cache_write_access);
-
- /* Schedule any cleanup tasks for this process. */
- _queue.add (safe_new (process_cleanup, process));
-}
-
-class process *
-process_cache::find (const DWORD winpid, class process **previous)
-{
- if (previous)
- *previous = NULL;
-
- for (class process *ptr = _processes_head; ptr; ptr = ptr->_next)
- if (ptr->_winpid == winpid)
- return ptr;
- else if (ptr->_winpid > winpid) // The list is sorted by winpid.
- return NULL;
- else if (previous)
- *previous = ptr;
-
- return NULL;
-}
-
-/*****************************************************************************/
diff --git a/winsup/cygwin/cygserver_shm.cc b/winsup/cygwin/cygserver_shm.cc
deleted file mode 100755
index 90053eec2..000000000
--- a/winsup/cygwin/cygserver_shm.cc
+++ /dev/null
@@ -1,896 +0,0 @@
-/* cygserver_shm.cc: Single unix specification IPC interface for Cygwin.
-
- Copyright 2002 Red Hat, Inc.
-
- Written by Conrad Scott <conrad.scott@dsl.pipex.com>.
- Based on code by Robert Collins <robert.collins@hotmail.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 "woutsup.h"
-
-#include <errno.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-
-#include "cygserver_ipc.h"
-#include "cygserver_shm.h"
-#include "security.h"
-
-#include "cygwin/cygserver.h"
-#include "cygwin/cygserver_process.h"
-#include "cygwin/cygserver_transport.h"
-
-/*---------------------------------------------------------------------------*
- * class server_shmmgr
- *
- * A singleton class.
- *---------------------------------------------------------------------------*/
-
-#define shmmgr (server_shmmgr::instance ())
-
-class server_shmmgr
-{
-private:
- class attach_t
- {
- public:
- class process *const _client;
- unsigned int _refcnt;
-
- attach_t *_next;
-
- attach_t (class process *const client)
- : _client (client),
- _refcnt (0),
- _next (NULL)
- {}
- };
-
- class segment_t
- {
- private:
- // Bits for the _flg field.
- enum { IS_DELETED = 0x01 };
-
- public:
- const int _intid;
- const int _shmid;
- struct shmid_ds _ds;
-
- segment_t *_next;
-
- segment_t (const key_t key, const int intid, const HANDLE hFileMap);
- ~segment_t ();
-
- bool is_deleted () const
- {
- return _flg & IS_DELETED;
- }
-
- bool is_pending_delete () const
- {
- return !_ds.shm_nattch && is_deleted ();
- }
-
- void mark_deleted ()
- {
- assert (!is_deleted ());
-
- _flg |= IS_DELETED;
- }
-
- int attach (class process *, HANDLE & hFileMap);
- int detach (class process *);
-
- private:
- static long _sequence;
-
- int _flg;
- const HANDLE _hFileMap;
- attach_t *_attach_head; // A list sorted by winpid;
-
- attach_t *find (const class process *, attach_t **previous = NULL);
- };
-
- class cleanup_t : public cleanup_routine
- {
- public:
- cleanup_t (const segment_t *const segptr)
- : cleanup_routine (reinterpret_cast<void *> (segptr->_shmid))
- {
- assert (key ());
- }
-
- int shmid () const { return reinterpret_cast<int> (key ()); }
-
- virtual void cleanup (class process *const client)
- {
- const int res = shmmgr.shmdt (shmid (), client);
-
- if (res != 0)
- debug_printf ("process cleanup failed [shmid = %d]: %s",
- shmid (), strerror (-res));
- }
- };
-
-public:
- static server_shmmgr & instance ();
-
- int shmat (HANDLE & hFileMap,
- int shmid, int shmflg, class process *);
- int shmctl (int & out_shmid, struct shmid_ds & out_ds,
- struct shminfo & out_shminfo, struct shm_info & out_shm_info,
- const int shmid, int cmd, const struct shmid_ds &,
- class process *);
- int shmdt (int shmid, class process *);
- int shmget (int & out_shmid, key_t, size_t, int shmflg, uid_t, gid_t,
- class process *);
-
-private:
- static server_shmmgr *_instance;
- static pthread_once_t _instance_once;
-
- static void initialise_instance ();
-
- CRITICAL_SECTION _segments_lock;
- segment_t *_segments_head; // A list sorted by int_id.
-
- int _shm_ids; // Number of shm segments (for ipcs(8)).
- int _shm_tot; // Total bytes of shm segments (for ipcs(8)).
- int _shm_atts; // Number of attached segments (for ipcs(8)).
- int _intid_max; // Highest intid yet allocated (for ipcs(8)).
-
- server_shmmgr ();
- ~server_shmmgr ();
-
- // Undefined (as this class is a singleton):
- server_shmmgr (const server_shmmgr &);
- server_shmmgr & operator= (const server_shmmgr &);
-
- segment_t *find_by_key (key_t);
- segment_t *find (int intid, segment_t **previous = NULL);
-
- int new_segment (key_t, size_t, int shmflg, pid_t, uid_t, gid_t);
-
- segment_t *new_segment (key_t, size_t, HANDLE);
- void delete_segment (segment_t *);
-};
-
-/* static */ long server_shmmgr::segment_t::_sequence = 0;
-
-/* static */ server_shmmgr *server_shmmgr::_instance = NULL;
-/* static */ pthread_once_t server_shmmgr::_instance_once = PTHREAD_ONCE_INIT;
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::segment_t::segment_t ()
- *---------------------------------------------------------------------------*/
-
-server_shmmgr::segment_t::segment_t (const key_t key,
- const int intid,
- const HANDLE hFileMap)
- : _intid (intid),
- _shmid (ipc_int2ext (intid, IPC_SHMOP, _sequence)),
- _next (NULL),
- _flg (0),
- _hFileMap (hFileMap),
- _attach_head (NULL)
-{
- assert (0 <= _intid && _intid < SHMMNI);
-
- memset (&_ds, '\0', sizeof (_ds));
- _ds.shm_perm.key = key;
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::segment_t::~segment_t ()
- *---------------------------------------------------------------------------*/
-
-server_shmmgr::segment_t::~segment_t ()
-{
- assert (!_attach_head);
-
- if (!CloseHandle (_hFileMap))
- syscall_printf ("failed to close file map [handle = 0x%x]: %E", _hFileMap);
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::segment_t::attach ()
- *---------------------------------------------------------------------------*/
-
-int
-server_shmmgr::segment_t::attach (class process *const client,
- HANDLE & hFileMap)
-{
- assert (client);
-
- if (!DuplicateHandle (GetCurrentProcess (),
- _hFileMap,
- client->handle (),
- &hFileMap,
- 0,
- FALSE, // bInheritHandle
- DUPLICATE_SAME_ACCESS))
- {
- syscall_printf (("failed to duplicate handle for client "
- "[key = 0x%016llx, shmid = %d, handle = 0x%x]: %E"),
- _ds.shm_perm.key, _shmid, _hFileMap);
-
- return -EACCES; // FIXME: Case analysis?
- }
-
- _ds.shm_lpid = client->cygpid ();
- _ds.shm_nattch += 1;
- _ds.shm_atime = time (NULL); // FIXME: sub-second times.
-
- attach_t *previous = NULL;
- attach_t *attptr = find (client, &previous);
-
- if (!attptr)
- {
- attptr = safe_new (attach_t, client);
-
- if (previous)
- {
- attptr->_next = previous->_next;
- previous->_next = attptr;
- }
- else
- {
- attptr->_next = _attach_head;
- _attach_head = attptr;
- }
- }
-
- attptr->_refcnt += 1;
-
- cleanup_t *const cleanup = safe_new (cleanup_t, this);
-
- // FIXME: ::add should only fail if the process object is already
- // cleaning up; but it can't be doing that since this thread has it
- // locked.
-
- const bool result = client->add (cleanup);
-
- assert (result);
-
- return 0;
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::segment_t::detach ()
- *---------------------------------------------------------------------------*/
-
-int
-server_shmmgr::segment_t::detach (class process *const client)
-{
- attach_t *previous = NULL;
- attach_t *const attptr = find (client, &previous);
-
- if (!attptr)
- return -EINVAL;
-
- if (client->is_active ())
- {
- const cleanup_t key (this);
-
- if (!client->remove (&key))
- syscall_printf (("failed to remove cleanup routine for %d(%lu) "
- "[shmid = %d]"),
- client->cygpid (), client->winpid (),
- _shmid);
- }
-
- attptr->_refcnt -= 1;
-
- if (!attptr->_refcnt)
- {
- assert (previous ? previous->_next == attptr : _attach_head == attptr);
-
- if (previous)
- previous->_next = attptr->_next;
- else
- _attach_head = attptr->_next;
-
- safe_delete (attptr);
- }
-
- assert (_ds.shm_nattch > 0);
-
- _ds.shm_lpid = client->cygpid ();
- _ds.shm_nattch -= 1;
- _ds.shm_dtime = time (NULL); // FIXME: sub-second times.
-
- return 0;
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::segment_t::find ()
- *---------------------------------------------------------------------------*/
-
-server_shmmgr::attach_t *
-server_shmmgr::segment_t::find (const class process *const client,
- attach_t **previous)
-{
- if (previous)
- *previous = NULL;
-
- // Nb. The _attach_head list is sorted by winpid.
-
- for (attach_t *attptr = _attach_head; attptr; attptr = attptr->_next)
- if (attptr->_client == client)
- return attptr;
- else if (attptr->_client->winpid () > client->winpid ())
- return NULL;
- else if (previous)
- *previous = attptr;
-
- return NULL;
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::instance ()
- *---------------------------------------------------------------------------*/
-
-/* static */ server_shmmgr &
-server_shmmgr::instance ()
-{
- pthread_once (&_instance_once, &initialise_instance);
-
- assert (_instance);
-
- return *_instance;
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::shmat ()
- *---------------------------------------------------------------------------*/
-
-int
-server_shmmgr::shmat (HANDLE & hFileMap,
- const int shmid, const int shmflg,
- class process *const client)
-{
- syscall_printf ("shmat (shmid = %d, shmflg = 0%o) for %d(%lu)",
- shmid, shmflg, client->cygpid (), client->winpid ());
-
- int result = 0;
- EnterCriticalSection (&_segments_lock);
-
- segment_t *const segptr = find (ipc_ext2int (shmid, IPC_SHMOP));
-
- if (!segptr)
- result = -EINVAL;
- else
- result = segptr->attach (client, hFileMap);
-
- if (!result)
- _shm_atts += 1;
-
- LeaveCriticalSection (&_segments_lock);
-
- if (result < 0)
- syscall_printf (("-1 [%d] = shmat (shmid = %d, shmflg = 0%o) "
- "for %d(%lu)"),
- -result, shmid, shmflg,
- client->cygpid (), client->winpid ());
- else
- syscall_printf (("0x%x = shmat (shmid = %d, shmflg = 0%o) "
- "for %d(%lu)"),
- hFileMap, shmid, shmflg,
- client->cygpid (), client->winpid ());
-
- return result;
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::shmctl ()
- *---------------------------------------------------------------------------*/
-
-int
-server_shmmgr::shmctl (int & out_shmid,
- struct shmid_ds & out_ds,
- struct shminfo & out_shminfo,
- struct shm_info & out_shm_info,
- const int shmid, const int cmd,
- const struct shmid_ds & ds,
- class process *const client)
-{
- syscall_printf ("shmctl (shmid = %d, cmd = 0x%x) for %d(%lu)",
- shmid, cmd, client->cygpid (), client->winpid ());
-
- int result = 0;
- EnterCriticalSection (&_segments_lock);
-
- switch (cmd)
- {
- case IPC_STAT:
- case SHM_STAT: // Uses intids rather than shmids.
- case IPC_SET:
- case IPC_RMID:
- {
- int intid;
-
- if (cmd == SHM_STAT)
- intid = shmid;
- else
- intid = ipc_ext2int (shmid, IPC_SHMOP);
-
- segment_t *const segptr = find (intid);
-
- if (!segptr)
- result = -EINVAL;
- else
- switch (cmd)
- {
- case IPC_STAT:
- out_ds = segptr->_ds;
- break;
-
- case IPC_SET:
- segptr->_ds.shm_perm.uid = ds.shm_perm.uid;
- segptr->_ds.shm_perm.gid = ds.shm_perm.gid;
- segptr->_ds.shm_perm.mode = ds.shm_perm.mode & 0777;
- segptr->_ds.shm_lpid = client->cygpid ();
- segptr->_ds.shm_ctime = time (NULL); // FIXME: sub-second times.
- break;
-
- case IPC_RMID:
- if (segptr->is_deleted ())
- result = -EIDRM;
- else
- {
- segptr->mark_deleted ();
- if (segptr->is_pending_delete ())
- delete_segment (segptr);
- }
- break;
-
- case SHM_STAT: // ipcs(8) i'face.
- out_ds = segptr->_ds;
- out_shmid = segptr->_shmid;
- break;
- }
- }
- break;
-
- case IPC_INFO:
- out_shminfo.shmmax = SHMMAX;
- out_shminfo.shmmin = SHMMIN;
- out_shminfo.shmmni = SHMMNI;
- out_shminfo.shmseg = SHMSEG;
- out_shminfo.shmall = SHMALL;
- break;
-
- case SHM_INFO: // ipcs(8) i'face.
- out_shmid = _intid_max;
- out_shm_info.shm_ids = _shm_ids;
- out_shm_info.shm_tot = _shm_tot;
- out_shm_info.shm_atts = _shm_atts;
- break;
-
- default:
- result = -EINVAL;
- break;
- }
-
- LeaveCriticalSection (&_segments_lock);
-
- if (result < 0)
- syscall_printf (("-1 [%d] = "
- "shmctl (shmid = %d, cmd = 0x%x) for %d(%lu)"),
- -result,
- shmid, cmd, client->cygpid (), client->winpid ());
- else
- syscall_printf (("%d = "
- "shmctl (shmid = %d, cmd = 0x%x) for %d(%lu)"),
- ((cmd == SHM_STAT || cmd == SHM_INFO)
- ? out_shmid
- : result),
- shmid, cmd, client->cygpid (), client->winpid ());
-
- return result;
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::shmdt ()
- *---------------------------------------------------------------------------*/
-
-int
-server_shmmgr::shmdt (const int shmid, class process *const client)
-{
- syscall_printf ("shmdt (shmid = %d) for %d(%lu)",
- shmid, client->cygpid (), client->winpid ());
-
- int result = 0;
- EnterCriticalSection (&_segments_lock);
-
- segment_t *const segptr = find (ipc_ext2int (shmid, IPC_SHMOP));
-
- if (!segptr)
- result = -EINVAL;
- else
- result = segptr->detach (client);
-
- if (!result)
- _shm_atts -= 1;
-
- if (!result && segptr->is_pending_delete ())
- delete_segment (segptr);
-
- LeaveCriticalSection (&_segments_lock);
-
- if (result < 0)
- syscall_printf ("-1 [%d] = shmdt (shmid = %d) for %d(%lu)",
- -result, shmid, client->cygpid (), client->winpid ());
- else
- syscall_printf ("%d = shmdt (shmid = %d) for %d(%lu)",
- result, shmid, client->cygpid (), client->winpid ());
-
- return result;
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::shmget ()
- *---------------------------------------------------------------------------*/
-
-int
-server_shmmgr::shmget (int & out_shmid,
- const key_t key, const size_t size, const int shmflg,
- const uid_t uid, const gid_t gid,
- class process *const client)
-{
- syscall_printf (("shmget (key = 0x%016llx, size = %u, shmflg = 0%o) "
- "for %d(%lu)"),
- key, size, shmflg,
- client->cygpid (), client->winpid ());
-
- int result = 0;
- EnterCriticalSection (&_segments_lock);
-
- if (key == IPC_PRIVATE)
- result = new_segment (key, size, shmflg,
- client->cygpid (), uid, gid);
- else
- {
- segment_t *const segptr = find_by_key (key);
-
- if (!segptr)
- if (shmflg & IPC_CREAT)
- result = new_segment (key, size, shmflg,
- client->cygpid (), uid, gid);
- else
- result = -ENOENT;
- else if (segptr->is_deleted ())
- result = -EIDRM;
- else if ((shmflg & IPC_CREAT) && (shmflg & IPC_EXCL))
- result = -EEXIST;
- else if ((shmflg & ~(segptr->_ds.shm_perm.mode)) & 0777)
- result = -EACCES;
- else if (size && segptr->_ds.shm_segsz < size)
- result = -EINVAL;
- else
- result = segptr->_shmid;
- }
-
- LeaveCriticalSection (&_segments_lock);
-
- if (result >= 0)
- {
- out_shmid = result;
- result = 0;
- }
-
- if (result < 0)
- syscall_printf (("-1 [%d] = "
- "shmget (key = 0x%016llx, size = %u, shmflg = 0%o) "
- "for %d(%lu)"),
- -result,
- key, size, shmflg,
- client->cygpid (), client->winpid ());
- else
- syscall_printf (("%d = "
- "shmget (key = 0x%016llx, size = %u, shmflg = 0%o) "
- "for %d(%lu)"),
- out_shmid,
- key, size, shmflg,
- client->cygpid (), client->winpid ());
-
- return result;
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::initialise_instance ()
- *---------------------------------------------------------------------------*/
-
-/* static */ void
-server_shmmgr::initialise_instance ()
-{
- assert (!_instance);
-
- _instance = safe_new0 (server_shmmgr);
-
- assert (_instance);
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::server_shmmgr ()
- *---------------------------------------------------------------------------*/
-
-server_shmmgr::server_shmmgr ()
- : _segments_head (NULL),
- _shm_ids (0),
- _shm_tot (0),
- _shm_atts (0),
- _intid_max (0)
-{
- InitializeCriticalSection (&_segments_lock);
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::~server_shmmgr ()
- *---------------------------------------------------------------------------*/
-
-server_shmmgr::~server_shmmgr ()
-{
- DeleteCriticalSection (&_segments_lock);
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::find_by_key ()
- *---------------------------------------------------------------------------*/
-
-server_shmmgr::segment_t *
-server_shmmgr::find_by_key (const key_t key)
-{
- for (segment_t *segptr = _segments_head; segptr; segptr = segptr->_next)
- if (segptr->_ds.shm_perm.key == key)
- return segptr;
-
- return NULL;
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::find ()
- *---------------------------------------------------------------------------*/
-
-server_shmmgr::segment_t *
-server_shmmgr::find (const int intid, segment_t **previous)
-{
- if (previous)
- *previous = NULL;
-
- for (segment_t *segptr = _segments_head; segptr; segptr = segptr->_next)
- if (segptr->_intid == intid)
- return segptr;
- else if (segptr->_intid > intid) // The list is sorted by intid.
- return NULL;
- else if (previous)
- *previous = segptr;
-
- return NULL;
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::new_segment ()
- *---------------------------------------------------------------------------*/
-
-int
-server_shmmgr::new_segment (const key_t key,
- const size_t size,
- const int shmflg,
- const pid_t cygpid,
- const uid_t uid,
- const gid_t gid)
-{
- if (size < SHMMIN || size > SHMMAX)
- return -EINVAL;
-
- const HANDLE hFileMap = CreateFileMapping (INVALID_HANDLE_VALUE,
- NULL, PAGE_READWRITE,
- 0, size,
- NULL);
-
- if (!hFileMap)
- {
- syscall_printf ("failed to create file mapping [size = %lu]: %E", size);
- return -ENOMEM; // FIXME
- }
-
- segment_t *const segptr = new_segment (key, size, hFileMap);
-
- if (!segptr)
- {
- (void) CloseHandle (hFileMap);
- return -ENOSPC;
- }
-
- segptr->_ds.shm_perm.cuid = segptr->_ds.shm_perm.uid = uid;
- segptr->_ds.shm_perm.cgid = segptr->_ds.shm_perm.gid = gid;
- segptr->_ds.shm_perm.mode = shmflg & 0777;
- segptr->_ds.shm_segsz = size;
- segptr->_ds.shm_cpid = cygpid;
- segptr->_ds.shm_ctime = time (NULL); // FIXME: sub-second times.
-
- return segptr->_shmid;
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::new_segment ()
- *
- * Allocate a new segment for the given key and file map with the
- * lowest available intid and insert into the segment map.
- *---------------------------------------------------------------------------*/
-
-server_shmmgr::segment_t *
-server_shmmgr::new_segment (const key_t key, const size_t size,
- const HANDLE hFileMap)
-{
- // FIXME: Overflow risk.
- if (_shm_tot + size > SHMALL)
- return NULL;
-
- int intid = 0; // Next expected intid value.
- segment_t *previous = NULL; // Insert pointer.
-
- // Find first unallocated intid.
- for (segment_t *segptr = _segments_head;
- segptr && segptr->_intid == intid;
- segptr = segptr->_next, intid++)
- {
- previous = segptr;
- }
-
- /* By the time this condition is reached (given the default value of
- * SHMMNI), the linear searches should all replaced by something
- * just a *little* cleverer . . .
- */
- if (intid >= SHMMNI)
- return NULL;
-
- segment_t *const segptr = safe_new (segment_t, key, intid, hFileMap);
-
- assert (segptr);
-
- if (previous)
- {
- segptr->_next = previous->_next;
- previous->_next = segptr;
- }
- else
- {
- segptr->_next = _segments_head;
- _segments_head = segptr;
- }
-
- _shm_ids += 1;
- _shm_tot += size;
- if (intid > _intid_max)
- _intid_max = intid;
-
- return segptr;
-}
-
-/*---------------------------------------------------------------------------*
- * server_shmmgr::delete_segment ()
- *---------------------------------------------------------------------------*/
-
-void
-server_shmmgr::delete_segment (segment_t *const segptr)
-{
- assert (segptr);
- assert (segptr->is_pending_delete ());
-
- segment_t *previous = NULL;
-
- const segment_t *const tmp = find (segptr->_intid, &previous);
-
- assert (tmp == segptr);
- assert (previous ? previous->_next == segptr : _segments_head == segptr);
-
- if (previous)
- previous->_next = segptr->_next;
- else
- _segments_head = segptr->_next;
-
- assert (_shm_ids > 0);
- _shm_ids -= 1;
- _shm_tot -= segptr->_ds.shm_segsz;
-
- safe_delete (segptr);
-}
-
-/*---------------------------------------------------------------------------*
- * client_request_shm::client_request_shm ()
- *---------------------------------------------------------------------------*/
-
-client_request_shm::client_request_shm ()
- : client_request (CYGSERVER_REQUEST_SHM,
- &_parameters, sizeof (_parameters))
-{
- // verbose: syscall_printf ("created");
-}
-
-/*---------------------------------------------------------------------------*
- * client_request_shm::serve ()
- *---------------------------------------------------------------------------*/
-
-void
-client_request_shm::serve (transport_layer_base *const conn,
- process_cache *const cache)
-{
- assert (conn);
-
- assert (!error_code ());
-
- if (msglen () != sizeof (_parameters.in))
- {
- syscall_printf ("bad request body length: expecting %lu bytes, got %lu",
- sizeof (_parameters), msglen ());
- error_code (EINVAL);
- msglen (0);
- return;
- }
-
- // FIXME: Get a return code out of this and don't continue on error.
- conn->impersonate_client ();
-
- class process *const client = cache->process (_parameters.in.cygpid,
- _parameters.in.winpid);
-
- if (!client)
- {
- error_code (EAGAIN);
- msglen (0);
- return;
- }
-
- int result = -EINVAL;
-
- switch (_parameters.in.shmop)
- {
- case SHMOP_shmget:
- result = shmmgr.shmget (_parameters.out.shmid,
- _parameters.in.key, _parameters.in.size,
- _parameters.in.shmflg,
- _parameters.in.uid, _parameters.in.gid,
- client);
- break;
-
- case SHMOP_shmat:
- result = shmmgr.shmat (_parameters.out.hFileMap,
- _parameters.in.shmid, _parameters.in.shmflg,
- client);
- break;
-
- case SHMOP_shmdt:
- result = shmmgr.shmdt (_parameters.in.shmid, client);
- break;
-
- case SHMOP_shmctl:
- result = shmmgr.shmctl (_parameters.out.shmid,
- _parameters.out.ds, _parameters.out.shminfo,
- _parameters.out.shm_info,
- _parameters.in.shmid, _parameters.in.cmd,
- _parameters.in.ds,
- client);
- break;
- }
-
- client->release ();
- conn->revert_to_self ();
-
- if (result < 0)
- {
- error_code (-result);
- msglen (0);
- }
- else
- msglen (sizeof (_parameters.out));
-}
diff --git a/winsup/cygwin/cygserver_shm.h b/winsup/cygwin/cygserver_shm.h
deleted file mode 100644
index 5a5ee3820..000000000
--- a/winsup/cygwin/cygserver_shm.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/* cygserver_shm.h: Single unix specification IPC interface for Cygwin.
-
- Copyright 2002 Red Hat, Inc.
-
- Written by Conrad Scott <conrad.scott@dsl.pipex.com>.
- Based on code by Robert Collins <robert.collins@hotmail.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. */
-
-#ifndef __CYGSERVER_SHM_H__
-#define __CYGSERVER_SHM_H__
-
-#include <sys/types.h>
-#include <cygwin/shm.h>
-
-#include <assert.h>
-#include <limits.h>
-
-#include "cygserver_ipc.h"
-
-#include "cygwin/cygserver.h"
-
-/*---------------------------------------------------------------------------*
- * Values for the shminfo entries.
- *
- * Nb. The values are segregated between two enums so that the `small'
- * values aren't promoted to `unsigned long' equivalents.
- *---------------------------------------------------------------------------*/
-
-enum
- {
- SHMMAX = ULONG_MAX,
- SHMSEG = ULONG_MAX,
- SHMALL = ULONG_MAX
- };
-
-enum
- {
- SHMMIN = 1,
- SHMMNI = IPCMNI // Must be <= IPCMNI.
- };
-
-/*---------------------------------------------------------------------------*
- * class client_request_shm
- *---------------------------------------------------------------------------*/
-
-#ifndef __INSIDE_CYGWIN__
-class transport_layer_base;
-class process_cache;
-#endif
-
-class client_request_shm : public client_request
-{
- friend class client_request;
-
-public:
- enum shmop_t
- {
- SHMOP_shmat,
- SHMOP_shmctl,
- SHMOP_shmdt,
- SHMOP_shmget
- };
-
-#ifdef __INSIDE_CYGWIN__
- client_request_shm (int shmid, int shmflg); // shmat
- client_request_shm (int shmid, int cmd, const struct shmid_ds *); // shmctl
- client_request_shm (int shmid); // shmdt
- client_request_shm (key_t, size_t, int shmflg); // shmget
-#endif
-
- // Accessors for out parameters.
-
- int shmid () const
- {
- assert (!error_code ());
- return _parameters.out.shmid;
- }
-
- HANDLE hFileMap () const
- {
- assert (!error_code ());
- return _parameters.out.hFileMap;
- }
-
- const struct shmid_ds & ds () const
- {
- assert (!error_code ());
- return _parameters.out.ds;
- }
-
- const struct shminfo & shminfo () const
- {
- assert (!error_code ());
- return _parameters.out.shminfo;
- }
-
- const struct shm_info & shm_info () const
- {
- assert (!error_code ());
- return _parameters.out.shm_info;
- }
-
-private:
- union
- {
- struct
- {
- shmop_t shmop;
- key_t key;
- size_t size;
- int shmflg;
- int shmid;
- int cmd;
- pid_t cygpid;
- DWORD winpid;
- __uid32_t uid;
- __gid32_t gid;
- struct shmid_ds ds;
- } in;
-
- struct {
- int shmid;
- union
- {
- HANDLE hFileMap;
- struct shmid_ds ds;
- struct shminfo shminfo;
- struct shm_info shm_info;
- };
- } out;
- } _parameters;
-
-#ifndef __INSIDE_CYGWIN__
- client_request_shm ();
-#endif
-
-#ifndef __INSIDE_CYGWIN__
- virtual void serve (transport_layer_base *, process_cache *);
-#endif
-};
-
-#endif /* __CYGSERVER_SHM_H__ */
diff --git a/winsup/cygwin/cygserver_transport.cc b/winsup/cygwin/cygserver_transport.cc
deleted file mode 100755
index 8684a6148..000000000
--- a/winsup/cygwin/cygserver_transport.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-/* cygserver_transport.cc
-
- Copyright 2001, 2002 Red Hat Inc.
-
- Written by Robert Collins <rbtcollins@hotmail.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. */
-
-/* to allow this to link into cygwin and the .dll, a little magic is needed. */
-#ifdef __OUTSIDE_CYGWIN__
-#include "woutsup.h"
-#else
-#include "winsup.h"
-#endif
-
-#include <sys/socket.h>
-
-#include "safe_memory.h"
-
-#include "cygwin/cygserver_transport.h"
-#include "cygwin/cygserver_transport_pipes.h"
-#include "cygwin/cygserver_transport_sockets.h"
-
-/* The factory */
-transport_layer_base *
-create_server_transport ()
-{
- if (wincap.is_winnt ())
- return safe_new0 (transport_layer_pipes);
- else
- return safe_new0 (transport_layer_sockets);
-}
-
-#ifndef __INSIDE_CYGWIN__
-
-void
-transport_layer_base::impersonate_client ()
-{}
-
-void
-transport_layer_base::revert_to_self ()
-{}
-
-#endif /* !__INSIDE_CYGWIN__ */
-
-transport_layer_base::~transport_layer_base ()
-{}
diff --git a/winsup/cygwin/cygserver_transport_pipes.cc b/winsup/cygwin/cygserver_transport_pipes.cc
deleted file mode 100755
index 6d80defd4..000000000
--- a/winsup/cygwin/cygserver_transport_pipes.cc
+++ /dev/null
@@ -1,362 +0,0 @@
-/* cygserver_transport_pipes.cc
-
- Copyright 2001, 2002 Red Hat Inc.
-
- Written by Robert Collins <rbtcollins@hotmail.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. */
-
-/* to allow this to link into cygwin and the .dll, a little magic is needed. */
-#ifdef __OUTSIDE_CYGWIN__
-#include "woutsup.h"
-#else
-#include "winsup.h"
-#endif
-
-#include <sys/types.h>
-
-#include <assert.h>
-#include <netdb.h>
-#include <pthread.h>
-#include <unistd.h>
-
-#include "cygerrno.h"
-#include "cygwin/cygserver_transport.h"
-#include "cygwin/cygserver_transport_pipes.h"
-
-#ifndef __INSIDE_CYGWIN__
-#include "cygwin/cygserver.h"
-#endif
-
-enum
- {
- MAX_WAIT_NAMED_PIPE_RETRY = 64,
- WAIT_NAMED_PIPE_TIMEOUT = 10 // milliseconds
- };
-
-#ifndef __INSIDE_CYGWIN__
-
-static pthread_once_t pipe_instance_lock_once = PTHREAD_ONCE_INIT;
-static CRITICAL_SECTION pipe_instance_lock;
-static long pipe_instance = 0;
-
-static void
-initialise_pipe_instance_lock ()
-{
- assert (pipe_instance == 0);
- InitializeCriticalSection (&pipe_instance_lock);
-}
-
-#endif /* !__INSIDE_CYGWIN__ */
-
-#ifndef __INSIDE_CYGWIN__
-
-transport_layer_pipes::transport_layer_pipes (const HANDLE hPipe)
- : _pipe_name (""),
- _hPipe (hPipe),
- _is_accepted_endpoint (true),
- _is_listening_endpoint (false)
-{
- assert (_hPipe);
- assert (_hPipe != INVALID_HANDLE_VALUE);
-
- init_security ();
-}
-
-#endif /* !__INSIDE_CYGWIN__ */
-
-transport_layer_pipes::transport_layer_pipes ()
- : _pipe_name ("\\\\.\\pipe\\cygwin_lpc"),
- _hPipe (NULL),
- _is_accepted_endpoint (false),
- _is_listening_endpoint (false)
-{
- init_security ();
-}
-
-void
-transport_layer_pipes::init_security ()
-{
- assert (wincap.has_security ());
-
- /* FIXME: pthread_once or equivalent needed */
-
- InitializeSecurityDescriptor (&_sd, SECURITY_DESCRIPTOR_REVISION);
- SetSecurityDescriptorDacl (&_sd, TRUE, NULL, FALSE);
-
- _sec_all_nih.nLength = sizeof (SECURITY_ATTRIBUTES);
- _sec_all_nih.lpSecurityDescriptor = &_sd;
- _sec_all_nih.bInheritHandle = FALSE;
-}
-
-transport_layer_pipes::~transport_layer_pipes ()
-{
- close ();
-}
-
-#ifndef __INSIDE_CYGWIN__
-
-int
-transport_layer_pipes::listen ()
-{
- assert (!_hPipe);
- assert (!_is_accepted_endpoint);
- assert (!_is_listening_endpoint);
-
- _is_listening_endpoint = true;
-
- /* no-op */
- return 0;
-}
-
-class transport_layer_pipes *
-transport_layer_pipes::accept (bool *const recoverable)
-{
- assert (!_hPipe);
- assert (!_is_accepted_endpoint);
- assert (_is_listening_endpoint);
-
- pthread_once (&pipe_instance_lock_once, &initialise_pipe_instance_lock);
-
- EnterCriticalSection (&pipe_instance_lock);
-
- // Read: http://www.securityinternals.com/research/papers/namedpipe.php
- // See also the Microsoft security bulletins MS00-053 and MS01-031.
-
- // FIXME: Remove FILE_CREATE_PIPE_INSTANCE.
-
- const bool first_instance = (pipe_instance == 0);
-
- const HANDLE accept_pipe =
- CreateNamedPipe (_pipe_name,
- (PIPE_ACCESS_DUPLEX
- | (first_instance ? FILE_FLAG_FIRST_PIPE_INSTANCE : 0)),
- (PIPE_TYPE_BYTE | PIPE_WAIT),
- PIPE_UNLIMITED_INSTANCES,
- 0, 0, 1000,
- &_sec_all_nih);
-
- const bool duplicate = (accept_pipe == INVALID_HANDLE_VALUE
- && pipe_instance == 0
- && GetLastError () == ERROR_ACCESS_DENIED);
-
- if (accept_pipe != INVALID_HANDLE_VALUE)
- InterlockedIncrement (&pipe_instance);
-
- LeaveCriticalSection (&pipe_instance_lock);
-
- if (duplicate)
- {
- *recoverable = false;
- system_printf ("failed to create named pipe: "
- "is the daemon already running?");
- return NULL;
- }
-
- if (accept_pipe == INVALID_HANDLE_VALUE)
- {
- debug_printf ("error creating pipe (%lu).", GetLastError ());
- *recoverable = true; // FIXME: case analysis?
- return NULL;
- }
-
- assert (accept_pipe);
-
- if (!ConnectNamedPipe (accept_pipe, NULL)
- && GetLastError () != ERROR_PIPE_CONNECTED)
- {
- debug_printf ("error connecting to pipe (%lu)", GetLastError ());
- (void) CloseHandle (accept_pipe);
- *recoverable = true; // FIXME: case analysis?
- return NULL;
- }
-
- return safe_new (transport_layer_pipes, accept_pipe);
-}
-
-#endif /* !__INSIDE_CYGWIN__ */
-
-void
-transport_layer_pipes::close ()
-{
- // verbose: debug_printf ("closing pipe %p", _hPipe);
-
- if (_hPipe)
- {
- assert (_hPipe != INVALID_HANDLE_VALUE);
-
-#ifndef __INSIDE_CYGWIN__
-
- if (_is_accepted_endpoint)
- {
- (void) FlushFileBuffers (_hPipe); // Blocks until client reads.
- (void) DisconnectNamedPipe (_hPipe);
- EnterCriticalSection (&pipe_instance_lock);
- (void) CloseHandle (_hPipe);
- assert (pipe_instance > 0);
- InterlockedDecrement (&pipe_instance);
- LeaveCriticalSection (&pipe_instance_lock);
- }
- else
- (void) CloseHandle (_hPipe);
-
-#else /* __INSIDE_CYGWIN__ */
-
- assert (!_is_accepted_endpoint);
- (void) ForceCloseHandle (_hPipe);
-
-#endif /* __INSIDE_CYGWIN__ */
-
- _hPipe = NULL;
- }
-}
-
-ssize_t
-transport_layer_pipes::read (void *const buf, const size_t len)
-{
- // verbose: debug_printf ("reading from pipe %p", _hPipe);
-
- assert (_hPipe);
- assert (_hPipe != INVALID_HANDLE_VALUE);
- assert (!_is_listening_endpoint);
-
- DWORD count;
- if (!ReadFile (_hPipe, buf, len, &count, NULL))
- {
- debug_printf ("error reading from pipe (%lu)", GetLastError ());
- set_errno (EINVAL); // FIXME?
- return -1;
- }
-
- return count;
-}
-
-ssize_t
-transport_layer_pipes::write (void *const buf, const size_t len)
-{
- // verbose: debug_printf ("writing to pipe %p", _hPipe);
-
- assert (_hPipe);
- assert (_hPipe != INVALID_HANDLE_VALUE);
- assert (!_is_listening_endpoint);
-
- DWORD count;
- if (!WriteFile (_hPipe, buf, len, &count, NULL))
- {
- debug_printf ("error writing to pipe, error = %lu", GetLastError ());
- set_errno (EINVAL); // FIXME?
- return -1;
- }
-
- return count;
-}
-
-/*
- * This routine holds a static variable, assume_cygserver, that is set
- * if the transport has good reason to think that cygserver is
- * running, i.e. if if successfully connected to it with the previous
- * attempt. If this is set, the code tries a lot harder to get a
- * connection, making the assumption that any failures are just
- * congestion and overloading problems.
- */
-
-int
-transport_layer_pipes::connect ()
-{
- assert (!_hPipe);
- assert (!_is_accepted_endpoint);
- assert (!_is_listening_endpoint);
-
- static bool assume_cygserver = false;
-
- BOOL rc = TRUE;
- int retries = 0;
-
- while (rc)
- {
- _hPipe = CreateFile (_pipe_name,
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- &_sec_all_nih,
- OPEN_EXISTING,
- SECURITY_IMPERSONATION,
- NULL);
-
- if (_hPipe != INVALID_HANDLE_VALUE)
- {
- assert (_hPipe);
-#ifdef __INSIDE_CYGWIN__
- ProtectHandle (_hPipe);
-#endif
- assume_cygserver = true;
- return 0;
- }
-
- _hPipe = NULL;
-
- if (!assume_cygserver && GetLastError () != ERROR_PIPE_BUSY)
- {
- debug_printf ("Error opening the pipe (%lu)", GetLastError ());
- return -1;
- }
-
- /* Note: `If no instances of the specified named pipe exist, the
- * WaitNamedPipe function returns immediately, regardless of the
- * time-out value.' Thus the explicit Sleep if the call fails
- * with ERROR_FILE_NOT_FOUND.
- */
- while (retries != MAX_WAIT_NAMED_PIPE_RETRY
- && !(rc = WaitNamedPipe (_pipe_name, WAIT_NAMED_PIPE_TIMEOUT)))
- {
- if (GetLastError () == ERROR_FILE_NOT_FOUND)
- Sleep (0); // Give the server a chance.
-
- retries += 1;
- }
- }
-
- assert (retries == MAX_WAIT_NAMED_PIPE_RETRY);
-
- system_printf ("lost connection to cygserver, error = %lu",
- GetLastError ());
-
- assume_cygserver = false;
-
- return -1;
-}
-
-#ifndef __INSIDE_CYGWIN__
-
-void
-transport_layer_pipes::impersonate_client ()
-{
- assert (_hPipe);
- assert (_hPipe != INVALID_HANDLE_VALUE);
- assert (_is_accepted_endpoint);
-
- // verbose: debug_printf ("impersonating pipe %p", _hPipe);
- if (_hPipe)
- {
- assert (_hPipe != INVALID_HANDLE_VALUE);
-
- if (!ImpersonateNamedPipeClient (_hPipe))
- debug_printf ("Failed to Impersonate the client, (%lu)",
- GetLastError ());
- }
- // verbose: debug_printf ("I am who you are");
-}
-
-void
-transport_layer_pipes::revert_to_self ()
-{
- assert (_is_accepted_endpoint);
-
- RevertToSelf ();
- // verbose: debug_printf ("I am who I yam");
-}
-
-#endif /* !__INSIDE_CYGWIN__ */
diff --git a/winsup/cygwin/cygserver_transport_sockets.cc b/winsup/cygwin/cygserver_transport_sockets.cc
deleted file mode 100755
index 6ade14bff..000000000
--- a/winsup/cygwin/cygserver_transport_sockets.cc
+++ /dev/null
@@ -1,387 +0,0 @@
-/* cygserver_transport_sockets.cc
-
- Copyright 2001, 2002 Red Hat Inc.
-
- Written by Robert Collins <rbtcollins@hotmail.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. */
-
-/* to allow this to link into cygwin and the .dll, a little magic is needed. */
-#ifdef __OUTSIDE_CYGWIN__
-#include "woutsup.h"
-#else
-#include "winsup.h"
-#endif
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-
-#include <assert.h>
-#include <errno.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include "cygwin/cygserver_transport.h"
-#include "cygwin/cygserver_transport_sockets.h"
-
-/* to allow this to link into cygwin and the .dll, a little magic is needed. */
-#ifndef __OUTSIDE_CYGWIN__
-
-extern "C" int cygwin_accept (int fd, struct sockaddr *, int *len);
-extern "C" int cygwin_bind (int fd, const struct sockaddr *, int len);
-extern "C" int cygwin_connect (int fd, const struct sockaddr *, int len);
-extern "C" int cygwin_listen (int fd, int backlog);
-extern "C" int cygwin_shutdown (int fd, int how);
-extern "C" int cygwin_socket (int af, int type, int protocol);
-
-#else /* __OUTSIDE_CYGWIN__ */
-
-#define cygwin_accept(A,B,C) ::accept (A,B,C)
-#define cygwin_bind(A,B,C) ::bind (A,B,C)
-#define cygwin_connect(A,B,C) ::connect (A,B,C)
-#define cygwin_listen(A,B) ::listen (A,B)
-#define cygwin_shutdown(A,B) ::shutdown (A,B)
-#define cygwin_socket(A,B,C) ::socket (A,B,C)
-
-#endif /* __OUTSIDE_CYGWIN__ */
-
-enum
- {
- MAX_CONNECT_RETRY = 64
- };
-
-transport_layer_sockets::transport_layer_sockets (const int fd)
- : _fd (fd),
- _addr_len (0),
- _is_accepted_endpoint (true),
- _is_listening_endpoint (false)
-{
- assert (_fd != -1);
-
- memset (&_addr, '\0', sizeof (_addr));
-}
-
-transport_layer_sockets::transport_layer_sockets ()
- : _fd (-1),
- _addr_len (0),
- _is_accepted_endpoint (false),
- _is_listening_endpoint (false)
-{
- memset (&_addr, '\0', sizeof (_addr));
-
- _addr.sun_family = AF_UNIX;
- strcpy (_addr.sun_path, "/tmp/cygdaemo"); // FIXME: $TMP?
- _addr_len = SUN_LEN (&_addr);
-}
-
-transport_layer_sockets::~transport_layer_sockets ()
-{
- close ();
-}
-
-#ifndef __INSIDE_CYGWIN__
-
-int
-transport_layer_sockets::listen ()
-{
- assert (_fd == -1);
- assert (!_is_accepted_endpoint);
- assert (!_is_listening_endpoint);
-
- debug_printf ("listen () [this = %p]", this);
-
- struct stat sbuf;
-
- if (stat (_addr.sun_path, &sbuf) == -1)
- {
- if (errno != ENOENT)
- {
- system_printf ("cannot access socket file `%s': %s",
- _addr.sun_path, strerror (errno));
- return -1;
- }
- }
- else if (S_ISSOCK (sbuf.st_mode))
- {
- // The socket already exists: is a duplicate cygserver running?
-
- const int newfd = cygwin_socket (AF_UNIX, SOCK_STREAM, 0);
-
- if (newfd == -1)
- {
- system_printf ("failed to create UNIX domain socket: %s",
- strerror (errno));
- return -1;
- }
-
- if (cygwin_connect (newfd, (struct sockaddr *) &_addr, _addr_len) == 0)
- {
- system_printf ("the daemon is already running");
- (void) cygwin_shutdown (newfd, SHUT_WR);
- char buf[BUFSIZ];
- while (::read (newfd, buf, sizeof (buf)) > 0)
- {}
- (void) ::close (newfd);
- return -1;
- }
-
- if (unlink (_addr.sun_path) == -1)
- {
- system_printf ("failed to remove `%s': %s",
- _addr.sun_path, strerror (errno));
- (void) ::close (newfd);
- return -1;
- }
- }
- else
- {
- system_printf ("cannot create socket `%s': File already exists",
- _addr.sun_path);
- return -1;
- }
-
- _fd = cygwin_socket (AF_UNIX, SOCK_STREAM, 0);
-
- if (_fd == -1)
- {
- system_printf ("failed to create UNIX domain socket: %s",
- strerror (errno));
- return -1;
- }
-
- if (cygwin_bind (_fd, (struct sockaddr *) &_addr, _addr_len) == -1)
- {
- const int saved_errno = errno;
- close ();
- errno = saved_errno;
- system_printf ("failed to bind UNIX domain socket `%s': %s",
- _addr.sun_path, strerror (errno));
- return -1;
- }
-
- _is_listening_endpoint = true; // i.e. this really means "have bound".
-
- if (cygwin_listen (_fd, SOMAXCONN) == -1)
- {
- const int saved_errno = errno;
- close ();
- errno = saved_errno;
- system_printf ("failed to listen on UNIX domain socket `%s': %s",
- _addr.sun_path, strerror (errno));
- return -1;
- }
-
- debug_printf ("0 = listen () [this = %p, fd = %d]", this, _fd);
-
- return 0;
-}
-
-class transport_layer_sockets *
-transport_layer_sockets::accept (bool *const recoverable)
-{
- assert (_fd != -1);
- assert (!_is_accepted_endpoint);
- assert (_is_listening_endpoint);
-
- debug_printf ("accept () [this = %p, fd = %d]", this, _fd);
-
- struct sockaddr_un client_addr;
- socklen_t client_addr_len = sizeof (client_addr);
-
- const int accept_fd =
- cygwin_accept (_fd, (struct sockaddr *) &client_addr, &client_addr_len);
-
- if (accept_fd == -1)
- {
- system_printf ("failed to accept connection: %s", strerror (errno));
- switch (errno)
- {
- case ECONNABORTED:
- case EINTR:
- case EMFILE:
- case ENFILE:
- case ENOBUFS:
- case ENOMEM:
- *recoverable = true;
- break;
-
- default:
- *recoverable = false;
- break;
- }
- return NULL;
- }
-
- debug_printf ("%d = accept () [this = %p, fd = %d]", accept_fd, this, _fd);
-
- return safe_new (transport_layer_sockets, accept_fd);
-}
-
-#endif /* !__INSIDE_CYGWIN__ */
-
-void
-transport_layer_sockets::close ()
-{
- debug_printf ("close () [this = %p, fd = %d]", this, _fd);
-
- if (_is_listening_endpoint)
- (void) unlink (_addr.sun_path);
-
- if (_fd != -1)
- {
- (void) cygwin_shutdown (_fd, SHUT_WR);
- if (!_is_listening_endpoint)
- {
- char buf[BUFSIZ];
- while (::read (_fd, buf, sizeof (buf)) > 0)
- {}
- }
- (void) ::close (_fd);
- _fd = -1;
- }
-
- _is_listening_endpoint = false;
-}
-
-ssize_t
-transport_layer_sockets::read (void *const buf, const size_t buf_len)
-{
- assert (_fd != -1);
- assert (!_is_listening_endpoint);
-
- assert (buf);
- assert (buf_len > 0);
-
- // verbose: debug_printf ("read (buf = %p, len = %u) [this = %p, fd = %d]",
- // buf, buf_len, this, _fd);
-
- char *read_buf = static_cast<char *> (buf);
- size_t read_buf_len = buf_len;
- ssize_t res = 0;
-
- while (read_buf_len != 0
- && (res = ::read (_fd, read_buf, read_buf_len)) > 0)
- {
- read_buf += res;
- read_buf_len -= res;
-
- assert (read_buf_len >= 0);
- }
-
- if (res != -1)
- {
- if (res == 0)
- errno = EIO; // FIXME?
-
- res = buf_len - read_buf_len;
- }
-
- if (res != static_cast<ssize_t> (buf_len))
- debug_printf ("%d = read (buf = %p, len = %u) [this = %p, fd = %d]: %s",
- res, buf, buf_len, this, _fd,
- (res == -1 ? strerror (errno) : "EOF"));
- else
- {
- // verbose: debug_printf ("%d = read (buf = %p, len = %u) [this = %p, fd = %d]",
- // res, buf, buf_len, this, _fd);
- }
-
- return res;
-}
-
-ssize_t
-transport_layer_sockets::write (void *const buf, const size_t buf_len)
-{
- assert (_fd != -1);
- assert (!_is_listening_endpoint);
-
- assert (buf);
- assert (buf_len > 0);
-
- // verbose: debug_printf ("write (buf = %p, len = %u) [this = %p, fd = %d]",
- // buf, buf_len, this, _fd);
-
- char *write_buf = static_cast<char *> (buf);
- size_t write_buf_len = buf_len;
- ssize_t res = 0;
-
- while (write_buf_len != 0
- && (res = ::write (_fd, write_buf, write_buf_len)) > 0)
- {
- write_buf += res;
- write_buf_len -= res;
-
- assert (write_buf_len >= 0);
- }
-
- if (res != -1)
- {
- if (res == 0)
- errno = EIO; // FIXME?
-
- res = buf_len - write_buf_len;
- }
-
- if (res != static_cast<ssize_t> (buf_len))
- debug_printf ("%d = write (buf = %p, len = %u) [this = %p, fd = %d]: %s",
- res, buf, buf_len, this, _fd,
- (res == -1 ? strerror (errno) : "EOF"));
- else
- {
- // verbose: debug_printf ("%d = write (buf = %p, len = %u) [this = %p, fd = %d]",
- // res, buf, buf_len, this, _fd);
- }
-
- return res;
-}
-
-int
-transport_layer_sockets::connect ()
-{
- assert (_fd == -1);
- assert (!_is_accepted_endpoint);
- assert (!_is_listening_endpoint);
-
- static bool assume_cygserver = false;
-
- debug_printf ("connect () [this = %p]", this);
-
- for (int retries = 0; retries != MAX_CONNECT_RETRY; retries++)
- {
- _fd = cygwin_socket (AF_UNIX, SOCK_STREAM, 0);
-
- if (_fd == -1)
- {
- system_printf ("failed to create UNIX domain socket: %s",
- strerror (errno));
- return -1;
- }
-
- if (cygwin_connect (_fd, (struct sockaddr *) &_addr, _addr_len) == 0)
- {
- assume_cygserver = true;
- debug_printf ("0 = connect () [this = %p, fd = %d]", this, _fd);
- return 0;
- }
-
- if (!assume_cygserver || errno != ECONNREFUSED)
- {
- debug_printf ("failed to connect to server: %s", strerror (errno));
- (void) ::close (_fd);
- _fd = -1;
- return -1;
- }
-
- (void) ::close (_fd);
- _fd = -1;
- Sleep (0); // Give the server a chance.
- }
-
- debug_printf ("failed to connect to server: %s", strerror (errno));
- return -1;
-}
diff --git a/winsup/cygwin/dlmalloc.c b/winsup/cygwin/dlmalloc.c
index de14fcb6a..a5a7ff008 100644
--- a/winsup/cygwin/dlmalloc.c
+++ b/winsup/cygwin/dlmalloc.c
@@ -28,6 +28,21 @@
* malloc_usable_size(P) is equivalent to realloc(P, malloc_usable_size(P))
*
* $Log$
+ * Revision 1.6 2003/08/31 18:26:58 cgf
+ * * Makefile.in (MALLOC_OFILES): Always fill in with correct malloc object.
+ * * configure.in: Fill in MALLOC_OFILES with either debugging or regular malloc.
+ * * configure: Regenerate.
+ * * dlmalloc.c: Make various fruitless changes to attempt to get to work.
+ * * dlmalloc.h: Ditto.
+ * * malloc.cc (free): Check malloc pool when debugging.
+ * * path.cc (win32_device_name): Eliminate compiler warning.
+ * * sigproc.cc (sig_dispatch_pending): Remove use of was_pending. Let
+ * thisframe.call_signal_handler decide if handler should be called rather than
+ * using bogus was_pending check.
+ * * exceptions.cc (interrupt_setup): Remove accidentally checked in debugging
+ * code.
+ * * heap.cc (sbrk): Save rounded addess in user_heap_max.
+ *
* Revision 1.5 2001/10/03 03:49:25 cgf
* * cygheap.cc (cfree): Remove malloc debugging probe.
* * dlmalloc.c (errprint): Remove abort() call which causes interesting error
@@ -973,31 +988,31 @@ extern Void_t* sbrk();
#else
#ifndef cALLOc
-#define cALLOc calloc
+#define cALLOc dlcalloc
#endif
#ifndef fREe
-#define fREe free
+#define fREe dlfree
#endif
#ifndef mALLOc
-#define mALLOc malloc
+#define mALLOc dlmalloc
#endif
#ifndef mEMALIGn
-#define mEMALIGn memalign
+#define mEMALIGn dlmemalign
#endif
#ifndef rEALLOc
-#define rEALLOc realloc
+#define rEALLOc dlrealloc
#endif
#ifndef vALLOc
-#define vALLOc valloc
+#define vALLOc dlvalloc
#endif
#ifndef pvALLOc
-#define pvALLOc pvalloc
+#define pvALLOc dlpvalloc
#endif
#ifndef mALLINFo
-#define mALLINFo mallinfo
+#define mALLINFo dlmallinfo
#endif
#ifndef mALLOPt
-#define mALLOPt mallopt
+#define mALLOPt dlmallopt
#endif
#endif
@@ -1012,7 +1027,6 @@ extern Void_t* sbrk();
#define memalign(align, size) memalign_dbg(align, size, __FILE__, __LINE__)
#define valloc(size) valloc_dbg(size, __FILE__, __LINE__)
#define pvalloc(size) pvalloc_dbg(size, __FILE__, __LINE__)
-#define cfree(p) cfree_dbg(p, __FILE__, __LINE__)
#define malloc_trim(pad) malloc_trim_dbg(pad, __FILE__, __LINE__)
#define malloc_usable_size(p) malloc_usable_size_dbg(p, __FILE__, __LINE__)
#define malloc_stats(void) malloc_stats_dbg(__FILE__, __LINE__)
@@ -1027,7 +1041,6 @@ Void_t* calloc_dbg(size_t, size_t, const char *, int);
Void_t* memalign_dbg(size_t, size_t, const char *, int);
Void_t* valloc_dbg(size_t, const char *, int);
Void_t* pvalloc_dbg(size_t, const char *, int);
-void cfree_dbg(Void_t*, const char *, int);
int malloc_trim_dbg(size_t, const char *, int);
size_t malloc_usable_size_dbg(Void_t*, const char *, int);
void malloc_stats_dbg(const char *, int);
@@ -1041,7 +1054,6 @@ Void_t* calloc_dbg();
Void_t* memalign_dbg();
Void_t* valloc_dbg();
Void_t* pvalloc_dbg();
-void cfree_dbg();
int malloc_trim_dbg();
size_t malloc_usable_size_dbg();
void malloc_stats_dbg();
@@ -1060,7 +1072,6 @@ Void_t* cALLOc(size_t, size_t);
Void_t* mEMALIGn(size_t, size_t);
Void_t* vALLOc(size_t);
Void_t* pvALLOc(size_t);
-void cfree(Void_t*);
int malloc_trim(size_t);
size_t malloc_usable_size(Void_t*);
void malloc_stats(void);
@@ -1074,7 +1085,6 @@ Void_t* cALLOc();
Void_t* mEMALIGn();
Void_t* vALLOc();
Void_t* pvALLOc();
-void cfree();
int malloc_trim();
size_t malloc_usable_size();
void malloc_stats();
@@ -1102,7 +1112,6 @@ extern "C" {
#undef memalign
#undef valloc
#undef pvalloc
-#undef cfree
#undef malloc_trim
#undef malloc_usable_size
#undef malloc_stats
@@ -1117,7 +1126,6 @@ Void_t* cALLOc(size_t, size_t);
Void_t* mEMALIGn(size_t, size_t);
Void_t* vALLOc(size_t);
Void_t* pvALLOc(size_t);
-void cfree(Void_t*);
int malloc_trim(size_t);
size_t malloc_usable_size(Void_t*);
void malloc_stats(void);
@@ -1131,7 +1139,6 @@ Void_t* cALLOc();
Void_t* mEMALIGn();
Void_t* vALLOc();
Void_t* pvALLOc();
-void cfree();
int malloc_trim();
size_t malloc_usable_size();
void malloc_stats();
@@ -1901,7 +1908,6 @@ static void malloc_err(const char *err, mchunkptr p)
#undef valloc
#undef pvalloc
#undef calloc
-#undef cfree
#undef malloc_trim
#undef malloc_usable_size
#undef malloc_stats
@@ -1959,20 +1965,17 @@ Void_t* realloc_dbg(Void_t *oldmem, size_t bytes, dbgargs) {
skelr(Void_t*, realloc(oldmem, bytes));
}
Void_t* memalign_dbg(size_t alignment, size_t bytes, dbgargs) {
- skelr(Void_t*, memalign(alignment, bytes));
+ skelr(Void_t*, dlmemalign(alignment, bytes));
}
Void_t* valloc_dbg(size_t bytes, dbgargs) {
- skelr(Void_t*, valloc(bytes));
+ skelr(Void_t*, dlvalloc(bytes));
}
Void_t* pvalloc_dbg(size_t bytes, dbgargs) {
- skelr(Void_t*, pvalloc(bytes));
+ skelr(Void_t*, dlpvalloc(bytes));
}
Void_t* calloc_dbg(size_t n, size_t elem_size, dbgargs) {
skelr(Void_t*, calloc(n, elem_size));
}
-void cfree_dbg(Void_t *mem, dbgargs) {
- skelv(cfree(mem));
-}
int malloc_trim_dbg(size_t pad, dbgargs) {
skelr(int, malloc_trim(pad));
}
@@ -1983,10 +1986,10 @@ void malloc_stats_dbg(dbgargs) {
skelv(malloc_stats());
}
int mallopt_dbg(int flag, int value, dbgargs) {
- skelr(int, mallopt(flag, value));
+ skelr(int, dlmallopt(flag, value));
}
struct mallinfo mallinfo_dbg(dbgargs) {
- skelr(struct mallinfo, mallinfo());
+ skelr(struct mallinfo, dlmallinfo());
}
#undef skel
@@ -3536,24 +3539,6 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;
}
}
-/*
-
- cfree just calls free. It is needed/defined on some systems
- that pair it with calloc, presumably for odd historical reasons.
-
-*/
-
-#if !defined(INTERNAL_LINUX_C_LIB) || !defined(__ELF__)
-#if __STD_C
-void cfree(Void_t *mem)
-#else
-void cfree(mem) Void_t *mem;
-#endif
-{
- free(mem);
-}
-#endif
-
/*
@@ -3580,7 +3565,7 @@ void cfree(mem) Void_t *mem;
*/
#if __STD_C
-int malloc_trim(size_t pad)
+int dlmalloc_trim(size_t pad)
#else
int malloc_trim(pad) size_t pad;
#endif
@@ -3653,7 +3638,7 @@ int malloc_trim(pad) size_t pad;
*/
#if __STD_C
-size_t malloc_usable_size(Void_t* mem)
+size_t dlmalloc_usable_size(Void_t* mem)
#else
size_t malloc_usable_size(mem) Void_t* mem;
#endif
@@ -3745,7 +3730,7 @@ static void malloc_update_mallinfo(void)
*/
-void malloc_stats(void)
+void dlmalloc_stats(void)
{
malloc_update_mallinfo();
fprintf(stderr, "max system bytes = %10u\n",
diff --git a/winsup/cygwin/dlmalloc.h b/winsup/cygwin/dlmalloc.h
index 15b25db7b..b8d7ebeeb 100644
--- a/winsup/cygwin/dlmalloc.h
+++ b/winsup/cygwin/dlmalloc.h
@@ -8,7 +8,7 @@
*
* bbclabel: autogenerated
*/
-
+#define _INCLUDE_MALLOC_H_ 1
void malloc_outofmem(void (*)(void));
@@ -41,19 +41,18 @@ struct mallinfo {
#ifdef MALLOC_DEBUG
-#define malloc(size) malloc_dbg(size, __FILE__, __LINE__)
-#define free(p) free_dbg(p, __FILE__, __LINE__)
-#define realloc(p, size) realloc_dbg(p, size, __FILE__, __LINE__)
-#define calloc(n, size) calloc_dbg(n, size, __FILE__, __LINE__)
-#define memalign(align, size) memalign_dbg(align, size, __FILE__, __LINE__)
-#define valloc(size) valloc_dbg(size, __FILE__, __LINE__)
-#define pvalloc(size) pvalloc_dbg(size, __FILE__, __LINE__)
-#define cfree(p) cfree_dbg(p, __FILE__, __LINE__)
-#define malloc_trim(pad) malloc_trim_dbg(pad, __FILE__, __LINE__)
-#define malloc_usable_size(p) malloc_usable_size_dbg(p, __FILE__, __LINE__)
-#define malloc_stats() malloc_stats_dbg(__FILE__, __LINE__)
-#define mallopt(flag, val) mallopt_dbg(flag, val, __FILE__, __LINE__)
-#define mallinfo() mallinfo_dbg(__FILE__, __LINE__)
+#define dmalloc(size) malloc_dbg(size, __FILE__, __LINE__)
+#define dfree(p) free_dbg(p, __FILE__, __LINE__)
+#define drealloc(p, size) realloc_dbg(p, size, __FILE__, __LINE__)
+#define dcalloc(n, size) calloc_dbg(n, size, __FILE__, __LINE__)
+#define dmemalign(align, size) memalign_dbg(align, size, __FILE__, __LINE__)
+#define dvalloc(size) valloc_dbg(size, __FILE__, __LINE__)
+#define dpvalloc(size) pvalloc_dbg(size, __FILE__, __LINE__)
+#define dmalloc_trim(pad) malloc_trim_dbg(pad, __FILE__, __LINE__)
+#define dmalloc_usable_size(p) malloc_usable_size_dbg(p, __FILE__, __LINE__)
+#define dmalloc_stats() malloc_stats_dbg(__FILE__, __LINE__)
+#define dmallopt(flag, val) mallopt_dbg(flag, val, __FILE__, __LINE__)
+#define dmallinfo() mallinfo_dbg(__FILE__, __LINE__)
#ifdef __cplusplus
@@ -66,7 +65,6 @@ void* calloc_dbg(size_t, size_t, const char *, int);
void* memalign_dbg(size_t, size_t, const char *, int);
void* valloc_dbg(size_t, const char *, int);
void* pvalloc_dbg(size_t, const char *, int);
-void cfree_dbg(void*, const char *, int);
int malloc_trim_dbg(size_t, const char *, int);
size_t malloc_usable_size_dbg(void*, const char *, int);
void malloc_stats_dbg(const char *, int);
@@ -87,7 +85,6 @@ void* calloc(size_t, size_t);
void* memalign(size_t, size_t);
void* valloc(size_t);
void* pvalloc(size_t);
-void cfree(void*);
int malloc_trim(size_t);
size_t malloc_usable_size(void*);
void malloc_stats(void);
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 075b3cc92..c63ed2058 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -731,18 +731,6 @@ signal_fixup_after_fork ()
sigproc_init ();
}
-void __stdcall
-signal_fixup_after_exec ()
-{
- /* Set up child's signal handlers */
- for (int i = 0; i < NSIG; i++)
- {
- myself->getsig (i).sa_mask = 0;
- if (myself->getsig (i).sa_handler != SIG_IGN)
- myself->getsig (i).sa_handler = SIG_DFL;
- }
-}
-
static int interrupt_on_return (sigthread *, int, void *, struct sigaction&) __attribute__((regparm(3)));
static int
interrupt_on_return (sigthread *th, int sig, void *handler, struct sigaction& siga)
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index 05dfa79ec..453eda4ae 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -264,7 +264,7 @@ fhandler_base::raw_read (void *ptr, size_t& ulen)
int prio = 0; /* ditto */
DWORD len = ulen;
- (ssize_t) ulen = -1;
+ ulen = (size_t) -1;
if (read_state)
{
h = GetCurrentThread ();
diff --git a/winsup/cygwin/heap.cc b/winsup/cygwin/heap.cc
index 95fdd12eb..5157a564d 100644
--- a/winsup/cygwin/heap.cc
+++ b/winsup/cygwin/heap.cc
@@ -139,7 +139,6 @@ sbrk (int n)
/* Couldn't allocate memory. Maybe we can reserve some more.
Reserve either the maximum of the standard cygwin_shared->heap_chunk_size ()
or the requested amount. Then attempt to actually allocate it. */
-
if ((newbrksize = cygheap->user_heap.chunk) < commitbytes)
newbrksize = commitbytes;
@@ -147,7 +146,7 @@ sbrk (int n)
|| VirtualAlloc (cygheap->user_heap.top, newbrksize = commitbytes, MEM_RESERVE, PAGE_NOACCESS))
&& VirtualAlloc (cygheap->user_heap.top, commitbytes, MEM_COMMIT, PAGE_READWRITE) != NULL)
{
- (char *) cygheap->user_heap.max += newbrksize;
+ (char *) cygheap->user_heap.max += pround (newbrksize);
goto good;
}
diff --git a/winsup/cygwin/include/sys/cygwin.h b/winsup/cygwin/include/sys/cygwin.h
index dccff2068..e117175e0 100644
--- a/winsup/cygwin/include/sys/cygwin.h
+++ b/winsup/cygwin/include/sys/cygwin.h
@@ -92,7 +92,7 @@ enum
PID_SPLIT_HEAP = 0x0100, /* Set if the heap has been split, */
/* which means we can't fork again. */
PID_MYSELF = 0x0200, /* Flag that pid is me. */
- PID_UNUSED1 = 0x0400, /* Set if process uses Winsock. */
+ PID_NOCLDSTOP = 0x0400, /* Set if no SIGCHLD signal on stop. */
PID_INITIALIZING = 0x0800, /* Set until ready to receive signals. */
PID_USETTY = 0x1000, /* Setting this enables or disables cygwin's */
/* tty support. This is inherited by */
@@ -207,6 +207,7 @@ extern void cygwin_set_impersonation_token (const HANDLE);
extern int cygwin32_attach_handle_to_fd (char *, int, HANDLE, mode_t, DWORD);
extern int cygwin_attach_handle_to_fd (char *, int, HANDLE, mode_t, DWORD);
+#ifdef __CYGWIN__
#include <sys/resource.h>
#define TTY_CONSOLE 0x40000000
@@ -250,11 +251,10 @@ struct external_pinfo
__uid32_t uid32;
__gid32_t gid32;
};
-
+#endif /*__CYGWIN__*/
#endif /*WINVER*/
#ifdef __cplusplus
};
#endif
-
#endif /* _SYS_CYGWIN_H */
diff --git a/winsup/cygwin/libc/fnmatch.c b/winsup/cygwin/libc/fnmatch.c
index 709bc78c8..b48d9e00a 100644
--- a/winsup/cygwin/libc/fnmatch.c
+++ b/winsup/cygwin/libc/fnmatch.c
@@ -66,9 +66,7 @@ static char rcsid[] = "$OpenBSD: fnmatch.c,v 1.7 2000/03/23 19:13:51 millert Exp
static int rangematch __P((const char *, char, int, char **));
int
-fnmatch(pattern, string, flags)
- const char *pattern, *string;
- int flags;
+fnmatch(const char *pattern, const char *string, int flags)
{
const char *stringstart;
char *newp;
@@ -168,15 +166,7 @@ fnmatch(pattern, string, flags)
}
static int
-#ifdef __STDC__
rangematch(const char *pattern, char test, int flags, char **newp)
-#else
-rangematch(pattern, test, flags, newp)
- char *pattern;
- char test;
- int flags;
- char **newp;
-#endif
{
int negate, ok;
char c, c2;
diff --git a/winsup/cygwin/malloc.cc b/winsup/cygwin/malloc.cc
index 383a590c8..7c85bd681 100644
--- a/winsup/cygwin/malloc.cc
+++ b/winsup/cygwin/malloc.cc
@@ -3744,6 +3744,7 @@ void fREe(mem) Void_t* mem;
mchunkptr bck; /* misc temp for linking */
mchunkptr fwd; /* misc temp for linking */
+ check_malloc_state();
/* free(0) has no effect */
if (mem != 0) {
p = mem2chunk(mem);
@@ -3878,6 +3879,7 @@ void fREe(mem) Void_t* mem;
#endif
}
}
+ check_malloc_state();
}
/*
diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc
index 36463c3b4..b888ab60c 100644
--- a/winsup/cygwin/net.cc
+++ b/winsup/cygwin/net.cc
@@ -25,6 +25,7 @@ details. */
#include <netdb.h>
#define USE_SYS_TYPES_FD_SET
#include <winsock2.h>
+#include <assert.h>
#include "cygerrno.h"
#include "security.h"
#include "fhandler.h"
@@ -381,95 +382,205 @@ set_host_errno ()
h_errno = NETDB_INTERNAL;
}
-static void
-free_char_list (char **clist)
+inline int
+DWORD_round (int n)
{
- if (clist)
- {
- for (char **cl = clist; *cl; ++cl)
- free (*cl);
- free (clist);
- }
+ return sizeof (DWORD) * (((n + sizeof (DWORD) - 1)) / sizeof (DWORD));
}
-static char **
-dup_char_list (char **src)
+inline int
+strlen_round (const char *s)
{
- char **dst;
- int cnt = 0;
-
- for (char **cl = src; *cl; ++cl)
- ++cnt;
- if (!(dst = (char **) calloc (cnt + 1, sizeof *dst)))
- return NULL;
- while (cnt-- > 0)
- if (!(dst[cnt] = strdup (src[cnt])))
- return NULL;
- return dst;
+ if (!s)
+ return 0;
+ return DWORD_round (strlen (s) + 1);
}
-#define free_addr_list(addr_list) free_char_list (addr_list)
+#pragma pack(push,2)
+struct pservent
+{
+ char *s_name;
+ char **s_aliases;
+ short s_port;
+ char *s_proto;
+};
+#pragma pack(pop)
-static char **
-dup_addr_list (char **src, unsigned int size)
+struct unionent
{
- char **dst;
- int cnt = 0;
+ char *name;
+ char **list;
+ short port_proto_addrtype;
+ short h_len;
+ union
+ {
+ char *s_proto;
+ char **h_addr_list;
+ };
+};
- for (char **cl = src; *cl; ++cl)
- ++cnt;
- if (!(dst = (char **) calloc (cnt + 1, sizeof *dst)))
- return NULL;
- while (cnt-- > 0)
- {
- if (!(dst[cnt] = (char *) malloc (size)))
- return NULL;
- memcpy (dst[cnt], src[cnt], size);
- }
- return dst;
-}
+enum struct_type
+{
+ is_hostent, is_protoent, is_servent
+};
-static void
-free_protoent_ptr (struct protoent *&p)
+static const char *entnames[] = {"host", "proto", "serv"};
+
+/* Generic "dup a {host,proto,serv}ent structure" function.
+ This is complicated because we need to be able to free the
+ structure at any point and we can't rely on the pointer contents
+ being untouched by callers. So, we allocate a chunk of memory
+ large enough to hold the structure and all of the stuff it points
+ to then we copy the source into this new block of memory.
+ The 'unionent' struct is a union of all of the currently used
+ *ent structure. */
+
+#ifdef DEBUGGING
+static void *
+#else
+static inline void *
+#endif
+dup_ent (void *old, void *src0, struct_type type)
{
- if (p)
+ if (old)
{
- debug_printf ("protoent: %s", p->p_name);
-
- if (p->p_name)
- free (p->p_name);
- free_char_list (p->p_aliases);
- free ((void *) p);
- p = NULL;
+ debug_printf ("freeing old %sent structure \"%s\" %p\n", entnames[type],
+ ((unionent *) old)->name, old);
+ free (old);
}
-}
-static struct protoent *
-dup_protoent_ptr (struct protoent *src)
-{
- if (!src)
+ if (!src0)
return NULL;
- struct protoent *dst = (struct protoent *) calloc (1, sizeof *dst);
+ unionent *src = (unionent *) src0;
+ debug_printf ("duping %sent \"%s\", %p", entnames[type],
+ src ? src->name : "<null!>", src);
- if (!dst)
- return NULL;
+ /* Find the size of the raw structure minus any character strings, etc. */
+ int sz, struct_sz;
+ switch (type)
+ {
+ case is_protoent:
+ struct_sz = sizeof (protoent);
+ break;
+ case is_servent:
+ struct_sz = sizeof (servent);
+ break;
+ case is_hostent:
+ struct_sz = sizeof (hostent);
+ break;
+ default:
+ api_fatal ("called with invalid value %d", type);
+ break;
+ }
- debug_printf ("protoent: %s", src->p_name);
+ /* Every *ent begins with a name. Calculate it's length. */
+ int namelen = strlen_round (src->name);
+ sz = struct_sz + namelen;
- dst->p_proto = src->p_proto;
- if (src->p_name && !(dst->p_name = strdup (src->p_name)))
- goto out;
- if (src->p_aliases && !(dst->p_aliases = dup_char_list (src->p_aliases)))
- goto out;
+ char **av;
+ /* The next field in every *ent is an argv list of "something".
+ Calculate the number of components and how much space the
+ character strings will take. */
+ int list_len = 0;
+ for (av = src->list; av && *av; av++)
+ {
+ list_len++;
+ sz += sizeof (char **) + strlen_round (*av);
+ }
- debug_printf ("protoent: copied %s", dst->p_name);
+ /* NULL terminate if there actually was a list */
+ if (av)
+ {
+ sz += sizeof (char **);
+ list_len++;
+ }
- return dst;
+ /* Do servent/hostent specific processing */
+ int protolen = 0;
+ int addr_list_len = 0;
+ if (type == is_servent)
+ sz += (protolen = strlen_round (src->s_proto));
+ else if (type == is_hostent)
+ {
+ /* Calculate the length and storage used for h_addr_list */
+ for (av = src->h_addr_list; av && *av; av++)
+ {
+ addr_list_len++;
+ sz += sizeof (char **) + DWORD_round (src->h_len);
+ }
+ if (av)
+ {
+ sz += sizeof (char **);
+ addr_list_len++;
+ }
+ }
-out:
- free_protoent_ptr (dst);
- return NULL;
+ /* Allocate the storage needed */
+ unionent *dst = (unionent *) calloc (1, sz);
+
+ /* Hopefully, this worked. */
+ if (dst)
+ {
+ /* This field is common to all *ent structures but named differently
+ in each, of course. */
+ dst->port_proto_addrtype = src->port_proto_addrtype;
+
+ /* Copy the name field to dst, using space just beyond the end of
+ the dst structure. */
+ char *dp = ((char *) dst) + struct_sz;
+ strcpy (dst->name = dp, src->name);
+ dp += namelen;
+
+ /* Copy the 'list' type to dst, using space beyond end of structure
+ + storage for name. */
+ if (src->list)
+ {
+ char **dav = dst->list = (char **) dp;
+ dp += sizeof (char **) * list_len;
+ for (av = src->list; av && *av; av++)
+ {
+ int len = strlen (*av) + 1;
+ memcpy (*dav++ = dp, *av, len);
+ dp += DWORD_round (len);
+ }
+ }
+
+ /* Do servent/hostent specific processing. */
+ if (type == is_servent)
+ {
+ if (src->s_proto)
+ {
+ char *s_proto;
+ /* Windows 95 idiocy. Structure is misaligned on Windows 95.
+ Kludge around this by trying a different pointer alignment. */
+ if (IsBadReadPtr (src->s_proto, sizeof (src->s_proto))
+ && !IsBadReadPtr (((pservent *) src)->s_proto, sizeof (src->s_proto)))
+ s_proto = ((pservent *) src)->s_proto;
+ else
+ s_proto = src->s_proto;
+ strcpy (dst->s_proto = dp, s_proto);
+ dp += protolen;
+ }
+ }
+ else if (type == is_hostent)
+ {
+ /* Transfer h_len and duplicate contents of h_addr_list, using
+ memory after 'list' allocation. */
+ dst->h_len = src->h_len;
+ char **dav = dst->h_addr_list = (char **) dp;
+ dp += sizeof (char **) * addr_list_len;
+ for (av = src->h_addr_list; av && *av; av++)
+ {
+ memcpy (*dav++ = dp, *av, src->h_len);
+ dp += DWORD_round (src->h_len);
+ }
+ }
+ /* Sanity check that we did our bookkeeping correctly. */
+ assert ((dp - (char *) dst) == sz);
+ }
+ debug_printf ("duped %sent \"%s\", %p", entnames[type], dst ? dst->name : "<null!>", dst);
+ return dst;
}
#ifdef _MT_SAFE
@@ -484,8 +595,8 @@ cygwin_getprotobyname (const char *p)
{
if (check_null_str_errno (p))
return NULL;
- free_protoent_ptr (protoent_buf);
- protoent_buf = dup_protoent_ptr (getprotobyname (p));
+ protoent_buf = (protoent *) dup_ent (protoent_buf, getprotobyname (p),
+ is_protoent);
if (!protoent_buf)
set_winsock_errno ();
@@ -497,8 +608,8 @@ cygwin_getprotobyname (const char *p)
extern "C" struct protoent *
cygwin_getprotobynumber (int number)
{
- free_protoent_ptr (protoent_buf);
- protoent_buf = dup_protoent_ptr (getprotobynumber (number));
+ protoent_buf = (protoent *) dup_ent (protoent_buf, getprotobynumber (number),
+ is_protoent);
if (!protoent_buf)
set_winsock_errno ();
@@ -828,71 +939,6 @@ cygwin_connect (int fd, const struct sockaddr *name, int namelen)
return res;
}
-static void
-free_servent_ptr (struct servent *&p)
-{
- if (p)
- {
- debug_printf ("servent: %s", p->s_name);
-
- if (p->s_name)
- free (p->s_name);
- if (p->s_proto)
- free (p->s_proto);
- free_char_list (p->s_aliases);
- free ((void *) p);
- p = NULL;
- }
-}
-
-#pragma pack(push,2)
-struct pservent
-{
- char *s_name;
- char **s_aliases;
- short s_port;
- char *s_proto;
-};
-
-#pragma pack(pop)
-static struct servent *
-dup_servent_ptr (struct servent *src)
-{
- if (!src)
- return NULL;
-
- struct servent *dst = (struct servent *) calloc (1, sizeof *dst);
-
- if (!dst)
- return NULL;
-
- debug_printf ("servent: %s", src->s_name);
-
- dst->s_port = src->s_port;
- if (src->s_name && !(dst->s_name = strdup (src->s_name)))
- goto out;
- if (src->s_aliases && !(dst->s_aliases = dup_char_list (src->s_aliases)))
- goto out;
- char *s_proto;
-
- if (IsBadReadPtr (src->s_proto, sizeof (src->s_proto))
- && !IsBadReadPtr (((pservent *) src)->s_proto, sizeof (src->s_proto)))
- s_proto = ((pservent *) src)->s_proto;
- else
- s_proto = src->s_proto;
-
- if (s_proto && !(dst->s_proto = strdup (s_proto)))
- goto out;
-
- debug_printf ("servent: copied %s", dst->s_name);
-
- return dst;
-
-out:
- free_servent_ptr (dst);
- return NULL;
-}
-
#ifdef _MT_SAFE
#define servent_buf _reent_winsup ()->_servent_buf
#else
@@ -909,8 +955,8 @@ cygwin_getservbyname (const char *name, const char *proto)
|| (proto != NULL && check_null_str_errno (proto)))
return NULL;
- free_servent_ptr (servent_buf);
- servent_buf = dup_servent_ptr (getservbyname (name, proto));
+ servent_buf = (servent *) dup_ent (servent_buf, getservbyname (name, proto),
+ is_servent);
if (!servent_buf)
set_winsock_errno ();
@@ -927,8 +973,8 @@ cygwin_getservbyport (int port, const char *proto)
if (proto != NULL && check_null_str_errno (proto))
return NULL;
- free_servent_ptr (servent_buf);
- servent_buf = dup_servent_ptr (getservbyport (port, proto));
+ servent_buf = (servent *) dup_ent (servent_buf, getservbyport (port, proto),
+ is_servent);
if (!servent_buf)
set_winsock_errno ();
@@ -959,54 +1005,6 @@ cygwin_gethostname (char *name, size_t len)
return 0;
}
-static void
-free_hostent_ptr (struct hostent *&p)
-{
- if (p)
- {
- debug_printf ("hostent: %s", p->h_name);
-
- if (p->h_name)
- free ((void *) p->h_name);
- free_char_list (p->h_aliases);
- free_addr_list (p->h_addr_list);
- free ((void *) p);
- p = NULL;
- }
-}
-
-static struct hostent *
-dup_hostent_ptr (struct hostent *src)
-{
- if (!src)
- return NULL;
-
- struct hostent *dst = (struct hostent *) calloc (1, sizeof *dst);
-
- if (!dst)
- return NULL;
-
- debug_printf ("hostent: %s", src->h_name);
-
- dst->h_addrtype = src->h_addrtype;
- dst->h_length = src->h_length;
- if (src->h_name && !(dst->h_name = strdup (src->h_name)))
- goto out;
- if (src->h_aliases && !(dst->h_aliases = dup_char_list (src->h_aliases)))
- goto out;
- if (src->h_addr_list
- && !(dst->h_addr_list = dup_addr_list (src->h_addr_list, src->h_length)))
- goto out;
-
- debug_printf ("hostent: copied %s", dst->h_name);
-
- return dst;
-
-out:
- free_hostent_ptr (dst);
- return NULL;
-}
-
#ifdef _MT_SAFE
#define hostent_buf _reent_winsup ()->_hostent_buf
#else
@@ -1045,8 +1043,8 @@ cygwin_gethostbyname (const char *name)
return &tmp;
}
- free_hostent_ptr (hostent_buf);
- hostent_buf = dup_hostent_ptr (gethostbyname (name));
+ hostent_buf = (hostent *) dup_ent (hostent_buf, gethostbyname (name),
+ is_hostent);
if (!hostent_buf)
{
set_winsock_errno ();
@@ -1069,8 +1067,9 @@ cygwin_gethostbyaddr (const char *addr, int len, int type)
if (__check_invalid_read_ptr_errno (addr, len))
return NULL;
- free_hostent_ptr (hostent_buf);
- hostent_buf = dup_hostent_ptr (gethostbyaddr (addr, len, type));
+ hostent_buf = (hostent *) dup_ent (hostent_buf,
+ gethostbyaddr (addr, len, type),
+ is_hostent);
if (!hostent_buf)
{
set_winsock_errno ();
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 26b6aa82f..58114977d 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -1124,7 +1124,7 @@ win32_device_name (const char *src_path, char *win32_path,
case FH_SOCKET:
char *c;
strcpy (win32_path, src_path);
- while (c = strchr (win32_path, '/'))
+ while ((c = strchr (win32_path, '/')))
*c = '\\';
break;
case FH_RANDOM:
diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h
index 89b683f94..e437328b6 100644
--- a/winsup/cygwin/pinfo.h
+++ b/winsup/cygwin/pinfo.h
@@ -36,6 +36,8 @@ enum picom
PICOM_CMDLINE = 1
};
+extern struct sigaction *global_sigs;
+
class _pinfo
{
public:
@@ -110,11 +112,9 @@ public:
inline struct sigaction& getsig (int sig)
{
- return thread2signal ? thread2signal->sigs[sig] : sigs[sig];
+ return global_sigs[sig];
}
- inline void copysigs (_pinfo *p) {memcpy (sigs, p->sigs, sizeof (sigs));}
-
inline sigset_t& getsigmask ()
{
return thread2signal ? *thread2signal->sigmask : sig_mask;
@@ -143,7 +143,6 @@ public:
friend void __stdcall set_myself (pid_t, HANDLE);
private:
- struct sigaction sigs[NSIG];
sigset_t sig_mask; /* one set for everything to ignore. */
LONG _sigtodo[NSIG + __SIGOFFSET];
pthread *thread2signal; // NULL means thread any other means a pthread
diff --git a/winsup/cygwin/shm.cc b/winsup/cygwin/shm.cc
index 2fef656e9..a7edeace3 100644
--- a/winsup/cygwin/shm.cc
+++ b/winsup/cygwin/shm.cc
@@ -1,6 +1,6 @@
/* shm.cc: Single unix specification IPC interface for Cygwin.
- Copyright 2002 Red Hat, Inc.
+ Copyright 2002,2003 Red Hat, Inc.
Written by Conrad Scott <conrad.scott@dsl.pipex.com>.
Based on code by Robert Collins <robert.collins@hotmail.com>.
diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc
index baad718b9..2b890dd62 100644
--- a/winsup/cygwin/signal.cc
+++ b/winsup/cygwin/signal.cc
@@ -338,6 +338,12 @@ sigaction (int sig, const struct sigaction *newact, struct sigaction *oldact)
if (newact->sa_handler == SIG_DFL && sig == SIGCHLD)
sig_clear (sig);
set_sigcatchers (oa.sa_handler, newact->sa_handler);
+ if (sig == SIGCHLD)
+ {
+ myself->process_state &= ~PID_NOCLDSTOP;
+ if (newact->sa_flags & SA_NOCLDSTOP);
+ myself->process_state |= PID_NOCLDSTOP;
+ }
}
if (oldact)
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index fd4f295cc..b14fbac1b 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -17,6 +17,7 @@ details. */
#include <stdlib.h>
#include <sys/cygwin.h>
#include <assert.h>
+#include <sys/signal.h>
#include "cygerrno.h"
#include "sync.h"
#include "sigproc.h"
@@ -48,12 +49,35 @@ details. */
#define NZOMBIES 256
-LONG local_sigtodo[TOTSIGS];
-inline LONG* getlocal_sigtodo (int sig)
+static LONG local_sigtodo[TOTSIGS];
+struct sigaction *global_sigs;
+
+inline LONG *
+getlocal_sigtodo (int sig)
{
return local_sigtodo + __SIGOFFSET + sig;
}
+void __stdcall
+sigalloc ()
+{
+ cygheap->sigs = global_sigs =
+ (struct sigaction *) ccalloc (HEAP_SIGS, NSIG, sizeof (struct sigaction));
+}
+
+void __stdcall
+signal_fixup_after_exec ()
+{
+ global_sigs = cygheap->sigs;
+ /* Set up child's signal handlers */
+ for (int i = 0; i < NSIG; i++)
+ {
+ myself->getsig (i).sa_mask = 0;
+ if (myself->getsig (i).sa_handler != SIG_IGN)
+ myself->getsig (i).sa_handler = SIG_DFL;
+ }
+}
+
/*
* Global variables
*/
@@ -300,7 +324,6 @@ proc_subproc (DWORD what, DWORD val)
vchild->sid = myself->sid;
vchild->ctty = myself->ctty;
vchild->process_state |= PID_INITIALIZING | (myself->process_state & PID_USETTY);
- vchild->copysigs (myself);
sigproc_printf ("added pid %d to wait list, slot %d, winpid %p, handle %p",
vchild->pid, nchildren, vchild->dwProcessId,
@@ -540,12 +563,11 @@ sig_dispatch_pending ()
sigframe thisframe (mainthread);
- int was_pending = pending_signals;
#ifdef DEBUGGING
- sigproc_printf ("pending_signals %d", was_pending);
+ sigproc_printf ("pending_signals %d", pending_signals);
#endif
- if (!was_pending)
+ if (!pending_signals)
#ifdef DEBUGGING
sigproc_printf ("no need to wake anything up");
#else
@@ -559,10 +581,7 @@ sig_dispatch_pending ()
#endif
}
- if (was_pending)
- thisframe.call_signal_handler ();
-
- return was_pending;
+ return thisframe.call_signal_handler ();
}
/* Message initialization. Called from dll_crt0_1
diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h
index 5cedaeae3..360ae8bcb 100644
--- a/winsup/cygwin/sigproc.h
+++ b/winsup/cygwin/sigproc.h
@@ -120,6 +120,7 @@ int __stdcall sig_send (_pinfo *, int, DWORD ebp = (DWORD) __builtin_frame_addre
void __stdcall signal_fixup_after_fork ();
void __stdcall signal_fixup_after_exec ();
void __stdcall wait_for_sigthread ();
+void __stdcall sigalloc ();
extern char myself_nowait_dummy[];
extern char myself_nowait_nonmain_dummy[];
diff --git a/winsup/cygwin/threaded_queue.cc b/winsup/cygwin/threaded_queue.cc
deleted file mode 100755
index ba0fe4178..000000000
--- a/winsup/cygwin/threaded_queue.cc
+++ /dev/null
@@ -1,408 +0,0 @@
-/* threaded_queue.cc
-
- Copyright 2001, 2002 Red Hat Inc.
-
- Written by Robert Collins <rbtcollins@hotmail.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 "woutsup.h"
-
-#include <assert.h>
-#include <errno.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <stdlib.h>
-#include "threaded_queue.h"
-
-/*****************************************************************************/
-
-/* queue_request */
-
-queue_request::~queue_request ()
-{}
-
-/*****************************************************************************/
-
-/* threaded_queue */
-
-threaded_queue::threaded_queue (const size_t initial_workers)
- : _workers_count (0),
- _running (false),
- _submitters_head (NULL),
- _requests_count (0),
- _requests_head (NULL),
- _requests_sem (NULL)
-{
- InitializeCriticalSection (&_queue_lock);
-
- // This semaphore's count is the number of requests on the queue.
- // The maximum count (129792) is calculated as MAXIMUM_WAIT_OBJECTS
- // multiplied by max. threads per process (2028?), which is (a few)
- // more requests than could ever be pending with the current design.
-
- _requests_sem = CreateSemaphore (NULL, // SECURITY_ATTRIBUTES
- 0, // Initial count
- 129792, // Maximum count
- NULL); // Anonymous
-
- if (!_requests_sem)
- {
- system_printf (("failed to create the request queue semaphore, "
- "error = %lu"),
- GetLastError ());
- abort ();
- }
-
- create_workers (initial_workers);
-}
-
-threaded_queue::~threaded_queue ()
-{
- if (_running)
- stop ();
-
- debug_printf ("deleting all pending queue requests");
- queue_request *reqptr = _requests_head;
- while (reqptr)
- {
- queue_request *const ptr = reqptr;
- reqptr = reqptr->_next;
- safe_delete (ptr);
- }
-
- DeleteCriticalSection (&_queue_lock);
- if (_requests_sem)
- (void) CloseHandle (_requests_sem);
-}
-
-/* FIXME: return success or failure rather than quitting */
-void
-threaded_queue::add_submission_loop (queue_submission_loop *const submitter)
-{
- assert (this);
- assert (submitter);
- assert (submitter->_queue == this);
- assert (!submitter->_next);
-
- submitter->_next =
- TInterlockedExchangePointer (&_submitters_head, submitter);
-
- if (_running)
- submitter->start ();
-}
-
-bool
-threaded_queue::start ()
-{
- EnterCriticalSection (&_queue_lock);
- const bool was_running = _running;
- _running = true;
- queue_submission_loop *loopptr = _submitters_head;
- LeaveCriticalSection (&_queue_lock);
-
- if (!was_running)
- {
- debug_printf ("starting all queue submission loops");
-
- while (loopptr)
- {
- queue_submission_loop *const ptr = loopptr;
- loopptr = loopptr->_next;
- ptr->start ();
- }
- }
-
- return was_running;
-}
-
-bool
-threaded_queue::stop ()
-{
- EnterCriticalSection (&_queue_lock);
- const bool was_running = _running;
- _running = false;
- queue_submission_loop *loopptr = _submitters_head;
- LeaveCriticalSection (&_queue_lock);
-
- if (was_running)
- {
- debug_printf ("stopping all queue submission loops");
- while (loopptr)
- {
- queue_submission_loop *const ptr = loopptr;
- loopptr = loopptr->_next;
- ptr->stop ();
- }
-
- ReleaseSemaphore (_requests_sem, _workers_count, NULL);
- while (_workers_count)
- {
- debug_printf (("waiting for worker threads to terminate: "
- "%lu still running"),
- _workers_count);
- Sleep (1000);
- }
- debug_printf ("all worker threads have terminated");
- }
-
- return was_running;
-}
-
-/* FIXME: return success or failure */
-void
-threaded_queue::add (queue_request *const therequest)
-{
- assert (this);
- assert (therequest);
- assert (!therequest->_next);
-
- if (!_workers_count)
- {
- system_printf ("warning: no worker threads to handle request!");
- // FIXME: And then what?
- }
-
- EnterCriticalSection (&_queue_lock);
- if (!_requests_head)
- _requests_head = therequest;
- else
- {
- /* Add to the queue end. */
- queue_request *reqptr = _requests_head;
- for (; reqptr->_next; reqptr = reqptr->_next)
- {}
- assert (reqptr);
- assert (!reqptr->_next);
- reqptr->_next = therequest;
- }
-
- _requests_count += 1;
- assert (_requests_count > 0);
- LeaveCriticalSection (&_queue_lock);
-
- (void) ReleaseSemaphore (_requests_sem, 1, NULL);
-}
-
-/*static*/ DWORD WINAPI
-threaded_queue::start_routine (const LPVOID lpParam)
-{
- class threaded_queue *const queue = (class threaded_queue *) lpParam;
- assert (queue);
-
- queue->worker_loop ();
-
- const long count = InterlockedDecrement (&queue->_workers_count);
- assert (count >= 0);
-
- if (queue->_running)
- debug_printf ("worker loop has exited; thread about to terminate");
-
- return 0;
-}
-
-/* Called from the constructor: so no need to be thread-safe until the
- * worker threads start to be created; thus the interlocked increment
- * of the `_workers_count' field.
- */
-
-void
-threaded_queue::create_workers (const size_t initial_workers)
-{
- assert (initial_workers > 0);
-
- for (unsigned int i = 0; i != initial_workers; i++)
- {
- const long count = InterlockedIncrement (&_workers_count);
- assert (count > 0);
-
- DWORD tid;
- const HANDLE hThread =
- CreateThread (NULL, 0, start_routine, this, 0, &tid);
-
- if (!hThread)
- {
- system_printf ("failed to create thread, error = %lu",
- GetLastError ());
- abort ();
- }
-
- (void) CloseHandle (hThread);
- }
-}
-
-void
-threaded_queue::worker_loop ()
-{
- while (true)
- {
- const DWORD rc = WaitForSingleObject (_requests_sem, INFINITE);
- if (rc == WAIT_FAILED)
- {
- system_printf ("wait for request semaphore failed, error = %lu",
- GetLastError ());
- return;
- }
- assert (rc == WAIT_OBJECT_0);
-
- EnterCriticalSection (&_queue_lock);
- if (!_running)
- {
- LeaveCriticalSection (&_queue_lock);
- return;
- }
-
- assert (_requests_head);
- queue_request *const reqptr = _requests_head;
- _requests_head = reqptr->_next;
-
- _requests_count -= 1;
- assert (_requests_count >= 0);
- LeaveCriticalSection (&_queue_lock);
-
- assert (reqptr);
- reqptr->process ();
- safe_delete (reqptr);
- }
-}
-
-/*****************************************************************************/
-
-/* queue_submission_loop */
-
-queue_submission_loop::queue_submission_loop (threaded_queue *const queue,
- const bool ninterruptible)
- : _running (false),
- _interrupt_event (NULL),
- _queue (queue),
- _interruptible (ninterruptible),
- _hThread (NULL),
- _tid (0),
- _next (NULL)
-{
- if (_interruptible)
- {
- // verbose: debug_printf ("creating an interruptible processing thread");
-
- _interrupt_event = CreateEvent (NULL, // SECURITY_ATTRIBUTES
- FALSE, // Auto-reset
- FALSE, // Initially non-signalled
- NULL); // Anonymous
-
- if (!_interrupt_event)
- {
- system_printf ("failed to create interrupt event, error = %lu",
- GetLastError ());
- abort ();
- }
- }
-}
-
-queue_submission_loop::~queue_submission_loop ()
-{
- if (_running)
- stop ();
- if (_interrupt_event)
- (void) CloseHandle (_interrupt_event);
- if (_hThread)
- (void) CloseHandle (_hThread);
-}
-
-bool
-queue_submission_loop::start ()
-{
- assert (this);
- assert (!_hThread);
-
- const bool was_running = _running;
-
- if (!was_running)
- {
- _running = true;
-
- _hThread = CreateThread (NULL, 0, start_routine, this, 0, &_tid);
- if (!_hThread)
- {
- system_printf ("failed to create thread, error = %lu",
- GetLastError ());
- abort ();
- }
- }
-
- return was_running;
-}
-
-bool
-queue_submission_loop::stop ()
-{
- assert (this);
- assert (_hThread && _hThread != INVALID_HANDLE_VALUE);
-
- const bool was_running = _running;
-
- if (_running)
- {
- _running = false;
-
- if (_interruptible)
- {
- assert (_interrupt_event
- && _interrupt_event != INVALID_HANDLE_VALUE);
-
- SetEvent (_interrupt_event);
-
- if (WaitForSingleObject (_hThread, 1000) == WAIT_TIMEOUT)
- {
- system_printf (("request loop thread %lu failed to shutdown "
- "when asked politely: about to get heavy"),
- _tid);
-
- if (!TerminateThread (_hThread, 0))
- {
- system_printf (("failed to kill request loop thread %lu"
- ", error = %lu"),
- _tid, GetLastError ());
- abort ();
- }
- }
- }
- else
- {
- // FIXME: could wait to see if the request loop notices that
- // the submission loop is no longer running and shuts down
- // voluntarily.
-
- debug_printf ("killing request loop thread %lu", _tid);
-
- if (!TerminateThread (_hThread, 0))
- system_printf (("failed to kill request loop thread %lu"
- ", error = %lu"),
- _tid, GetLastError ());
- }
- }
-
- return was_running;
-}
-
-/*static*/ DWORD WINAPI
-queue_submission_loop::start_routine (const LPVOID lpParam)
-{
- class queue_submission_loop *const submission_loop =
- (class queue_submission_loop *) lpParam;
- assert (submission_loop);
-
- submission_loop->request_loop ();
-
- debug_printf ("submission loop has exited; thread about to terminate");
-
- submission_loop->stop ();
-
- return 0;
-}
-
-/*****************************************************************************/
diff --git a/winsup/doc/ChangeLog b/winsup/doc/ChangeLog
index 6739c069f..96e19d9a9 100644
--- a/winsup/doc/ChangeLog
+++ b/winsup/doc/ChangeLog
@@ -1,3 +1,9 @@
+2003-09-01 Corinna Vinschen <corinna@vinschen.de>
+
+ * pathnames.sgml: Remove description how to mount raw devices and
+ dicourage it. Desparately try to make usage of raw devices a bit
+ clearer.
+
2003-07-31 Joshua Daniel Franklin <joshuadfranklin@yahoo.com>
* effectively.sgml: New file, "Using Cygwin Effectively with Windows".
diff --git a/winsup/doc/pathnames.sgml b/winsup/doc/pathnames.sgml
index 12bff5685..13441e995 100644
--- a/winsup/doc/pathnames.sgml
+++ b/winsup/doc/pathnames.sgml
@@ -170,62 +170,17 @@ although commands such as <command>ls /dev/tty</command> work fine.
<para>Windows NT/W2K/XP additionally support raw devices like floppies,
disks, partitions and tapes. These are accessed from Cygwin applications
using POSIX device names which are supported in two different ways.
-Up to 1.3.3, Cygwin only uses Win32 device names, since 1.3.4
-it additionally uses NT internal device names.
</para>
-<para>Up to Cygwin 1.3.3 the only way to access those devices is
-to mount the Win32 device names to a POSIX device name.
+<para>Up to Cygwin 1.3.3 the only way to access those devices was
+to mount the Win32 device names to a POSIX device name but this usage
+is discouraged since Cygwin 1.3.4 and only kept for backward compatibility.
</para>
<para>
-The Win32 device name for a partition is the drive letter
-with leading <filename>\\.\</filename>, so the floppy would be
-<filename>\\.\A:</filename>, the first partition typically
-<filename>\\.\C:</filename>. Complete drives (except floppies and CD-ROMS
-which are supported as partitions only) are named
-<filename>\\.\PHYSICALDRIVEx</filename>. The <literal>x</literal>
-is the drive number which you can check in the disk manager.
-Each drive line has prepended the text "Disk x".
-</para>
-
-<para>To access tape drives the Win32 file name <filename>\\.\TAPEx</filename>
-is used. For example the first installed tape device is named
-<filename>\\.\tape0</filename>.
-</para>
-
-<para>
-The naming convention is simple: The name of the POSIX device has to begin with
-<filename>/dev/</filename> and the rest is as you like. The only
-exception are tape devices. To identify if the tape device is
-used as a rewind or a no-rewind device the name must not begin with
-<literal>n</literal> (rewind) or has to begin with <literal>n</literal>
-(no-rewind).
-</para>
-
-<para>Some examples:</para>
-
-<screen>
-mount -b //./A: /dev/fd0 # mount floppy as raw block special
-mount -b //./physicaldrive1 /dev/hdb # mount "Disk 1"
-mount -b //./tape0 /dev/st0 # mount first tape as the rewind device...
-mount -b //./tape0 /dev/nst0 # ...and as the no-rewind device
-</screen>
-
-<para>Note the usage of the <literal>-b</literal> option. It is best to
-include the -b option when mounting these devices to ensure that all
-file I/O is in "binary mode".
-</para>
-
-<para>
-Since Cygwin 1.3.4 raw devices are accessible from inside of Cygwin processes
-using fixed POSIX device names. That means, you don't have to mount the devices
-anymore which results in a more cleaner mount table.
-</para>
-
-<para>
-These new fixed POSIX device names are generated using a direct conversion
-from the POSIX namespace to the internal NT namespace.
+Beginning with Cygwin 1.3.4, raw devices are accessible by Cygwin processes
+using fixed POSIX device names. These fixed POSIX device names are generated
+using a direct conversion from the POSIX namespace to the internal NT namespace.
E.g. the first harddisk is the NT internal device \device\harddisk0\partition0
or the first partition on the third harddisk is \device\harddisk2\partition1.
The first floppy in the system is \device\floppy0, the first CD-ROM is
@@ -272,19 +227,23 @@ links as they are created on Linux systems for convenience:
<screen>
ln -s /dev/scd0 /dev/cdrom
-ln -s /dev/st0 /dev/tape
+ln -s /dev/scd2 /dev/sr2 # actually srX are real device nodes on Linux but who cares.
+ln -s /dev/nst0 /dev/tape
...
</screen>
<para>
Note that you can't use the mount table to map from fixed device name
to your own device name or to map from internal NT device name to
-your own device name. The following two examples will not work:
+your own device name. Also using symbolic links to map from the internal
+NT device name to your own device name will not do what you want.
+The following three examples will not work as expected:
</para>
<screen>
-mount -s -f -b /dev/st0 /dev/tape
-mount -s -f -b /device/tape0 /dev/tape
+mount -f -b /dev/nst0 /dev/tape
+mount -f -b /device/tape0 /dev/tape
+ln -s /device/tape0 /dev/tape
</screen>
</sect2>
diff --git a/winsup/utils/ChangeLog b/winsup/utils/ChangeLog
index 639d05b33..06df99f3e 100644
--- a/winsup/utils/ChangeLog
+++ b/winsup/utils/ChangeLog
@@ -1,3 +1,18 @@
+2003-08-31 Christopher Faylor <cgf@redhat.com>
+
+ * kill.cc (forcekill): Silence some compiler warnings.
+
+2003-08-31 Christopher Faylor <cgf@redhat.com>
+
+ * Makefile.in: Oops. Put the '...' in the right place.
+
+2003-08-31 Christopher Faylor <cgf@redhat.com>
+
+ * Makefile.in: Display "..." when not-verbose.
+
+ * kill.cc (forcekill): Default to entered pid when pinfo fails. Issue
+ some warnings when things don't work.
+
2003-08-17 David Rothenberger <daveroth@acm.org>
* dump_setup.cc (check_package_files): Strip leading / and ./ from
diff --git a/winsup/utils/Makefile.in b/winsup/utils/Makefile.in
index a52d48fca..43c0ee5da 100644
--- a/winsup/utils/Makefile.in
+++ b/winsup/utils/Makefile.in
@@ -207,6 +207,6 @@ endif
ifdef VERBOSE
$(CXX) -o $@ ${firstword $^} -B$(cygwin_build)/ $(ALL_LDFLAGS)
else
- @echo $(CXX) -o $@ ${firstword $^} ${filter-out -B%, $(ALL_LDFLAGS)};\
+ @echo $(CXX) -o $@ ${firstword $^} ... ${filter-out -B%, $(ALL_LDFLAGS)};\
$(CXX) -o $@ ${firstword $^} -B$(cygwin_build)/ $(ALL_LDFLAGS)
endif
diff --git a/winsup/utils/kill.cc b/winsup/utils/kill.cc
index b0a2e1f65..c5b61c616 100644
--- a/winsup/utils/kill.cc
+++ b/winsup/utils/kill.cc
@@ -129,13 +129,17 @@ static void __stdcall
forcekill (int pid, int sig, int wait)
{
external_pinfo *p = (external_pinfo *) cygwin_internal (CW_GETPINFO_FULL, pid);
- if (!p)
- return;
- HANDLE h = OpenProcess (PROCESS_TERMINATE, FALSE, (DWORD) p->dwProcessId);
+ DWORD dwpid = p ? p->dwProcessId : (DWORD) pid;
+ HANDLE h = OpenProcess (PROCESS_TERMINATE, FALSE, (DWORD) dwpid);
if (!h)
+ {
+ fprintf (stderr, "couldn't open pid %u\n", (unsigned) dwpid);
return;
+ }
if (!wait || WaitForSingleObject (h, 200) != WAIT_OBJECT_0)
- TerminateProcess (h, sig << 8);
+ if (!TerminateProcess (h, sig << 8))
+ fprintf (stderr, "couldn't kill pid %u, %u\n", (unsigned) dwpid,
+ (unsigned) GetLastError ());
CloseHandle (h);
}