From ff6336e5ef38ce4806d05fffd68e4e3d3a8981e5 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Sun, 23 Feb 2003 06:00:21 +0000 Subject: merge from trunk --- winsup/cygwin/ChangeLog | 109 ++++++++++++++ winsup/cygwin/ChangeLog.branch | 5 + winsup/cygwin/autoload.cc | 3 + winsup/cygwin/cygmalloc.h | 28 ++++ winsup/cygwin/cygwin-gperf | 2 +- winsup/cygwin/cygwin.din | 1 + winsup/cygwin/devices.gperf | 2 +- winsup/cygwin/devices.h | 2 +- winsup/cygwin/fhandler.cc | 27 ++-- winsup/cygwin/fhandler_disk_file.cc | 71 ++++++--- winsup/cygwin/fhandler_socket.cc | 38 +++-- winsup/cygwin/fhandler_tty.cc | 10 +- winsup/cygwin/fhandler_virtual.cc | 23 +-- winsup/cygwin/grp.cc | 4 +- winsup/cygwin/include/cygwin/version.h | 2 +- winsup/cygwin/malloc_wrapper.cc | 18 +++ winsup/cygwin/net.cc | 256 +++++++++++++++++---------------- winsup/cygwin/path.cc | 4 + winsup/cygwin/path.h | 3 +- winsup/cygwin/sec_acl.cc | 63 -------- winsup/cygwin/security.cc | 51 +++++++ winsup/cygwin/security.h | 1 + winsup/cygwin/sigproc.cc | 11 +- winsup/cygwin/syscalls.cc | 32 ++++- winsup/cygwin/syslog.cc | 31 ++-- 25 files changed, 523 insertions(+), 274 deletions(-) create mode 100644 winsup/cygwin/cygmalloc.h diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index bdff5fa253e..6c313cde75b 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,112 @@ +2003-02-22 Christopher Faylor + + * cygmalloc.h: Remove MORECORE_CANNOT_TRIM. It's not true. + # cygwin.din: Export mallinfo. + # malloc_wrapper.cc (mallinfo): New function. + +2003-02-22 Pierre Humblet + + * syslog.cc (syslog): Do not print the Windows pid. Print the Cygwin + pid as an unsigned decimal. On Win95 print a timestamp and attempt to + lock the file up to four times in 3 ms. + +2003-02-21 Corinna Vinschen + + * fhandler_socket.cc (fhandler_socket::fhandler_socket): Fix compiler + warning. + (fhandler_socket::fstat): Simplify. Set st_uid/st_gid to effective + uid/gid of current process in case of open sockets. + +2003-02-21 Corinna Vinschen + + * dtable.cc (dtable::build_fhandler_from_name): Set some fhandler + data on sockets to evaluate AF_LOCAL sockets correctly. + (dtable::build_fhandler): Set unit number on sockets. + * fhandler.h (fhandler_socket): Add unit number. + (fhandler_socket::get_unit): New method. + * fhandler_socket.cc (fhandler_socket::fhandler_socket): Set unit + number. + (fhandler_socket::fstat): Reorganize to return more Linux-like + values. + * net.cc: include ctype.h. + (fdsock): Set unit number when building fhandler. + * path.cc (path_conv::check): Set device type to FH_SOCKET if file + is a AF_UNIX socket. + (get_devn): Evaluate unit for virtual socket devices. + (win32_device_name): Set windows path for sockets to unix_path with + just backslashes to keep the different names. + * syscalls.cc (fstat64): Don't override st_ino, st_dev and st_rdev + for sockets. + (stat_worker): Ditto. + +2003-02-21 Pierre Humblet + + * autoload.cc (AccessCheck): Add. + (DuplicateToken): Add. + * security.h (check_file_access): Declare. + * syscalls.cc (access): Convert path to Windows, check existence + and readonly attribute. Call check_file_access instead of acl_access. + * security.cc (check_file_access): Create. + * sec_acl (acl_access): Delete. + +2003-02-19 Christopher Faylor + + * fhandler.cc (fhandler_base::open): Move some filesystem specific + stuff. + (fhandler_disk_file::open): Accept some filesystem specific stuff. + * sigproc.cc (wait_for_sigthread): Become slightly more thread safe. + (sig_send): Don't assume that signal thread is ready. + +2003-02-20 Corinna Vinschen + + * wincap.h (wincap): Remove unnecessary definition of + supports_sparse_files. + * wincap.cc: Ditto. + +2003-02-20 Corinna Vinschen + + * fhandler_disk_file.cc (fhandler_disk_file::opendir): Check descriptor + created by cygheap_fdnew constructor. + * fhandler_virtual.cc (fhandler_virtual::opendir): Ditto. + * fhandler_socket.cc (fhandler_socket::accept): Ditto and move + creation of file descriptor behind blocking OS call. + * net.cc (cygwin_socket): Ditto. + (cygwin_rcmd): Ditto. + (cygwin_rresvport): Ditto. + (cygwin_rexec): Ditto. + (socketpair): Ditto. + +2003-02-20 Corinna Vinschen + + * autoload.cc (GetCompressedFileSize): Add. + * fhandler_disk_file.cc (fhandler_disk_file::fstat_helper): Compute + st_blocks value from GetCompressedFileSize() if available. + +2003-02-18 Vaclav Haisman + + * wincap.h (wincaps::supports_sparse_files): New flag. + (wincapc::supports_sparse_files): New method. + * wincap.cc (wincap_unknown): Define value for the new flag. + (wincap_95): Ditto. + (wincap_95osr2): Ditto. + (wincap_98): Ditto. + (wincap_98se): Ditto. + (wincap_me): Ditto. + (wincap_nt3): Ditto. + (wincap_nt4): Ditto. + (wincap_nt4sp4): Ditto. + (wincap_2000): Ditto. + (wincap_xp): Ditto. + * path.h (path_conv::fs_flags): New method. + * fhandler_disk_file.cc: Include winioctl.h for DeviceIoControl. + (fhandler_disk_file::open): Set newly created and truncated files as + sparse on platforms that support it. + +2003-02-17 Pierre Humblet + + * grp.cc (internal_getgroups): Handle properly tokens with + no groups. Fix bug introduced on 2003-02-04. + 2003-02-16 Christopher Faylor * cygwin.din: Export all appropriate newlibc libm functions. Sort. diff --git a/winsup/cygwin/ChangeLog.branch b/winsup/cygwin/ChangeLog.branch index 165327de7e3..c93eb39bad2 100644 --- a/winsup/cygwin/ChangeLog.branch +++ b/winsup/cygwin/ChangeLog.branch @@ -1,3 +1,8 @@ +2003-02-23 Christopher Faylor + + * fhandler.cc (fhandler_base::set_name): Explicitly set posix name. + (fhandler_base::dup): Ditto. + 2003-02-14 Christopher Faylor * path.h (path_conv::set_normalized_path): Declare. diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index 805055c82ce..b29c9d26908 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -307,6 +307,7 @@ wsock_init () LoadDLLprime (wsock32, wsock_init) LoadDLLprime (ws2_32, wsock_init) +LoadDLLfunc (AccessCheck, 32, advapi32) LoadDLLfunc (AddAccessAllowedAce, 16, advapi32) LoadDLLfunc (AddAccessDeniedAce, 16, advapi32) LoadDLLfunc (AddAce, 20, advapi32) @@ -318,6 +319,7 @@ LoadDLLfuncEx (CryptAcquireContextA, 20, advapi32, 1) LoadDLLfuncEx (CryptGenRandom, 12, advapi32, 1) LoadDLLfuncEx (CryptReleaseContext, 8, advapi32, 1) LoadDLLfunc (DeregisterEventSource, 4, advapi32) +LoadDLLfunc (DuplicateToken, 12, advapi32) LoadDLLfuncEx (DuplicateTokenEx, 24, advapi32, 1) LoadDLLfunc (EqualSid, 8, advapi32) LoadDLLfunc (GetAce, 12, advapi32) @@ -497,6 +499,7 @@ LoadDLLfunc (CoCreateInstance, 20, ole32) LoadDLLfuncEx (CancelIo, 4, kernel32, 1) LoadDLLfuncEx (CreateHardLinkA, 12, kernel32, 1) LoadDLLfuncEx (CreateToolhelp32Snapshot, 8, kernel32, 1) +LoadDLLfuncEx2 (GetCompressedFileSizeA, 8, kernel32, 1, 0xffffffff) LoadDLLfuncEx (GetConsoleWindow, 0, kernel32, 1) LoadDLLfuncEx2 (IsDebuggerPresent, 0, kernel32, 1, 1) LoadDLLfuncEx (Process32First, 8, kernel32, 1) diff --git a/winsup/cygwin/cygmalloc.h b/winsup/cygwin/cygmalloc.h new file mode 100644 index 00000000000..3d3a0acd5f1 --- /dev/null +++ b/winsup/cygwin/cygmalloc.h @@ -0,0 +1,28 @@ +/* cygmalloc.h: cygwin DLL malloc stuff + + Copyright 2002 Red Hat, Inc. + +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. */ + +extern "C" void dlfree (void *p) __attribute__ ((regparm (1))); +extern "C" void *dlmalloc (unsigned size) __attribute__ ((regparm (1))); +extern "C" void *dlrealloc (void *p, unsigned size) __attribute__ ((regparm (2))); +extern "C" void *dlcalloc (size_t nmemb, size_t size) __attribute__ ((regparm (2))); +extern "C" void *dlmemalign (size_t alignment, size_t bytes) __attribute__ ((regparm (2))); +extern "C" void *dlvalloc (size_t bytes) __attribute__ ((regparm (1))); +extern "C" size_t dlmalloc_usable_size (void *p) __attribute__ ((regparm (1))); +extern "C" int dlmalloc_trim (size_t) __attribute__ ((regparm (1))); +extern "C" int dlmallopt (int p, int v) __attribute__ ((regparm (2))); +extern "C" void dlmalloc_stats (); + +#ifndef __INSIDE_CYGWIN__ +# define USE_DL_PREFIX 1 +#else +# define __malloc_lock() mallock->acquire () +# define __malloc_unlock() mallock->release () +extern muto *mallock; +#endif diff --git a/winsup/cygwin/cygwin-gperf b/winsup/cygwin/cygwin-gperf index db9b054f1c2..0d490a6834b 100755 --- a/winsup/cygwin/cygwin-gperf +++ b/winsup/cygwin/cygwin-gperf @@ -63,7 +63,7 @@ EOF next; }; my ($str, $fh) = (split(/, /, $f))[0..1]; - if ($str !~ "/dev") { + if ($str !~ m!^"(?:/dev|:bad:)!) { $ix++; } else { my $what = lc(($fh =~ /FH_(.+)/o)[0]) . '_dev' ; diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din index dd201f55714..a2dd2667463 100644 --- a/winsup/cygwin/cygwin.din +++ b/winsup/cygwin/cygwin.din @@ -767,6 +767,7 @@ lseek _lseek = lseek lseek64 lstat64 +mallinfo malloc _malloc = malloc malloc_stats diff --git a/winsup/cygwin/devices.gperf b/winsup/cygwin/devices.gperf index ca66aadf0d6..8162db59ac6 100644 --- a/winsup/cygwin/devices.gperf +++ b/winsup/cygwin/devices.gperf @@ -161,7 +161,7 @@ void device::tty_to_real_device () { if (!real_tty_attached (myself)) - *this = *console_dev; + *this = myself->ctty < 0 ? *bad_dev : *console_dev; else { *this = *ttys_dev; diff --git a/winsup/cygwin/devices.h b/winsup/cygwin/devices.h index a3853f4c0ae..5f59c4ba5c7 100644 --- a/winsup/cygwin/devices.h +++ b/winsup/cygwin/devices.h @@ -109,7 +109,7 @@ enum fh_devices DEV_RAWDRIVE_MAJOR = 65, FH_RAWDRIVE= FHDEV (DEV_RAWDRIVE_MAJOR, 0), - FH_BAD = 0 + FH_BAD = FHDEV (0, 0) }; struct device diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index af489f13d9a..3a9173e1755 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -35,10 +35,10 @@ struct __cygwin_perfile *perfile_table; DWORD binmode; inline fhandler_base& -fhandler_base::operator =(fhandler_base &x) +fhandler_base::operator =(fhandler_base& x) { memcpy (this, &x, sizeof *this); - pc.set_normalized_path (pc.normalized_path); + pc.set_normalized_path (x.pc.normalized_path); rabuf = NULL; ralen = 0; raixget = 0; @@ -148,6 +148,7 @@ void fhandler_base::set_name (path_conv &in_pc) { memcpy (&pc, &in_pc, in_pc.size ()); + pc.set_normalized_path (in_pc.normalized_path); namehash = hash_path_name (0, get_win32_name ()); } @@ -423,10 +424,6 @@ fhandler_base::open (int flags, mode_t mode) x = CreateFile (get_win32_name (), access, shared, &sa, creation_distribution, file_attributes, 0); - syscall_printf ("%p = CreateFile (%s, %p, %p, %p, %p, %p, 0)", - x, get_win32_name (), access, shared, &sa, - creation_distribution, file_attributes); - if (x == INVALID_HANDLE_VALUE) { if (!wincap.can_open_directories () && pc.isdir ()) @@ -439,20 +436,16 @@ fhandler_base::open (int flags, mode_t mode) set_nohandle (true); } else if (GetLastError () == ERROR_INVALID_HANDLE) - set_errno (ENOENT); + set_errno (ENOENT); else - __seterrno (); + __seterrno (); if (!get_nohandle ()) - goto done; - } + goto done; + } - /* Attributes may be set only if a file is _really_ created. - This code is now only used for ntea here since the files - security attributes are set in CreateFile () now. */ - if (flags & O_CREAT && get_device () == FH_FS - && GetLastError () != ERROR_ALREADY_EXISTS - && !allow_ntsec && allow_ntea) - set_file_attribute (has_acls (), get_win32_name (), mode); + syscall_printf ("%p = CreateFile (%s, %p, %p, %p, %p, %p, 0)", + x, get_win32_name (), access, shared, &sa, + creation_distribution, file_attributes); set_io_handle (x); set_flags (flags, pc.binmode ()); diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index f7d76bfb8db..b47937cfbe5 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -26,6 +26,7 @@ details. */ #include "pinfo.h" #include #include +#include #define _COMPILING_NEWLIB #include @@ -265,7 +266,20 @@ fhandler_base::fstat_helper (struct __stat64 *buf, } buf->st_blksize = S_BLKSIZE; - buf->st_blocks = (buf->st_size + S_BLKSIZE - 1) / S_BLKSIZE; + + /* GetCompressedFileSize() gets autoloaded. It returns INVALID_FILE_SIZE + if it doesn't exist. Since that's also a valid return value on 64bit + capable file systems, we must additionally check for the win32 error. */ + nFileSizeLow = GetCompressedFileSizeA (pc, &nFileSizeHigh); + if (nFileSizeLow != INVALID_FILE_SIZE || GetLastError () == NO_ERROR) + /* On systems supporting compressed (and sparsed) files, + GetCompressedFileSize() returns the actual amount of + bytes allocated on disk. */ + buf->st_blocks = (((__off64_t)nFileSizeHigh << 32) + + nFileSizeLow + S_BLKSIZE - 1) / S_BLKSIZE; + else + /* Just compute no. of blocks from file size. */ + buf->st_blocks = (buf->st_size + S_BLKSIZE - 1) / S_BLKSIZE; buf->st_mode = 0; /* Using a side effect: get_file_attibutes checks for @@ -404,6 +418,26 @@ fhandler_base::open_fs (int flags, mode_t mode) return 0; } + /* Attributes may be set only if a file is _really_ created. + This code is now only used for ntea here since the files + security attributes are set in CreateFile () now. */ + if (flags & O_CREAT + && GetLastError () != ERROR_ALREADY_EXISTS + && !allow_ntsec && allow_ntea) + set_file_attribute (has_acls (), get_win32_name (), mode); + + /* Set newly created and truncated files as sparse files. */ + if ((pc.fs_flags () & FILE_SUPPORTS_SPARSE_FILES) + && (get_access () & GENERIC_WRITE) == GENERIC_WRITE) + { + DWORD dw; + HANDLE h = get_handle (); + BOOL r = DeviceIoControl (h , FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &dw, + NULL); + syscall_printf ("%d = DeviceIoControl(0x%x, FSCTL_SET_SPARSE, NULL, 0, " + "NULL, 0, &dw, NULL)", r, h); + } + set_symlink_p (pc.issymlink ()); set_execable_p (pc.exec_state ()); set_socket_p (pc.issocket ()); @@ -611,22 +645,25 @@ fhandler_disk_file::opendir () strcpy (dir->__d_dirname, get_win32_name ()); dir->__d_dirent->d_version = __DIRENT_VERSION; cygheap_fdnew fd; - fd = this; - fd->set_nohandle (true); - dir->__d_dirent->d_fd = fd; - dir->__d_u.__d_data.__fh = this; - /* FindFirstFile doesn't seem to like duplicate /'s. */ - len = strlen (dir->__d_dirname); - if (len == 0 || isdirsep (dir->__d_dirname[len - 1])) - strcat (dir->__d_dirname, "*"); - else - strcat (dir->__d_dirname, "\\*"); /**/ - dir->__d_cookie = __DIRENT_COOKIE; - dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE; - dir->__d_position = 0; - dir->__d_dirhash = get_namehash (); - - res = dir; + if (fd >= 0) + { + fd = this; + fd->set_nohandle (true); + dir->__d_dirent->d_fd = fd; + dir->__d_u.__d_data.__fh = this; + /* FindFirstFile doesn't seem to like duplicate /'s. */ + len = strlen (dir->__d_dirname); + if (len == 0 || isdirsep (dir->__d_dirname[len - 1])) + strcat (dir->__d_dirname, "*"); + else + strcat (dir->__d_dirname, "\\*"); /**/ + dir->__d_cookie = __DIRENT_COOKIE; + dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE; + dir->__d_position = 0; + dir->__d_dirhash = get_namehash (); + + res = dir; + } } syscall_printf ("%p = opendir (%s)", res, get_name ()); diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index a760c86a609..a01dbe5bf52 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -99,6 +99,14 @@ fhandler_socket::fhandler_socket () set_need_fork_fixup (); prot_info_ptr = (LPWSAPROTOCOL_INFOA) cmalloc (HEAP_BUF, sizeof (WSAPROTOCOL_INFOA)); +#if 0 + if (pc.is_fs_special ()) + { + fhandler_socket * fhs = (fhandler_socket *) fh; + fhs->set_addr_family (AF_LOCAL); + fhs->set_sun_path (posix_path); + } +#endif } fhandler_socket::~fhandler_socket () @@ -484,7 +492,6 @@ fhandler_socket::accept (struct sockaddr *peer, int *len) WSAEVENT ev[2] = { WSA_INVALID_EVENT, signal_arrived }; BOOL secret_check_failed = FALSE; BOOL in_progress = FALSE; - cygheap_fdnew res_fd; /* Allows NULL peer and len parameters. */ struct sockaddr_in peer_dummy; @@ -593,19 +600,28 @@ fhandler_socket::accept (struct sockaddr *peer, int *len) } } - if (res_fd < 0) - /* FIXME: what is correct errno? */; - else if ((SOCKET) res == (SOCKET) INVALID_SOCKET) + if ((SOCKET) res == (SOCKET) INVALID_SOCKET) set_winsock_errno (); else { - fhandler_socket* res_fh = fdsock (res_fd, get_name (), res); - if (get_addr_family () == AF_LOCAL) - res_fh->set_sun_path (get_sun_path ()); - res_fh->set_addr_family (get_addr_family ()); - res_fh->set_socket_type (get_socket_type ()); - res_fh->set_connect_state (CONNECTED); - res = res_fd; + cygheap_fdnew res_fd; + fhandler_socket* res_fh = NULL; + if (res_fd >= 0) + res_fh = fdsock (res_fd, get_name (), res); + if (res_fh) + { + if (get_addr_family () == AF_LOCAL) + res_fh->set_sun_path (get_sun_path ()); + res_fh->set_addr_family (get_addr_family ()); + res_fh->set_socket_type (get_socket_type ()); + res_fh->set_connect_state (CONNECTED); + res = res_fd; + } + else + { + closesocket (res); + res = -1; + } } done: diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 080d2346da1..395c4fc9719 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -579,17 +579,17 @@ fhandler_tty_slave::cygserver_attach_tty (LPHANDLE from_master_ptr, void fhandler_tty_slave::init (HANDLE, DWORD a, mode_t) { - int mode = 0; + int flags = 0; a &= GENERIC_READ | GENERIC_WRITE; if (a == GENERIC_READ) - mode = O_RDONLY; + flags = O_RDONLY; if (a == GENERIC_WRITE) - mode = O_WRONLY; + flags = O_WRONLY; if (a == (GENERIC_READ | GENERIC_WRITE)) - mode = O_RDWR; + flags = O_RDWR; - open (0, mode); + open (flags); } int diff --git a/winsup/cygwin/fhandler_virtual.cc b/winsup/cygwin/fhandler_virtual.cc index fe83f90e8a3..420544d6152 100644 --- a/winsup/cygwin/fhandler_virtual.cc +++ b/winsup/cygwin/fhandler_virtual.cc @@ -74,16 +74,19 @@ fhandler_virtual::opendir () strcpy (dir->__d_dirname, get_name ()); dir->__d_dirent->d_version = __DIRENT_VERSION; cygheap_fdnew fd; - fd = this; - fd->set_nohandle (true); - dir->__d_dirent->d_fd = fd; - dir->__d_u.__d_data.__fh = this; - dir->__d_cookie = __DIRENT_COOKIE; - dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE; - dir->__d_position = 0; - dir->__d_dirhash = get_namehash (); - - res = dir; + if (fd >= 0) + { + fd = this; + fd->set_nohandle (true); + dir->__d_dirent->d_fd = fd; + dir->__d_u.__d_data.__fh = this; + dir->__d_cookie = __DIRENT_COOKIE; + dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE; + dir->__d_position = 0; + dir->__d_dirhash = get_namehash (); + + res = dir; + } } syscall_printf ("%p = opendir (%s)", res, get_name ()); diff --git a/winsup/cygwin/grp.cc b/winsup/cygwin/grp.cc index 7a654ba15cf..39881e3dda5 100644 --- a/winsup/cygwin/grp.cc +++ b/winsup/cygwin/grp.cc @@ -267,7 +267,6 @@ internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygpsid * srchsid) for (DWORD pg = 0; pg < groups->GroupCount; ++pg) if ((cnt = (*srchsid == groups->Groups[pg].Sid))) break; - cnt = -1; } else for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx) @@ -293,8 +292,7 @@ internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygpsid * srchsid) debug_printf ("%d = GetTokenInformation(NULL) %E", size); if (hToken != cygheap->user.token) CloseHandle (hToken); - if (cnt) - return cnt; + return cnt; } gid = myself->gid; diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index 343a74d03a0..c3ee2bcabbd 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -154,7 +154,7 @@ details. */ 56: Make ntsec on by default. 57: Export setgroups. 58: Export memalign, valloc, malloc_trim, malloc_usable_size, mallopt, - malloc_stats + malloc_stats 59: getsid 60: MSG_NOSIGNAL 61: Export getc_unlocked, getchar_unlocked, putc_unlocked, diff --git a/winsup/cygwin/malloc_wrapper.cc b/winsup/cygwin/malloc_wrapper.cc index 494fbf13c5b..9841cd528b6 100644 --- a/winsup/cygwin/malloc_wrapper.cc +++ b/winsup/cygwin/malloc_wrapper.cc @@ -25,6 +25,8 @@ details. */ #include "sync.h" #include "perprocess.h" #include "cygmalloc.h" +#include +extern "C" struct mallinfo dlmallinfo (); /* we provide these stubs to call into a user's provided malloc if there is one - otherwise @@ -276,6 +278,22 @@ malloc_stats () return; } +extern "C" struct mallinfo +mallinfo () +{ + struct mallinfo m; + if (!use_internal_malloc) + set_errno (ENOSYS); + else + { + __malloc_lock (); + m = dlmallinfo (); + __malloc_unlock (); + } + + return m; +} + extern "C" char * strdup (const char *s) { diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index 371643a4fac..0d8b80b5c33 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -14,6 +14,7 @@ details. */ #include "winsup.h" #include +#include #include #include #include @@ -540,40 +541,36 @@ cygwin_socket (int af, int type, int protocol) SOCKET soc = 0; fhandler_socket *fh = NULL; - cygheap_fdnew fd; + debug_printf ("socket (%d, %d, %d)", af, type, protocol); - if (fd >= 0) - { - debug_printf ("socket (%d, %d, %d)", af, type, protocol); - - soc = socket (AF_INET, type, af == AF_LOCAL ? 0 : protocol); + soc = socket (AF_INET, type, af == AF_LOCAL ? 0 : protocol); - if (soc == INVALID_SOCKET) - { - set_winsock_errno (); - goto done; - } + if (soc == INVALID_SOCKET) + { + set_winsock_errno (); + goto done; + } - const char *name; + const char *name; - if (af == AF_INET) - name = (type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp"); - else - name = (type == SOCK_STREAM ? "/dev/streamsocket" : "/dev/dgsocket"); + if (af == AF_INET) + name = (type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp"); + else + name = (type == SOCK_STREAM ? "/dev/streamsocket" : "/dev/dgsocket"); + { + cygheap_fdnew fd; + if (fd >= 0) fh = fdsock (fd, name, soc); - if (!fh) - { - closesocket (soc); - res = -1; - } - else - { - fh->set_addr_family (af); - fh->set_socket_type (type); - res = fd; - } - } + if (fh) + { + fh->set_addr_family (af); + fh->set_socket_type (type); + res = fd; + } + else + closesocket (soc); + } done: syscall_printf ("%d = socket (%d, %d, %d)", res, af, type, protocol); @@ -1901,6 +1898,7 @@ cygwin_rcmd (char **ahost, unsigned short inport, char *locuser, { int res = -1; SOCKET fd2s; + sig_dispatch_pending (0); sigframe thisframe (mainthread); @@ -1910,33 +1908,40 @@ cygwin_rcmd (char **ahost, unsigned short inport, char *locuser, (remuser && check_null_str_errno (remuser))) return (int) INVALID_SOCKET; - cygheap_fdnew res_fd; - - if (res_fd < 0) - goto done; - - if (fd2p) + res = rcmd (ahost, inport, locuser, remuser, cmd, fd2p ? &fd2s : NULL); + if (res != (int) INVALID_SOCKET) { - cygheap_fdnew newfd (res_fd, false); + fhandler_socket *fh = NULL; + cygheap_fdnew res_fd; - if (*fd2p < 0) - goto done; - *fd2p = newfd; - } + if (res_fd >= 0) + fh = fdsock (res_fd, "/dev/tcp", res); + if (fh) + res = res_fd; + else + { + closesocket (res); + res = -1; + } - res = rcmd (ahost, inport, locuser, remuser, cmd, fd2p ? &fd2s : NULL); - if (res == (int) INVALID_SOCKET) - goto done; - else - { - fdsock (res_fd, "/dev/tcp", res); - res = res_fd; - } + if (res >= 0 && fd2p) + { + cygheap_fdnew newfd (res_fd, false); - if (fd2p) - fdsock (*fd2p, "/dev/tcp", fd2s); + fh = NULL; + if (newfd >= 0) + fh = fdsock (*fd2p, "/dev/tcp", fd2s); + if (fh) + *fd2p = newfd; + else + { + closesocket (res); + closesocket (fd2s); + res = -1; + } + } + } -done: syscall_printf ("%d = rcmd (...)", res); return res; } @@ -1952,19 +1957,19 @@ cygwin_rresvport (int *port) if (check_null_invalid_struct_errno (port)) return -1; - cygheap_fdnew res_fd; + res = rresvport (port); - if (res_fd < 0) - res = -1; - else + if (res != (int) INVALID_SOCKET) { - res = rresvport (port); + fhandler_socket *fh = NULL; + cygheap_fdnew res_fd; - if (res != (int) INVALID_SOCKET) - { - fdsock (res_fd, "/dev/tcp", res); - res = res_fd; - } + if (res_fd >= 0) + fh = fdsock (res_fd, "/dev/tcp", res); + if (fh) + res = res_fd; + else + res = -1; } syscall_printf ("%d = rresvport (%d)", res, port ? *port : 0); @@ -1987,30 +1992,40 @@ cygwin_rexec (char **ahost, unsigned short inport, char *locuser, (password && check_null_str_errno (password))) return (int) INVALID_SOCKET; - cygheap_fdnew res_fd; - - if (res_fd < 0) - goto done; - if (fd2p) - { - cygheap_fdnew newfd (res_fd); - - if (newfd < 0) - goto done; - *fd2p = newfd; - } res = rexec (ahost, inport, locuser, password, cmd, fd2p ? &fd2s : NULL); - if (res == (int) INVALID_SOCKET) - goto done; - else + if (res != (int) INVALID_SOCKET) { - fdsock (res_fd, "/dev/tcp", res); - res = res_fd; + fhandler_socket *fh = NULL; + cygheap_fdnew res_fd; + + if (res_fd >= 0) + fh = fdsock (res_fd, "/dev/tcp", res); + if (fh) + res = res_fd; + else + { + closesocket (res); + res = -1; + } + + if (res >= 0 && fd2p) + { + cygheap_fdnew newfd (res_fd, false); + + fh = NULL; + if (newfd >= 0) + fh = fdsock (*fd2p, "/dev/tcp", fd2s); + if (fh) + *fd2p = newfd; + else + { + closesocket (res); + closesocket (fd2s); + res = -1; + } + } } - if (fd2p) - fdsock (*fd2p, "/dev/tcp", fd2s); -done: syscall_printf ("%d = rexec (...)", res); return res; } @@ -2024,8 +2039,6 @@ socketpair (int family, int type, int protocol, int *sb) SOCKET insock, outsock, newsock; struct sockaddr_in sock_in, sock_out; int len; - cygheap_fdnew sb0; - fhandler_socket *fh; sig_dispatch_pending (0); sigframe thisframe (mainthread); @@ -2049,19 +2062,6 @@ socketpair (int family, int type, int protocol, int *sb) goto done; } - if (sb0 < 0) - goto done; - else - { - sb[0] = sb0; - cygheap_fdnew sb1 (sb0, false); - - if (sb1 < 0) - goto done; - - sb[1] = sb1; - } - /* create the first socket */ newsock = socket (AF_INET, type, 0); if (newsock == INVALID_SOCKET) @@ -2175,35 +2175,47 @@ socketpair (int family, int type, int protocol, int *sb) insock = newsock; } - res = 0; + { + fhandler_socket *fh = NULL; + cygheap_fdnew sb0; + const char *name; + + if (family == AF_INET) + name = (type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp"); + else + name = (type == SOCK_STREAM ? "/dev/streamsocket" : "/dev/dgsocket"); + + if (sb0 >= 0) + fh = fdsock (sb0, name, insock); + if (fh) + { + fh->set_sun_path (""); + fh->set_addr_family (family); + fh->set_socket_type (type); - if (family == AF_LOCAL) - { + cygheap_fdnew sb1 (sb0, false); - fh = fdsock (sb[0], - type == SOCK_STREAM ? "/dev/streamsocket" : "/dev/dgsocket", - insock); - fh->set_sun_path (""); - fh->set_addr_family (AF_LOCAL); - fh->set_socket_type (type); - fh = fdsock (sb[1], - type == SOCK_STREAM ? "/dev/streamsocket" : "/dev/dgsocket", - outsock); - fh->set_sun_path (""); - fh->set_addr_family (AF_LOCAL); - fh->set_socket_type (type); - } - else - { - fh = fdsock (sb[0], type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp", - insock); - fh->set_addr_family (AF_INET); - fh->set_socket_type (type); - fh = fdsock (sb[1], type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp", - outsock); - fh->set_addr_family (AF_INET); - fh->set_socket_type (type); - } + fh = NULL; + if (sb1 >= 0) + fh = fdsock (sb1, name, outsock); + if (fh) + { + fh->set_sun_path (""); + fh->set_addr_family (family); + fh->set_socket_type (type); + + sb[0] = sb0; + sb[1] = sb1; + res = 0; + } + } + + if (res == -1) + { + closesocket (insock); + closesocket (outsock); + } + } done: syscall_printf ("%d = socketpair (...)", res); diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 51130e7c651..5d15e9bef14 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -629,6 +629,9 @@ path_conv::check (const char *src, unsigned opt, goto out; } + if (sym.pflags & PATH_SOCKET) + dev.setfs (1); + if (sym.case_clash) { if (pcheck_case == PCHECK_STRICT) @@ -814,6 +817,7 @@ out: set_has_buggy_open (strcmp (fs.name, "SUNWNFS") == 0); } } + #if 0 if (issocket ()) devn = FH_SOCKET; diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index dfaa67061f6..912ea6bf392 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -171,9 +171,10 @@ class path_conv short get_unitn () {return dev.minor;} DWORD file_attributes () {return fileattr;} DWORD drive_type () {return fs.drive_type;} + DWORD fs_flags () {return fs.flags;} BOOL fs_fast_ea () {return fs.sym_opt & PC_CHECK_EA;} void set_path (const char *p) {strcpy (path, p);} - const char * root_dir () { return fs.root_dir; } + const char * root_dir () const { return fs.root_dir; } DWORD volser () { return fs.serial; } const char *volname () {return fs.name; } void fillin (HANDLE h); diff --git a/winsup/cygwin/sec_acl.cc b/winsup/cygwin/sec_acl.cc index 1a67dcd41d5..932afc7aaa9 100644 --- a/winsup/cygwin/sec_acl.cc +++ b/winsup/cygwin/sec_acl.cc @@ -413,69 +413,6 @@ getacl (const char *file, DWORD attr, int nentries, __aclent32_t *aclbufp) return pos; } -int -acl_access (const char *path, int flags) -{ - __aclent32_t acls[MAX_ACL_ENTRIES]; - int cnt; - - if ((cnt = acl32 (path, GETACL, MAX_ACL_ENTRIES, acls)) < 1) - return -1; - - /* Only check existence. */ - if (!(flags & (R_OK | W_OK | X_OK))) - return 0; - - for (int i = 0; i < cnt; ++i) - { - switch (acls[i].a_type) - { - case USER_OBJ: - case USER: - if (acls[i].a_id != myself->uid) - { - /* - * Check if user is a NT group: - * Take SID from passwd, search SID in token groups - */ - cygsid owner; - struct passwd *pw; - - if ((pw = internal_getpwuid (acls[i].a_id)) != NULL - && owner.getfrompw (pw) - && internal_getgroups (0, NULL, &owner) > 0) - break; - continue; - } - break; - case GROUP_OBJ: - case GROUP: - if (acls[i].a_id != myself->gid) - { - cygsid group; - struct __group32 *gr = NULL; - - if ((gr = internal_getgrgid (acls[i].a_id)) != NULL - && group.getfromgr (gr) - && internal_getgroups (0, NULL, &group) > 0) - break; - continue; - } - break; - case OTHER_OBJ: - break; - default: - continue; - } - if ((!(flags & R_OK) || (acls[i].a_perm & S_IROTH)) - && (!(flags & W_OK) || (acls[i].a_perm & S_IWOTH)) - && (!(flags & X_OK) || (acls[i].a_perm & S_IXOTH))) - return 0; - } - set_errno (EACCES); - return -1; -} - static int acl_worker (const char *path, int cmd, int nentries, __aclent32_t *aclbufp, diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc index e32b24c8c6f..620c4ff6fbf 100644 --- a/winsup/cygwin/security.cc +++ b/winsup/cygwin/security.cc @@ -1918,3 +1918,54 @@ set_file_attribute (int use_ntsec, const char *file, int attribute) return set_file_attribute (use_ntsec, file, myself->uid, myself->gid, attribute); } + +int +check_file_access (const char *fn, int flags) +{ + int ret = -1; + char sd_buf[4096]; + DWORD sd_size = sizeof sd_buf; + PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) sd_buf; + HANDLE hToken, hIToken; + BOOL status; + char pbuf[sizeof (PRIVILEGE_SET) + 3 * sizeof (LUID_AND_ATTRIBUTES)]; + DWORD desired = 0, granted, plength = sizeof pbuf; + static GENERIC_MAPPING NO_COPY mapping = { FILE_GENERIC_READ, + FILE_GENERIC_WRITE, + FILE_GENERIC_EXECUTE, + FILE_ALL_ACCESS }; + if (read_sd (fn, psd, &sd_size) <= 0) + goto done; + + if (cygheap->user.issetuid ()) + hToken = cygheap->user.token; + else if (!OpenProcessToken (hMainProc, TOKEN_DUPLICATE, &hToken)) + { + __seterrno (); + goto done; + } + if (!(status = DuplicateToken (hToken, SecurityIdentification, &hIToken))) + __seterrno (); + if (hToken != cygheap->user.token) + CloseHandle (hToken); + if (!status) + goto done; + + if (flags & R_OK) + desired |= FILE_READ_DATA; + if (flags & W_OK) + desired |= FILE_WRITE_DATA; + if (flags & X_OK) + desired |= FILE_EXECUTE; + if (!AccessCheck (psd, hIToken, desired, &mapping, + (PPRIVILEGE_SET) pbuf, &plength, &granted, &status)) + __seterrno (); + else if (!status) + set_errno (EACCES); + else + ret = 0; + CloseHandle (hIToken); + done: + debug_printf ("flags %x, ret %d", flags, ret); + return ret; +} diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h index 9cbea2ff0b9..a859526d7f6 100644 --- a/winsup/cygwin/security.h +++ b/winsup/cygwin/security.h @@ -225,6 +225,7 @@ LONG __stdcall read_sd(const char *file, PSECURITY_DESCRIPTOR sd_buf, LPDWORD sd LONG __stdcall write_sd(const char *file, PSECURITY_DESCRIPTOR sd_buf, DWORD sd_size); BOOL __stdcall add_access_allowed_ace (PACL acl, int offset, DWORD attributes, PSID sid, size_t &len_add, DWORD inherit); BOOL __stdcall add_access_denied_ace (PACL acl, int offset, DWORD attributes, PSID sid, size_t &len_add, DWORD inherit); +int __stdcall check_file_access (const char *, int); void set_security_attribute (int attribute, PSECURITY_ATTRIBUTES psa, void *sd_buf, DWORD sd_buf_size); diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 2a3bd945e9a..f3c5d6818ab 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -170,10 +170,12 @@ out: void __stdcall wait_for_sigthread () { - assert (wait_sig_inited); - (void) WaitForSingleObject (wait_sig_inited, INFINITE); - (void) ForceCloseHandle (wait_sig_inited); + sigproc_printf ("wait_sig_inited %p", wait_sig_inited); + HANDLE hsig_inited = wait_sig_inited; + assert (hsig_inited); + (void) WaitForSingleObject (hsig_inited, INFINITE); wait_sig_inited = NULL; + (void) ForceCloseHandle1 (hsig_inited, wait_sig_inited); } /* Get the sync_proc_subproc muto to control access to @@ -654,7 +656,8 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception) { if (no_signals_available ()) goto out; // Either exiting or not yet initializing - assert (!wait_sig_inited); + if (wait_sig_inited) + wait_for_sigthread (); wait_for_completion = p != myself_nowait; p = myself; } diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index fea94f4f3c7..c4dc59ebd6e 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -1179,8 +1179,6 @@ cygwin_lstat (const char *name, struct __stat32 *buf) return ret; } -extern int acl_access (const char *, int); - extern "C" int access (const char *fn, int flags) { @@ -1192,11 +1190,33 @@ access (const char *fn, int flags) return -1; } - if (allow_ntsec) - return acl_access (fn, flags); + path_conv real_path (fn, PC_SYM_FOLLOW | PC_FULL, stat_suffixes); + if (real_path.error) + { + set_errno (real_path.error); + return -1; + } + + if (!real_path.exists ()) + { + set_errno (ENOENT); + return -1; + } + + if (!(flags & (R_OK | W_OK | X_OK))) + return 0; + + if (real_path.has_attribute (FILE_ATTRIBUTE_READONLY) && (flags & W_OK)) + { + set_errno (EACCES); + return -1; + } + + if (real_path.has_acls () && allow_ntsec) + return check_file_access (real_path, flags); struct __stat64 st; - int r = stat_worker (fn, &st, 0); + int r = stat_worker (real_path, &st, 0); if (r) return -1; r = -1; @@ -1824,7 +1844,7 @@ statfs (const char *fname, struct statfs *sfs) } path_conv full_path (fname, PC_SYM_FOLLOW | PC_FULL); - char *root = rootdir (full_path); + const char *root = full_path.root_dir (); syscall_printf ("statfs %s", root); diff --git a/winsup/cygwin/syslog.cc b/winsup/cygwin/syslog.cc index 7e358df3a51..761708f1d3f 100644 --- a/winsup/cygwin/syslog.cc +++ b/winsup/cygwin/syslog.cc @@ -302,8 +302,7 @@ syslog (int priority, const char *message, ...) } if (process_logopt & LOG_PID) { - if (pass.print ("Win32 Process Id = 0x%X : Cygwin Process Id = 0x%X : ", - GetCurrentProcessId (), getpid ()) == -1) + if (pass.print ("PID %u : ", getpid ()) == -1) return; } @@ -375,6 +374,8 @@ syslog (int priority, const char *message, ...) else { /* Under Windows 95, append the message to the log file */ + char timestamp[24]; + time_t ctime; FILE *fp = fopen (get_win95_event_log_path (), "a"); if (fp == NULL) { @@ -382,24 +383,32 @@ syslog (int priority, const char *message, ...) get_win95_event_log_path ()); return; } + strftime (timestamp, sizeof timestamp, "%Y-%m-%d %H:%M:%S : ", + localtime (&(ctime = time (NULL)))); + /* Now to prevent several syslog messages from being interleaved, we must lock the first byte of the file This works on Win32 even if we created the file above. */ HANDLE fHandle = cygheap->fdtab[fileno (fp)]->get_handle (); - if (LockFile (fHandle, 0, 0, 1, 0) == FALSE) - { - debug_printf ("failed to lock file %s", get_win95_event_log_path ()); - fclose (fp); - return; - } + for (int i = 0;; i++) + if (LockFile (fHandle, 0, 0, 1, 0) == FALSE) + if (i == 3) + { + debug_printf ("failed to lock file %s", get_win95_event_log_path ()); + fclose (fp); + return; + } + else + usleep (1000); + else + break; + fputs (timestamp, fp); fputs (msg_strings[0], fp); fputc ('\n', fp); UnlockFile (fHandle, 0, 0, 1, 0); if (ferror (fp)) - { - debug_printf ("error in writing syslog"); - } + debug_printf ("error in writing syslog"); fclose (fp); } } -- cgit v1.2.1