aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2003-06-06 00:27:50 +0000
committerChristopher Faylor <me@cgf.cx>2003-06-06 00:27:50 +0000
commita98a3f687baf9f6aac1ef45d4798446028536996 (patch)
tree9db72ed4dbe34249aa0884e24f54acfe0b0e436c
parente4be0da637723b663fbffd37b6fb7a950cd21cf9 (diff)
downloadnewlib-a98a3f687baf9f6aac1ef45d4798446028536996.zip
newlib-a98a3f687baf9f6aac1ef45d4798446028536996.tar.gz
newlib-a98a3f687baf9f6aac1ef45d4798446028536996.tar.bz2
merge from trunk
-rw-r--r--winsup/cygwin/ChangeLog141
-rwxr-xr-xwinsup/cygwin/configure2
-rw-r--r--winsup/cygwin/configure.in2
-rw-r--r--winsup/cygwin/cygheap.cc2
-rw-r--r--winsup/cygwin/cygthread.cc15
-rw-r--r--winsup/cygwin/cygthread.h2
-rw-r--r--winsup/cygwin/exceptions.cc5
-rw-r--r--winsup/cygwin/fhandler.cc2
-rw-r--r--winsup/cygwin/fhandler_disk_file.cc64
-rw-r--r--winsup/cygwin/fhandler_socket.cc149
-rw-r--r--winsup/cygwin/include/sys/mount.h3
-rw-r--r--winsup/cygwin/include/sys/param.h7
-rwxr-xr-xwinsup/cygwin/mkvers.sh2
-rw-r--r--winsup/cygwin/net.cc65
-rw-r--r--winsup/cygwin/path.cc97
-rw-r--r--winsup/cygwin/shared.cc2
-rw-r--r--winsup/cygwin/shared_info.h2
-rw-r--r--winsup/cygwin/spawn.cc4
18 files changed, 345 insertions, 221 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 76f1fc3..fdce9f4 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,144 @@
+2003-06-05 Christopher Faylor <cgf@redhat.com>
+
+ * cygthread.cc (cygthread::terminate_thread): Change system_printf to
+ debug_printf.
+
+2003-06-04 Christopher Faylor <cgf@redhat.com>
+
+ * shared.cc (shared_info::heap_chunk_size): Be really defensive about
+ making sure that heap_chunk is set.
+
+2003-06-04 Christopher Faylor <cgf@redhat.com>
+
+ * path.cc (conv_path_list): Use correct value when calculating length
+ to avoid a potential SEGV.
+
+2003-06-03 Pierre Humblet <pierre.humblet@ieee.org>
+
+ * fhandler_disk_file.cc (fhandler_disk_file::fstat): Mark the pc
+ as non-executable if the file cannot be opened for read. Retry query
+ open only if errno is EACCES. Never change the mode, even if it is 000
+ when query open() fails.
+
+2003-06-03 Christopher Faylor <cgf@redhat.com>
+
+ * configure.in: Allow any i?86 variant.
+ * configure: Regenerate.
+
+2003-06-03 Corinna Vinschen <corinna@vinschen.de>
+ Thomas Pfaff <tpfaff@gmx.net>
+
+ * fhandler_socket.cc (connect_thread): Remove.
+ (accept_thread): Remove.
+ (fhandler_socket::connect): Remove all special blocking handling.
+ (fhandler_socket::accept): Ditto.
+ * net.cc (cygwin_connect): Make blocking sockets temporarily
+ non-blocking and call cygwin_select on them to be interruptible.
+ (cygwin_accept): Ditto.
+
+2003-06-02 Christopher Faylor <cgf@redhat.com>
+
+ * spawn.cc (spawn_guts): Don't hang around if the parent doesn't exist.
+
+2003-06-02 Christopher Faylor <cgf@redhat.com>
+
+ * cygthread.h (cygthread::terminate_thread): Mark private.
+ * cygthread.cc (cygthread::terminate_thread): Deallocate free_range
+ thread stuff.
+
+2003-06-02 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_socket.cc (fhandler_socket::accept): Rename `signalled'
+ to `interrupted' as used in fhandler_socket::connect.
+
+2003-06-02 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_socket.cc (fhandler_socket::connect): Simplify previous
+ patch.
+ (fhandler_socket::accept): Ditto.
+
+2003-06-02 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_socket.cc: Include cygthread.h.
+ (class sock_event): Remove.
+ (thread_connect): New function.
+ (thread_accept): Ditto.
+ (fhandler_socket::connect): Use cygthread instead of socket event
+ handling for blocking sockets.
+ (fhandler_socket::accept): Ditto.
+
+2003-06-02 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler.cc (fhandler_base::write): Correct minor printf formatting
+ style glitch.
+
+2003-06-01 Pierre Humblet <pierre.humblet@ieee.org>
+
+ * fhandler_disk_file.cc (fhandler_disk_file::fstat_by_name): Assume
+ an existing directory is a root if FindFirstFile fails.
+
+2003-05-30 Christopher Faylor <cgf@redhat.com>
+
+ * path.cc (mount_info::conv_to_win32_path): gcc warning about chroot_ok
+ was actually valid. Fix it.
+
+2003-05-30 Christopher Faylor <cgf@redhat.com>
+
+ * cygheap.cc (init_cheap): Temporarily remove inline that newer gcc's
+ have problems with.
+
+ * path.cc (path_conv::check): Rework has_acls logic slightly. Uncouple
+ exec tests away from filesystem tests.
+
+2003-05-30 Corinna Vinschen <corinna@vinschen.de>
+
+ * include/sys/param.h: Add DEV_BSIZE.
+
+2003-05-29 Pierre Humblet <pierre.humblet@ieee.org>
+ Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_socket.cc (fhandler_socket::dup): Rearrange. Fix
+ conditional.
+
+2003-05-28 Christopher Faylor <cgf@redhat.com>
+
+ * mkvers.sh: Avoid "-dontuse" tags.
+
+ * path.cc (path_conv::check): Set exec state based on known situations.
+
+ * path.cc (mount_item::fnmunge): New function.
+ (mount_item::build_win32): New function.
+ (mount_info::conv_to_win32_path): Use build_win32 to build windows
+ path.
+ * path.h (mount_item::fnmunge): Declare new function.
+ (mount_item::build_win32): Ditto.
+ * sys/mount.h (MOUNT_ENC): Define.
+
+2003-05-28 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_socket.cc (fhandler_socket::dup): If running impersonated,
+ revert to original account before calling fixup_before_fork_exec
+ and impersonate again afterwards. Change comment accordingly.
+ Clean up error handling and debug output.
+
+2003-05-27 Thomas Pfaff <tpfaff@gmx.net>
+
+ * fhandler_socket.cc (sock_event::~sock_event): New method.
+ (sock_event::load): Change to void. Check if winsock2 is available.
+ (socke_event::wait): Return 0 if interruptible mode is not available.
+ (fhandler_socket::connect): Remove checks for winsock2 availability.
+ (fhandler_socket::accept): Ditto.
+
+2003-05-27 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_socket.cc (fhandler_socket::dup): First try duplicating
+ using WSADuplicateSocket/WSASocket, if that fails, try DuplicateHandle.
+
+2003-05-27 Bill C. Riemers <cygwin@docbill.net>
+
+ * fhandler_disk_file.cc (fhandler_disk_file::fstat_helper): Filter
+ permissions throug umask on FAT or if ntsec is off.
+
2003-05-26 Pierre Humblet <pierre.humblet@ieee.org>
* syscalls.cc (statfs): Call GetDiskFreeSpaceEx before GetDiskFreeSpace.
diff --git a/winsup/cygwin/configure b/winsup/cygwin/configure
index 4114757..f5c8a7d 100755
--- a/winsup/cygwin/configure
+++ b/winsup/cygwin/configure
@@ -1965,7 +1965,7 @@ esac
case "$target_cpu" in
- i386|i486|i586|i686) DLL_ENTRY="_dll_entry@12"
+ i?86) DLL_ENTRY="_dll_entry@12"
DEF_DLL_ENTRY="dll_entry@12"
ALLOCA="_alloca"
CONFIG_DIR="i386" ;;
diff --git a/winsup/cygwin/configure.in b/winsup/cygwin/configure.in
index de3a571..48ffe7d 100644
--- a/winsup/cygwin/configure.in
+++ b/winsup/cygwin/configure.in
@@ -198,7 +198,7 @@ dnl fi
dnl fi
case "$target_cpu" in
- i386|i486|i586|i686) DLL_ENTRY="_dll_entry@12"
+ i?86) DLL_ENTRY="_dll_entry@12"
DEF_DLL_ENTRY="dll_entry@12"
ALLOCA="_alloca"
CONFIG_DIR="i386" ;;
diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc
index cfc2405..1d3e4fb 100644
--- a/winsup/cygwin/cygheap.cc
+++ b/winsup/cygwin/cygheap.cc
@@ -47,7 +47,7 @@ extern "C" {
static void __stdcall _cfree (void *ptr) __attribute__((regparm(1)));
}
-inline static void
+static void
init_cheap ()
{
cygheap = (init_cygheap *) VirtualAlloc ((void *) &_cygheap_start, CYGHEAPSIZE, MEM_RESERVE, PAGE_NOACCESS);
diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc
index e3c177e..2d45f29 100644
--- a/winsup/cygwin/cygthread.cc
+++ b/winsup/cygwin/cygthread.cc
@@ -255,13 +255,18 @@ cygthread::terminate_thread ()
if (!m.RegionSize)
system_printf ("m.RegionSize 0? stack_ptr %p", stack_ptr);
else if (!VirtualFree (m.AllocationBase, 0, MEM_RELEASE))
- system_printf ("VirtualFree of allocation base %p<%p> failed, %E",
+ debug_printf ("VirtualFree of allocation base %p<%p> failed, %E",
stack_ptr, m.AllocationBase);
- h = NULL;
- __name = NULL;
- stack_ptr = NULL;
- (void) InterlockedExchange (&inuse, 0); /* No longer in use */
+ if (is_freerange)
+ free (this);
+ else
+ {
+ h = NULL;
+ __name = NULL;
+ stack_ptr = NULL;
+ (void) InterlockedExchange (&inuse, 0); /* No longer in use */
+ }
}
/* Detach the cygthread from the current thread. Note that the
diff --git a/winsup/cygwin/cygthread.h b/winsup/cygwin/cygthread.h
index 7af3f31..57b50e2 100644
--- a/winsup/cygwin/cygthread.h
+++ b/winsup/cygwin/cygthread.h
@@ -22,6 +22,7 @@ class cygthread
static bool exiting;
static DWORD WINAPI stub (VOID *);
static DWORD WINAPI simplestub (VOID *);
+ void terminate_thread ();
public:
static const char * name (DWORD = 0);
cygthread (LPTHREAD_START_ROUTINE, LPVOID, const char *);
@@ -33,7 +34,6 @@ class cygthread
void * operator new (size_t);
static cygthread *freerange ();
void exit_thread ();
- void terminate_thread ();
static void terminate ();
bool SetThreadPriority (int nPriority) {return ::SetThreadPriority (h, nPriority);}
void zap_h ()
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 482745e..4a38a8e 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -608,9 +608,8 @@ sig_handle_tty_stop (int sig)
myself->stopsig = sig;
/* See if we have a living parent. If so, send it a special signal.
- * It will figure out exactly which pid has stopped by scanning
- * its list of subprocesses.
- */
+ It will figure out exactly which pid has stopped by scanning
+ its list of subprocesses. */
if (my_parent_is_alive ())
{
pinfo parent (myself->ppid);
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index fb391f4..ab5e4b8 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -609,7 +609,7 @@ fhandler_base::write (const void *ptr, size_t len)
HANDLE h = get_output_handle ();
BOOL r = DeviceIoControl (h, FSCTL_SET_SPARSE, NULL, 0, NULL,
0, &dw, NULL);
- syscall_printf ("%d = DeviceIoControl(0x%x, FSCTL_SET_SPARSE, "
+ syscall_printf ("%d = DeviceIoControl(%p, FSCTL_SET_SPARSE, "
"NULL, 0, NULL, 0, &dw, NULL)", r, h);
}
else if (wincap.has_lseek_bug ())
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc
index d28c4bb..7e6d033 100644
--- a/winsup/cygwin/fhandler_disk_file.cc
+++ b/winsup/cygwin/fhandler_disk_file.cc
@@ -114,18 +114,7 @@ fhandler_base::fstat_by_name (struct __stat64 *buf)
set_errno (ENOENT);
res = -1;
}
- else if (pc.isdir () && strlen (pc) <= strlen (pc.root_dir ()))
- {
- FILETIME ft = {};
- res = fstat_helper (buf, ft, ft, ft, 0, 0);
- }
- else if ((handle = FindFirstFile (pc, &local)) == INVALID_HANDLE_VALUE)
- {
- debug_printf ("FindFirstFile failed for '%s', %E", (char *) pc);
- __seterrno ();
- res = -1;
- }
- else
+ else if ((handle = FindFirstFile (pc, &local)) != INVALID_HANDLE_VALUE)
{
FindClose (handle);
res = fstat_helper (buf,
@@ -135,6 +124,17 @@ fhandler_base::fstat_by_name (struct __stat64 *buf)
local.nFileSizeHigh,
local.nFileSizeLow);
}
+ else if (pc.isdir ())
+ {
+ FILETIME ft = {};
+ res = fstat_helper (buf, ft, ft, ft, 0, 0);
+ }
+ else
+ {
+ debug_printf ("FindFirstFile failed for '%s', %E", (char *) pc);
+ __seterrno ();
+ res = -1;
+ }
return res;
}
@@ -143,8 +143,6 @@ fhandler_base::fstat_fs (struct __stat64 *buf)
{
int res = -1;
int oret;
- __uid32_t uid;
- __gid32_t gid;
int open_flags = O_RDONLY | O_BINARY | O_DIROPEN;
bool query_open_already;
@@ -165,27 +163,15 @@ fhandler_base::fstat_fs (struct __stat64 *buf)
if (query_open_already && strncasematch (pc.volname (), "FAT", 3)
&& !strpbrk (get_win32_name (), "?*|<>"))
oret = 0;
- else if (!(oret = open_fs (open_flags, 0)))
+ else if (!(oret = open_fs (open_flags, 0))
+ && !query_open_already
+ && get_errno () == EACCES)
{
- mode_t ntsec_atts = 0;
/* If we couldn't open the file, try a "query open" with no permissions.
This will allow us to determine *some* things about the file, at least. */
+ pc.set_exec (0);
set_query_open (true);
- if (!query_open_already && (oret = open (open_flags, 0)))
- /* ok */;
- else if (allow_ntsec && pc.has_acls () && get_errno () == EACCES
- && !get_file_attribute (TRUE, get_win32_name (), &ntsec_atts, &uid, &gid)
- && !ntsec_atts && uid == myself->uid && gid == myself->gid)
- {
- /* Check a special case here. If ntsec is ON it happens
- that a process creates a file using mode 000 to disallow
- other processes access. In contrast to UNIX, this results
- in a failing open call in the same process. Check that
- case. */
- set_file_attribute (TRUE, get_win32_name (), 0400);
- oret = open (open_flags, 0);
- set_file_attribute (TRUE, get_win32_name (), ntsec_atts);
- }
+ oret = open_fs (open_flags, 0);
}
if (!oret || get_nohandle ())
@@ -222,8 +208,12 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
to_timestruc_t (&ftLastWriteTime, &buf->st_mtim);
to_timestruc_t (&ftCreationTime, &buf->st_ctim);
buf->st_dev = pc.volser ();
- buf->st_size = ((_off64_t )nFileSizeHigh << 32) + nFileSizeLow;
- /* Unfortunately the count of 2 confuses `find (1)' command. So
+ buf->st_size = ((_off64_t) nFileSizeHigh << 32) + nFileSizeLow;
+ /* The number of links to a directory includes the
+ number of subdirectories in the directory, since all
+ those subdirectories point to it.
+ This is too slow on remote drives, so we do without it.
+ Setting the count to 2 confuses `find (1)' command. So
let's try it with `1' as link count. */
if (pc.isdir () && !pc.isremote () && nNumberOfLinks == 1)
buf->st_nlink = num_entries (pc.get_win32 ());
@@ -342,13 +332,11 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
if (pc.exec_state () == is_executable)
buf->st_mode |= STD_XBITS;
+
+ /* This fakes the permissions of all files to match the current umask. */
+ buf->st_mode &= ~(cygheap->umask);
}
- /* The number of links to a directory includes the
- number of subdirectories in the directory, since all
- those subdirectories point to it.
- This is too slow on remote drives, so we do without it and
- set the number of links to 2. */
done:
syscall_printf ("0 = fstat (, %p) st_atime=%x st_size=%D, st_mode=%p, st_ino=%d, sizeof=%d",
buf, buf->st_atime, buf->st_size, buf->st_mode,
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index 5a16073..6a163b6 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -32,6 +32,8 @@
#include "cygheap.h"
#include "sigproc.h"
#include "wsock_event.h"
+#include "cygthread.h"
+#include "select.h"
#include <unistd.h>
extern bool fdsock (cygheap_fdmanip& fd, const device *, SOCKET soc);
@@ -117,73 +119,6 @@ get_inet_addr (const struct sockaddr *in, int inlen,
}
}
-class sock_event
-{
- WSAEVENT ev[2];
- SOCKET evt_sock;
- int evt_type_bit;
-
-public:
- sock_event ()
- {
- ev[0] = WSA_INVALID_EVENT;
- ev[1] = signal_arrived;
- }
- bool load (SOCKET sock, int type_bit)
- {
- if ((ev[0] = WSACreateEvent ()) == WSA_INVALID_EVENT)
- return false;
- evt_sock = sock;
- evt_type_bit = type_bit;
- if (WSAEventSelect (evt_sock, ev[0], 1 << evt_type_bit))
- {
- WSACloseEvent (ev[0]);
- ev[0] = WSA_INVALID_EVENT;
- return false;
- }
- return true;
- }
- int wait ()
- {
- WSANETWORKEVENTS sock_event;
- int wait_result = WSAWaitForMultipleEvents (2, ev, FALSE, WSA_INFINITE,
- FALSE);
- if (wait_result == WSA_WAIT_EVENT_0)
- WSAEnumNetworkEvents (evt_sock, ev[0], &sock_event);
-
- /* Cleanup, Revert to blocking. */
- WSAEventSelect (evt_sock, ev[0], 0);
- WSACloseEvent (ev[0]);
- unsigned long nonblocking = 0;
- ioctlsocket (evt_sock, FIONBIO, &nonblocking);
-
- switch (wait_result)
- {
- case WSA_WAIT_EVENT_0:
- if ((sock_event.lNetworkEvents & (1 << evt_type_bit))
- && sock_event.iErrorCode[evt_type_bit])
- {
- WSASetLastError (sock_event.iErrorCode[evt_type_bit]);
- set_winsock_errno ();
- return -1;
- }
- break;
-
- case WSA_WAIT_EVENT_0 + 1:
- debug_printf ("signal received");
- set_errno (EINTR);
- return 1;
-
- case WSA_WAIT_FAILED:
- default:
- WSASetLastError (WSAEFAULT);
- set_winsock_errno ();
- return -1;
- }
- return 0;
- }
-};
-
/**********************************************************************/
/* fhandler_socket */
@@ -390,38 +325,47 @@ fhandler_socket::dup (fhandler_base *child)
debug_printf ("here");
fhandler_socket *fhs = (fhandler_socket *) child;
fhs->addr_family = addr_family;
- fhs->set_io_handle (get_io_handle ());
if (get_addr_family () == AF_LOCAL)
fhs->set_sun_path (get_sun_path ());
fhs->set_socket_type (get_socket_type ());
- /* Using WinSock2 methods for dup'ing sockets seem to collide
- with user context switches under... some... conditions. So we
- drop this for NT systems at all and return to the good ol'
- DuplicateHandle way of life. This worked fine all the time on
- NT anyway and it's even a bit faster. */
- if (!wincap.has_security ())
+ if (winsock2_active)
{
+ /* Since WSADuplicateSocket() fails on NT systems when the process
+ is currently impersonating a non-privileged account, we revert
+ to the original account before calling WSADuplicateSocket() and
+ switch back afterwards as it's also in fork().
+ If WSADuplicateSocket() still fails for some reason, we fall back
+ to DuplicateHandle(). */
+ WSASetLastError (0);
+ if (cygheap->user.issetuid ())
+ RevertToSelf ();
+ fhs->set_io_handle (get_io_handle ());
fhs->fixup_before_fork_exec (GetCurrentProcessId ());
- if (winsock2_active)
+ if (cygheap->user.issetuid ())
+ ImpersonateLoggedOnUser (cygheap->user.token);
+ if (!WSAGetLastError ())
{
fhs->fixup_after_fork (hMainProc);
- return get_io_handle () == (HANDLE) INVALID_SOCKET;
+ if (fhs->get_io_handle() != (HANDLE) INVALID_SOCKET)
+ return 0;
}
+ debug_printf ("WSADuplicateSocket failed, trying DuplicateHandle");
}
+
/* We don't call fhandler_base::dup here since that requires to
have winsock called from fhandler_base and it creates only
inheritable sockets which is wrong for winsock2. */
+
HANDLE nh;
if (!DuplicateHandle (hMainProc, get_io_handle (), hMainProc, &nh, 0,
!winsock2_active, DUPLICATE_SAME_ACCESS))
{
- system_printf ("dup(%s) failed, handle %x, %E",
- get_name (), get_io_handle ());
+ system_printf ("!DuplicateHandle(%x) failed, %E", get_io_handle ());
__seterrno ();
return -1;
}
- child->set_io_handle (nh);
+ fhs->set_io_handle (nh);
return 0;
}
@@ -543,8 +487,6 @@ out:
int
fhandler_socket::connect (const struct sockaddr *name, int namelen)
{
- sock_event evt;
- BOOL interrupted = FALSE;
int res = -1;
BOOL secret_check_failed = FALSE;
BOOL in_progress = FALSE;
@@ -554,31 +496,8 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen)
if (!get_inet_addr (name, namelen, &sin, &namelen, secret))
return -1;
- if (winsock2_active && !is_nonblocking () && !is_connect_pending ())
- if (!evt.load (get_socket (), FD_CONNECT_BIT))
- {
- set_winsock_errno ();
- return -1;
- }
-
res = ::connect (get_socket (), (sockaddr *) &sin, namelen);
- if (winsock2_active && res && !is_nonblocking () && !is_connect_pending () &&
- WSAGetLastError () == WSAEWOULDBLOCK)
- switch (evt.wait ())
- {
- case 1: /* Signal */
- WSASetLastError (WSAEINPROGRESS);
- interrupted = TRUE;
- break;
- case 0:
- res = 0;
- break;
- default:
- res = -1;
- break;
- }
-
if (res)
{
/* Special handling for connect to return the correct error code
@@ -632,9 +551,6 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen)
else
set_connect_state (CONNECTED);
- if (interrupted)
- set_errno (EINTR);
-
return res;
}
@@ -674,25 +590,6 @@ fhandler_socket::accept (struct sockaddr *peer, int *len)
if (len && ((unsigned) *len < sizeof (struct sockaddr_in)))
*len = sizeof (struct sockaddr_in);
- if (winsock2_active && !is_nonblocking ())
- {
- sock_event evt;
- if (!evt.load (get_socket (), FD_ACCEPT_BIT))
- {
- set_winsock_errno ();
- return -1;
- }
- switch (evt.wait ())
- {
- case 1: /* Signal */
- return -1;
- case 0:
- break;
- case -1:
- return -1;
- }
- }
-
res = ::accept (get_socket (), peer, len);
if ((SOCKET) res == INVALID_SOCKET && WSAGetLastError () == WSAEWOULDBLOCK)
diff --git a/winsup/cygwin/include/sys/mount.h b/winsup/cygwin/include/sys/mount.h
index 5741374..5915ddc 100644
--- a/winsup/cygwin/include/sys/mount.h
+++ b/winsup/cygwin/include/sys/mount.h
@@ -28,7 +28,8 @@ enum
not yet implemented */
MOUNT_NOTEXEC = 0x100, /* don't check files for executable magic */
MOUNT_DEVFS = 0x200, /* /device "filesystem" */
- MOUNT_PROC = 0x400 /* /proc "filesystem" */
+ MOUNT_PROC = 0x400, /* /proc "filesystem" */
+ MOUNT_ENC = 0x800 /* encode special characters */
};
int mount (const char *, const char *, unsigned __flags);
diff --git a/winsup/cygwin/include/sys/param.h b/winsup/cygwin/include/sys/param.h
index 09ef74e..5469cc7 100644
--- a/winsup/cygwin/include/sys/param.h
+++ b/winsup/cygwin/include/sys/param.h
@@ -1,6 +1,6 @@
/* sys/param.h
- Copyright 2001 Red Hat, Inc.
+ Copyright 2001, 2003 Red Hat, Inc.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
@@ -33,6 +33,11 @@
The Posix version is PATH_MAX. */
#define MAXPATHLEN (260 - 1 /*NUL*/)
+/* This is the number of bytes per block given in the st_blocks stat member.
+ It should be in sync with S_BLKSIZE in sys/stat.h. S_BLKSIZE is the
+ BSD variant of this constant. */
+#define DEV_BSIZE 1024
+
/* Some autoconf'd packages check for endianness. When cross-building we
can't run programs on the target. Fortunately, autoconf supports the
definition of byte order in sys/param.h (that's us!).
diff --git a/winsup/cygwin/mkvers.sh b/winsup/cygwin/mkvers.sh
index d14deb1..85d016b 100755
--- a/winsup/cygwin/mkvers.sh
+++ b/winsup/cygwin/mkvers.sh
@@ -84,7 +84,7 @@ fn=`basename $incfile`
# if it exists, will contain the name of the sticky tag associated with
# the current build. Save that for output later.
#
-cvs_tag="`sed 's%^.\(.*\)%\1%' $dir/CVS/Tag 2>/dev/null`"
+cvs_tag="`sed -e '/dontuse/d' -e 's%^.\(.*\)%\1%' $dir/CVS/Tag 2>/dev/null`"
wv_cvs_tag="$cvs_tag"
[ -n "$cvs_tag" ] && cvs_tag=" CVS tag"'
diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc
index c4ade44..fc4f548 100644
--- a/winsup/cygwin/net.cc
+++ b/winsup/cygwin/net.cc
@@ -769,7 +769,56 @@ cygwin_connect (int fd, const struct sockaddr *name, int namelen)
if (__check_invalid_read_ptr_errno (name, namelen) || !fh)
res = -1;
else
- res = fh->connect (name, namelen);
+ {
+ bool was_blocking = false;
+ if (!fh->is_nonblocking ())
+ {
+ int nonblocking = 1;
+ fh->ioctl (FIONBIO, &nonblocking);
+ was_blocking = true;
+ }
+ res = fh->connect (name, namelen);
+ if (was_blocking)
+ {
+ if (res == -1 && get_errno () == EINPROGRESS)
+ {
+ size_t fds_size = howmany (fd + 1, NFDBITS) * sizeof (fd_mask);
+ fd_set *write_fds = (fd_set *) alloca (fds_size);
+ fd_set *except_fds = (fd_set *) alloca (fds_size);
+ memset (write_fds, 0, fds_size);
+ memset (except_fds, 0, fds_size);
+ FD_SET (fd, write_fds);
+ FD_SET (fd, except_fds);
+ res = cygwin_select (fd + 1, NULL, write_fds, except_fds, NULL);
+ if (res > 0 && FD_ISSET (fd, except_fds))
+ {
+ res = -1;
+ for (;;)
+ {
+ int err;
+ int len = sizeof err;
+ cygwin_getsockopt (fd, SOL_SOCKET, SO_ERROR,
+ (void *) &err, &len);
+ if (err)
+ {
+ set_errno (err);
+ break;
+ }
+ low_priority_sleep (0);
+ }
+ }
+ else if (res > 0)
+ res = 0;
+ else
+ {
+ WSASetLastError (WSAEINPROGRESS);
+ set_winsock_errno ();
+ }
+ }
+ int nonblocking = 0;
+ fh->ioctl (FIONBIO, &nonblocking);
+ }
+ }
syscall_printf ("%d = connect (%d, %p, %d)", res, fd, name, namelen);
@@ -1047,7 +1096,19 @@ cygwin_accept (int fd, struct sockaddr *peer, int *len)
|| !fh)
res = -1;
else
- res = fh->accept (peer, len);
+ {
+ if (!fh->is_nonblocking ())
+ {
+ size_t fds_size = howmany (fd + 1, NFDBITS) * sizeof (fd_mask);
+ fd_set *read_fds = (fd_set *) alloca (fds_size);
+ memset (read_fds, 0, fds_size);
+ FD_SET (fd, read_fds);
+ res = cygwin_select (fd + 1, read_fds, NULL, NULL, NULL);
+ if (res == -1)
+ return -1;
+ }
+ res = fh->accept (peer, len);
+ }
syscall_printf ("%d = accept (%d, %p, %p)", res, fd, peer, len);
return res;
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index df30ce9..60856f2 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -800,22 +800,34 @@ out:
if (!fs.update (path))
{
fs.root_dir ()[0] = '\0';
- set_has_acls (false);
- set_has_buggy_open (false);
+ set_has_acls (false); // already implied but...
+ set_has_buggy_open (false); // ditto
}
else
{
set_isdisk ();
debug_printf ("root_dir(%s), this->path(%s), set_has_acls(%d)",
fs.root_dir (), this->path, fs.flags () & FS_PERSISTENT_ACLS);
- if (!allow_smbntsec && fs.is_remote_drive ())
+ if (!(fs.flags () & FS_PERSISTENT_ACLS) || (!allow_smbntsec && fs.is_remote_drive ()))
set_has_acls (false);
else
- set_has_acls (fs.flags () & FS_PERSISTENT_ACLS);
+ {
+ set_has_acls (true);
+ if (allow_ntsec && wincap.has_security ())
+ set_exec (0); /* We really don't know if this is executable or not here
+ but set it to not executable since it will be figured out
+ later by anything which cares about this. */
+ }
/* Known file systems with buggy open calls. Further explanation
in fhandler.cc (fhandler_disk_file::open). */
set_has_buggy_open (strcmp (fs.name (), "SUNWNFS") == 0);
}
+ if (exec_state () != dont_know_if_executable)
+ /* ok */;
+ else if (isdir ())
+ set_exec (1);
+ else if (issymlink () || issocket ())
+ set_exec (0);
}
#if 0
@@ -1139,6 +1151,41 @@ set_flags (unsigned *flags, unsigned val)
}
}
+void
+mount_item::fnmunge (char *dst, const char *src)
+{
+ strcpy (dst, src);
+ backslashify (dst, dst, 0);
+}
+
+void
+mount_item::build_win32 (char *dst, const char *src, unsigned *outflags, unsigned chroot_pathlen)
+{
+ int n;
+ const char *real_native_path;
+ int real_posix_pathlen;
+ set_flags (outflags, (unsigned) flags);
+ if (!cygheap->root.exists () || posix_pathlen != 1 || posix_path[0] != '/')
+ {
+ n = native_pathlen;
+ real_native_path = native_path;
+ real_posix_pathlen = chroot_pathlen ?: posix_pathlen;
+ }
+ else
+ {
+ n = cygheap->root.native_length ();
+ real_native_path = cygheap->root.native_path ();
+ real_posix_pathlen = posix_pathlen;
+ }
+ memcpy (dst, real_native_path, n + 1);
+ const char *p = src + real_posix_pathlen;
+ if (*p == '/')
+ /* nothing */;
+ else if ((isdrive (dst) && !dst[2]) || *p)
+ dst[n++] = '\\';
+ fnmunge (dst + n, p);
+}
+
/* conv_to_win32_path: Ensure src_path is a pure Win32 path and store
the result in win32_path.
@@ -1156,6 +1203,7 @@ int
mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev,
unsigned *flags, bool no_normalize)
{
+ bool chroot_ok = !cygheap->root.exists ();
while (sys_mount_table_counter < cygwin_shared->sys_mount_table_counter)
{
init ();
@@ -1164,7 +1212,6 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev,
int src_path_len = strlen (src_path);
MALLOC_CHECK;
unsigned dummy_flags;
- int chroot_ok = !cygheap->root.exists ();
dev.devn = FH_FS;
@@ -1272,8 +1319,8 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev,
return ENOENT;
}
- int chrooted_path_len;
- chrooted_path_len = 0;
+ int chroot_pathlen;
+ chroot_pathlen = 0;
/* Check the mount table for prefix matches. */
for (i = 0; i < nmounts; i++)
{
@@ -1290,11 +1337,11 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev,
else if (cygheap->root.posix_ok (mi->posix_path))
{
path = cygheap->root.unchroot (mi->posix_path);
- chrooted_path_len = len = strlen (path);
+ chroot_pathlen = len = strlen (path);
}
else
{
- chrooted_path_len = 0;
+ chroot_pathlen = 0;
continue;
}
@@ -1306,36 +1353,12 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev,
{
backslashify (pathbuf, dst, 0); /* just convert */
set_flags (flags, PATH_BINARY);
+ chroot_ok = !cygheap->root.exists ();
}
else
{
- int n;
- const char *native_path;
- int posix_pathlen;
- if (chroot_ok || chrooted_path_len || mi->posix_pathlen != 1
- || mi->posix_path[0] != '/')
- {
- n = mi->native_pathlen;
- native_path = mi->native_path;
- posix_pathlen = chrooted_path_len ?: mi->posix_pathlen;
- chroot_ok = 1;
- }
- else
- {
- n = cygheap->root.native_length ();
- native_path = cygheap->root.native_path ();
- posix_pathlen = mi->posix_pathlen;
- chroot_ok = 1;
- }
- memcpy (dst, native_path, n + 1);
- const char *p = pathbuf + posix_pathlen;
- if (*p == '/')
- /* nothing */;
- else if ((isdrive (dst) && !dst[2]) || *p)
- dst[n++] = '\\';
- strcpy (dst + n, p);
- backslashify (dst, dst, 0);
- set_flags (flags, (unsigned) mi->flags);
+ mi->build_win32 (dst, pathbuf, flags, chroot_pathlen);
+ chroot_ok = true;
}
if (!isvirtual_dev (dev.devn))
@@ -3354,7 +3377,7 @@ conv_path_list_buf_size (const char *path_list, bool to_posix)
/* 100: slop */
size = strlen (path_list)
+ (num_elms * max_mount_path_len)
- + (nrel * strlen (to_posix ? pc.get_win32 () : pc.normalized_path))
+ + (nrel * strlen (to_posix ? pc.normalized_path : pc.get_win32 ()))
+ 100;
return size;
}
diff --git a/winsup/cygwin/shared.cc b/winsup/cygwin/shared.cc
index 7ab3d19..c91e380 100644
--- a/winsup/cygwin/shared.cc
+++ b/winsup/cygwin/shared.cc
@@ -254,6 +254,8 @@ shared_info::heap_chunk_size ()
heap_chunk = 4 * 1024 * 1024;
else
heap_chunk <<= 20;
+ if (!heap_chunk)
+ heap_chunk = 384 * 1024 * 1024;
debug_printf ("fixed heap size is %u", heap_chunk);
}
diff --git a/winsup/cygwin/shared_info.h b/winsup/cygwin/shared_info.h
index 4f137d6..7014c56 100644
--- a/winsup/cygwin/shared_info.h
+++ b/winsup/cygwin/shared_info.h
@@ -31,6 +31,8 @@ class mount_item
void init (const char *dev, const char *path, unsigned flags);
struct mntent *getmntent ();
+ void fnmunge (char *, const char *);
+ void build_win32 (char *, const char *, unsigned *, unsigned);
};
/* Warning: Decreasing this value will cause cygwin.dll to ignore existing
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index afa54d0..850536c 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -800,9 +800,9 @@ spawn_guts (const char * prog_arg, const char *const *argv,
reset_signal_arrived ();
continue;
case WAIT_OBJECT_0 + 2:
- if (myself->ppid_handle)
+ if (my_parent_is_alive ())
res |= EXIT_REPARENTING;
- if (!my_parent_is_alive ())
+ else if (!myself->ppid_handle)
{
nwait = 2;
sigproc_terminate ();