diff options
author | Christopher Faylor <me@cgf.cx> | 2003-05-26 19:39:07 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2003-05-26 19:39:07 +0000 |
commit | e4be0da637723b663fbffd37b6fb7a950cd21cf9 (patch) | |
tree | e55a68c6ee130091a297cd9e5457fa7c3ee9847f | |
parent | 2d6b97688a24f1a792a59a106fc22fffd7fe8627 (diff) | |
download | newlib-e4be0da637723b663fbffd37b6fb7a950cd21cf9.zip newlib-e4be0da637723b663fbffd37b6fb7a950cd21cf9.tar.gz newlib-e4be0da637723b663fbffd37b6fb7a950cd21cf9.tar.bz2 |
merge from trunk
29 files changed, 573 insertions, 206 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index d7584b8..76f1fc3 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,163 @@ +2003-05-26 Pierre Humblet <pierre.humblet@ieee.org> + + * syscalls.cc (statfs): Call GetDiskFreeSpaceEx before GetDiskFreeSpace. + +2003-05-26 Corinna Vinschen <corinna@vinschen.de> + + * fhandler.cc (is_at_eof): Fix conditional. Use INVALID_FILE_SIZE + instead of numeric constant. + +2003-05-26 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_socket.cc (fhandler_socket::connect): Guard calls to + sock_event methods by a check for WinSock2 availability. + (fhandler_socket::accept): Ditto. + +2003-05-26 Corinna Vinschen <corinna@vinschen.de> + + * fhandler.h: Rename FH_W95LSBUG flag to FH_LSEEKED. + (fhandler_base::set_did_lseek): Rename from set_check_win95_lseek_bug. + (fhandler_base::get_did_lseek): Rename from get_check_win95_lseek_bug. + (fhandler_base::set_fs_flags): New method. + (fhandler_base::get_fs_flags): Ditto. + * fhandler.cc (fhandler_base::write): Make 64 bit clean. Convert file + to a "sparse" file when writing after a long lseek (>64K) beyond EOF. + (fhandler_base::lseek): Call set_did_lseek() instead of + set_check_win95_lseek_bug(). + (fhandler_base::fhandler_base): Initialize fs_flags to 0. + * fhandler_disk_file.cc (fhandler_disk_file::open): Don't create files + as "sparse" unconditionally. Set fs_flags member. + +2003-05-25 Pierre Humblet <pierre.humblet@ieee.org> + + * autoload.cc (GetDiskFreeSpaceEx): Add. + * syscalls.cc (statfs): Call full_path.root_dir() instead of + rootdir(full_path). Use GetDiskFreeSpaceEx when available and + report space available in addition to free space. + * fhandler_disk_file.cc (fhandler_disk_file::fstat_by_name): + Do not call FindFirstFile for disk root directories. + +2003-05-24 Joe Buehler <jhpb@draco.hekimian.com> + + * fhandler_process.cc (format_process_stat): Use PagefileUsage + instead of VirtualSize. + (get_mem_values): Ditto. + +2003-05-21 Corinna Vinschen <corinna@vinschen.de> + + * shared_info.h: Match shared_name declaration with below change. + * shared.cc (shared_name): Use incoming char * parameter instead of + local static buffer. + (open_shared): Accomodate new calling convention for shared_name. + * exceptions.cc (events_init): Ditto. + * sigproc.cc (getsem): Ditto. + * syscalls.cc (login): Ditto. + (logout): Ditto. + (pututline): Ditto. + +2003-05-20 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_socket.cc (secret_event_name): Return void. Use incoming + char * parameter instead of local static buffer. + (fhandler_socket::create_secret_event): Accomodate new calling + convention for secret_event_name. + (fhandler_socket::close_secret_event): Ditto. + +2003-05-20 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_socket.cc (SECRET_EVENT_NAME): Remove. + (ENTROPY_SOURCE_NAME): Ditto. + (secret_event_name): New static function. Create shared event name + with "Global\" prefix on systems supporting terminal services. + (fhandler_socket::set_connect_secret): Fix conditional. + (fhandler_socket::create_secret_event): Create secret event using + secret_event_name(). + (fhandler_socket::close_secret_event): Ditto. + * shared.cc (shared_name): Create shared object name with "Global\" + prefix on systems supporting terminal services. + * wincap.cc: Set has_terminal_services capability throughout. + (wincap_2003): New global object representing Windows 2003 Server + capabilities. + (wincapc::init): Accomodate Windows 2003 Server. + * wincap.h (struct wincaps): Add has_terminal_services capability. + +2003-05-20 Charles Wilson <cygwin@cwilson.fastmail.fm> + + * winsup/cygwin/include/cygwin/version.h: Bump API minor version. + * winsup/cygwin/include/cygwin/types.h: Define key_t as long long. + * winsup/cygwin/cygwin.din: Add ftok, _ftok. + * winsup/cygwin/ipc.cc (ftok): Rework implementation. + +2003-05-18 Joe Buehler <jhpb@hekimian.com> + + * spawn.cc (spawn_guts): Show more of command line in strace output. + +2003-05-15 Thomas Pfaff <tpfaff@gmx.net> + + * thread.h (pthread::init_mainthread): Remove function parameter. + (MTinterface::Init): Ditto. + * thread.cc (MTinterface::Init): Remove function parameter. + Always initialize reent_key. + (pthread::init_mainthread): Remove function parameter. + (MTinterface::fixup_after_fork): Fix pthread::init_mainthread call. + * dcrt0.cc (dll_crt_0_1) Fix calls to MTinterface::Init and + pthread::init_mainthread. + Call pthread::init_mainthread only when not forked. + +2003-05-15 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_proc.cc (format_proc_meminfo): Make swap memory output + Linux style values. + +2003-05-13 Corinna Vinschen <corinna@vinschen.de> + + * include/cygwin/config.h: Define __USE_INTERNAL_STAT64 appropriately. + +2003-05-12 Corinna Vinschen <corinna@vinschen.de> + + * Makefile.in (CYGWIN_START): Define as crt0.o. Add to TARGET_LIBS. + * fhandler.h (fhandler_virtual::fstat): Remove useless declaration. + * fhandler_virtual.cc: Remove _COMPILING_NEWLIB define. + * ipc.cc (ftok): Use stat64. + * syscalls.cc (_fstat64): Remove alias. + (_fstat): Ditto. + (_stat): Ditto. + (_fstat64_r): New function. + (_fstat_r): Ditto. + (_stat64_r): Ditto. + (stat_r): Ditto. + * crt0.o: New file, moved from newlib. + * include/sys/param.h: Ditto. + * include/sys/utime.h: Ditto. + * include/sys/utmp.h: Ditto. + * include/sys/dirent.h: Ditto. Expose different struct dirent, + dependening of the environment. + +2003-05-11 Corinna Vinschen <corinna@vinschen.de> + + Replace ino_t by __ino64_t throughout. + +2003-05-11 Corinna Vinschen <corinna@vinschen.de> + + * include/cygwin/types.h: Add key_t typedef. + +2003-05-10 Christopher Faylor <cgf@redhat.com> + + * dir.cc (readdir): Fill out new old_d_ino field. + * fhandler.h (fhandler_base::namehash): Define as ino_t. + (fhandler_base::get_namehash): Ditto. + * fhandler_disk_file.cc (fhandler_disk_file::fstat_helper): Accommodate + new 64 bit st_ino. + * fhandler_socket.cc (fhandler_socket::fstat): Ditto. + * path.cc (hash_path_name): Return ino_t. + * syscalls.cc (stat64_to_stat32): Convert 64 bit inode to 32 bit. + * winsup.h (hash_path_name): Declare as returning ino_t. + * include/cygwin/stat.h (__stat32): Use 32 bit st_ino. + (__stat64): Use 64 bit st_ino. + * include/cygwin/types.h (__ino64_t): Define. + (__ino32_t): Ditto. + (ino_t): Define appropriately. + 2003-05-10 Corinna Vinschen <corinna@vinschen.de> * Makefile.in (NEW_FUNCTIONS): All 32/64 from 0.79 API get @@ -202,7 +362,7 @@ (cygthread::operator new): Simplify. Just grab a thread structure from the pool. Don't try to start the thread. (cygthread::terminate_thread): Don't close event handles. Just reuse - them. Call MEM_RELEASE rather than MEM_DECOMMIT (from Joe Buehler). + them. Call MEM_RELEASE rather than MEM_DECOMMIT (from Joe uehler). 2003-04-08 Bob Cassels <bcassels@abinitio.com> @@ -448,11 +608,6 @@ 2003-03-22 Christopher Faylor <cgf@redhat.com> - * pipe.cc (fhandler_pipe::dup): Don't dup input_handle if it doesn't - exist. - -2003-03-22 Christopher Faylor <cgf@redhat.com> - * syscalls.cc (unlink): Be more defensive when SetFileAttributes is called. Fix typo in debugging output. diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index 6378db4..b892b37 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -124,6 +124,7 @@ DEF_FILE:=cygwin.def DLL_ENTRY:=@DLL_ENTRY@ LIBGMON_A:=libgmon.a +CYGWIN_START:=crt0.o GMON_START:=gcrt0.o # Some things want these from libc, but they have their own static @@ -239,7 +240,7 @@ PWD:=${shell pwd} SUBLIBS:=libpthread.a $(PWD)/libm.a libc.a EXTRALIBS:=libautomode.a libbinmode.a libtextmode.a INSTOBJS:=automode.o binmode.o textmode.o -TARGET_LIBS:=$(LIB_NAME) $(SUBLIBS) $(GMON_START) $(LIBGMON_A) $(SUBLIBS) $(INSTOBJS) $(EXTRALIBS) +TARGET_LIBS:=$(LIB_NAME) $(SUBLIBS) $(CYGWIN_START) $(GMON_START) $(LIBGMON_A) $(SUBLIBS) $(INSTOBJS) $(EXTRALIBS) .PHONY: all force dll_ofiles install all_target install_target all_host install_host \ install install-libs install-headers -lgcc diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index 24527f5..71e7f9e 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -502,6 +502,7 @@ LoadDLLfuncEx (CreateHardLinkA, 12, kernel32, 1) LoadDLLfuncEx (CreateToolhelp32Snapshot, 8, kernel32, 1) LoadDLLfuncEx2 (GetCompressedFileSizeA, 8, kernel32, 1, 0xffffffff) LoadDLLfuncEx (GetConsoleWindow, 0, kernel32, 1) +LoadDLLfuncEx (GetDiskFreeSpaceEx, 16, kernel32, 1) LoadDLLfuncEx (GetSystemTimes, 12, kernel32, 1) LoadDLLfuncEx2 (IsDebuggerPresent, 0, kernel32, 1, 1) LoadDLLfunc (IsProcessorFeaturePresent, 4, kernel32); diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din index cf0dfd6..5dda7ea 100644 --- a/winsup/cygwin/cygwin.din +++ b/winsup/cygwin/cygwin.din @@ -508,6 +508,8 @@ _ftello = ftello _ftello64 = ftello64 ftime _ftime = ftime +ftok +_ftok = ftok ftruncate _ftruncate = ftruncate _ftruncate64 = ftruncate64 diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 51c3db0..09fbf58 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -564,7 +564,7 @@ dll_crt0_1 () _impure_ptr = &reent_data; user_data->resourcelocks->Init (); - user_data->threadinterface->Init (user_data->forkee); + user_data->threadinterface->Init (); mainthread.init ("mainthread"); // For use in determining if signals // should be blocked. @@ -630,7 +630,10 @@ dll_crt0_1 () ProtectHandle (hMainThread); cygthread::init (); - pthread::init_mainthread (!user_data->forkee); + /* Initialize pthread mainthread when not forked and it is save to call new, + otherwise it is reinitalized in fixup_after_fork */ + if (!user_data->forkee) + pthread::init_mainthread (); /* Initialize debug muto, if DLL is built with --enable-debugging. Need to do this before any helper threads start. */ diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc index 5ef76d8..4ed076e 100644 --- a/winsup/cygwin/dir.cc +++ b/winsup/cygwin/dir.cc @@ -140,10 +140,11 @@ readdir (DIR *dir) else { hashit: - ino_t dino = hash_path_name (dir->__d_dirhash, "\\"); + __ino64_t dino = hash_path_name (dir->__d_dirhash, "\\"); dir->__d_dirent->d_ino = hash_path_name (dino, res->d_name); } } + dir->__d_dirent->old_d_ino = dir->__d_dirent->d_ino; // just truncate return res; } diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index ec4b7f4..482745e 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -1134,11 +1134,13 @@ void events_init (void) { char *name; + char mutex_name[MAX_PATH]; /* title_mutex protects modification of console title. It's necessary while finding console window handle */ if (!(title_mutex = CreateMutex (&sec_all_nih, FALSE, - name = shared_name ("title_mutex", 0)))) + name = shared_name (mutex_name, + "title_mutex", 0)))) api_fatal ("can't create title mutex '%s', %E", name); ProtectHandle (title_mutex); diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index a431966..fb391f4 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -27,6 +27,7 @@ details. */ #include "pinfo.h" #include <assert.h> #include <limits.h> +#include <winioctl.h> static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */ @@ -160,7 +161,7 @@ is_at_eof (HANDLE h, DWORD err) DWORD size, upper1, curr; size = GetFileSize (h, &upper1); - if (upper1 != 0xffffffff || GetLastError () == NO_ERROR) + if (size != INVALID_FILE_SIZE || GetLastError () == NO_ERROR) { LONG upper2 = 0; curr = SetFilePointer (h, 0, &upper2, FILE_CURRENT); @@ -581,47 +582,75 @@ fhandler_base::write (const void *ptr, size_t len) if (get_append_p ()) SetFilePointer (get_output_handle (), 0, 0, FILE_END); - else if (wincap.has_lseek_bug () && get_check_win95_lseek_bug ()) + else if (get_did_lseek ()) { - /* Note: this bug doesn't happen on NT4, even though the documentation - for WriteFile() says that it *may* happen on any OS. */ - int actual_length, current_position; - set_check_win95_lseek_bug (0); /* don't do it again */ - actual_length = GetFileSize (get_output_handle (), NULL); - current_position = SetFilePointer (get_output_handle (), 0, 0, FILE_CURRENT); + _off64_t actual_length, current_position; + DWORD size_high = 0; + LONG pos_high = 0; + + set_did_lseek (0); /* don't do it again */ + + actual_length = GetFileSize (get_output_handle (), &size_high); + actual_length += ((_off64_t) size_high) << 32; + + current_position = SetFilePointer (get_output_handle (), 0, &pos_high, + FILE_CURRENT); + current_position += ((_off64_t) pos_high) << 32; + if (current_position > actual_length) { - /* Oops, this is the bug case - Win95 uses whatever is on the disk - instead of some known (safe) value, so we must seek back and - fill in the gap with zeros. - DJ */ - char zeros[512]; - int number_of_zeros_to_write = current_position - actual_length; - memset (zeros, 0, 512); - SetFilePointer (get_output_handle (), 0, 0, FILE_END); - while (number_of_zeros_to_write > 0) + if ((get_fs_flags (FILE_SUPPORTS_SPARSE_FILES)) + && current_position >= actual_length + (64 * 1024)) { - DWORD zeros_this_time = (number_of_zeros_to_write > 512 - ? 512 : number_of_zeros_to_write); - DWORD written; - if (!WriteFile (get_output_handle (), zeros, zeros_this_time, &written, - NULL)) - { - __seterrno (); - if (get_errno () == EPIPE) - raise (SIGPIPE); - /* This might fail, but it's the best we can hope for */ - SetFilePointer (get_output_handle (), current_position, 0, FILE_BEGIN); - return -1; - - } - if (written < zeros_this_time) /* just in case */ + /* If the file systemn supports sparse files and the application + is writing after a long seek beyond EOF, convert the file to + a sparse file. */ + DWORD dw; + 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, " + "NULL, 0, NULL, 0, &dw, NULL)", r, h); + } + else if (wincap.has_lseek_bug ()) + { + /* Oops, this is the bug case - Win95 uses whatever is on the + disk instead of some known (safe) value, so we must seek + back and fill in the gap with zeros. - DJ + Note: this bug doesn't happen on NT4, even though the + documentation for WriteFile() says that it *may* happen + on any OS. */ + char zeros[512]; + int number_of_zeros_to_write = current_position - actual_length; + memset (zeros, 0, 512); + SetFilePointer (get_output_handle (), 0, NULL, FILE_END); + while (number_of_zeros_to_write > 0) { - set_errno (ENOSPC); - /* This might fail, but it's the best we can hope for */ - SetFilePointer (get_output_handle (), current_position, 0, FILE_BEGIN); - return -1; + DWORD zeros_this_time = (number_of_zeros_to_write > 512 + ? 512 : number_of_zeros_to_write); + DWORD written; + if (!WriteFile (get_output_handle (), zeros, zeros_this_time, + &written, NULL)) + { + __seterrno (); + if (get_errno () == EPIPE) + raise (SIGPIPE); + /* This might fail, but it's the best we can hope for */ + SetFilePointer (get_output_handle (), current_position, NULL, + FILE_BEGIN); + return -1; + + } + if (written < zeros_this_time) /* just in case */ + { + set_errno (ENOSPC); + /* This might fail, but it's the best we can hope for */ + SetFilePointer (get_output_handle (), current_position, NULL, + FILE_BEGIN); + return -1; + } + number_of_zeros_to_write -= written; } - number_of_zeros_to_write -= written; } } } @@ -847,7 +876,7 @@ fhandler_base::lseek (_off64_t offset, int whence) { /* When next we write(), we will check to see if *this* seek went beyond the end of the file, and back-seek and fill with zeros if so - DJ */ - set_check_win95_lseek_bug (); + set_did_lseek (); /* If this was a SEEK_CUR with offset 0, we still might have readahead that we have to take into account when calculating @@ -1138,6 +1167,7 @@ fhandler_base::fhandler_base (): raixput (0), rabuflen (0), open_status (0), + fs_flags (0), read_state (NULL) { } diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index cd278a3..d3b0f5d 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -25,9 +25,10 @@ enum FH_SYMLINK = 0x00100000, /* is a symlink */ FH_EXECABL = 0x00200000, /* file looked like it would run: * ends in .exe or .bat or begins with #! */ - FH_W95LSBUG = 0x00400000, /* set when lseek is called as a flag that + FH_LSEEKED = 0x00400000, /* set when lseek is called as a flag that * _write should check if we've moved beyond - * EOF, zero filling if so. */ + * EOF, zero filling or making file sparse + if so. */ FH_NOHANDLE = 0x00800000, /* No handle associated with fhandler. */ FH_NOEINTR = 0x01000000, /* Set if I/O should be uninterruptible. */ FH_FFIXUP = 0x02000000, /* Set if need to fixup after fork. */ @@ -104,7 +105,7 @@ class fhandler_base int access; HANDLE io_handle; - unsigned long namehash; /* hashed filename, used as inode num */ + __ino64_t namehash; /* hashed filename, used as inode num */ protected: /* Full unix path name of this file */ @@ -118,6 +119,7 @@ class fhandler_base size_t rabuflen; DWORD open_status; + DWORD fs_flags; HANDLE read_state; path_conv pc; @@ -192,8 +194,8 @@ class fhandler_base return get_close_on_exec () ? &sec_none_nih : &sec_none; } - void set_check_win95_lseek_bug (int b = 1) { FHCONDSETF (b, W95LSBUG); } - bool get_check_win95_lseek_bug () { return FHISSETF (W95LSBUG); } + void set_did_lseek (int b = 1) { FHCONDSETF (b, LSEEKED); } + bool get_did_lseek () { return FHISSETF (LSEEKED); } bool get_need_fork_fixup () { return FHISSETF (FFIXUP); } void set_need_fork_fixup () { FHSETF (FFIXUP); } @@ -226,6 +228,10 @@ class fhandler_base void set_append_p (int val) { FHCONDSETF (val, APPEND); } void set_append_p () { FHSETF (APPEND); } + void set_fs_flags (DWORD flags) { fs_flags = flags; } + bool get_fs_flags (DWORD flagval = 0xffffffffUL) + { return (fs_flags & (flagval)); } + bool get_query_open () { return FHISSETF (QUERYOPEN); } void set_query_open (bool val) { FHCONDSETF (val, QUERYOPEN); } @@ -250,7 +256,7 @@ class fhandler_base const char *get_name () const { return pc.normalized_path; } const char *get_win32_name () { return pc.get_win32 (); } - unsigned long get_namehash () { return namehash; } + __ino64_t get_namehash () { return namehash; } virtual void hclose (HANDLE h) {CloseHandle (h);} virtual void set_inheritance (HANDLE &h, int not_inheriting); diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index 0980440..d28c4bb 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -26,7 +26,6 @@ details. */ #include "pinfo.h" #include <assert.h> #include <ctype.h> -#include <winioctl.h> #define _COMPILING_NEWLIB #include <dirent.h> @@ -106,6 +105,8 @@ int __stdcall fhandler_base::fstat_by_name (struct __stat64 *buf) { int res; + HANDLE handle; + WIN32_FIND_DATA local; if (!pc.exists ()) { @@ -113,41 +114,26 @@ 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 { - char drivebuf[5]; - char *name; - if ((pc)[3] != '\0' || !isalpha ((pc)[0]) || (pc)[1] != ':' || (pc)[2] != '\\') - name = pc; - else - { - /* FIXME: Does this work on empty disks? */ - drivebuf[0] = pc[0]; - drivebuf[1] = pc[1]; - drivebuf[2] = pc[2]; - drivebuf[3] = '*'; - drivebuf[4] = '\0'; - name = drivebuf; - } - - HANDLE h; - WIN32_FIND_DATA local; - if ((h = FindFirstFile (name, &local)) == INVALID_HANDLE_VALUE) - { - debug_printf ("FindFirstFile failed for '%s', %E", name); - __seterrno (); - res = -1; - } - else - { - FindClose (h); - res = fstat_helper (buf, - local.ftCreationTime, - local.ftLastAccessTime, - local.ftLastWriteTime, - local.nFileSizeHigh, - local.nFileSizeLow); - } + FindClose (handle); + res = fstat_helper (buf, + local.ftCreationTime, + local.ftLastAccessTime, + local.ftLastWriteTime, + local.nFileSizeHigh, + local.nFileSizeLow); } return res; } @@ -256,7 +242,8 @@ fhandler_base::fstat_helper (struct __stat64 *buf, case DRIVE_RAMDISK: /* Although the documentation indicates otherwise, it seems like "inodes" on these devices are persistent, at least across reboots. */ - buf->st_ino = nFileIndexHigh | nFileIndexLow; + buf->st_ino = (((__ino64_t) nFileIndexHigh) << 32) + | (__ino64_t) nFileIndexLow; break; default: /* Either the nFileIndex* fields are unreliable or unavailable. Use the @@ -290,7 +277,7 @@ fhandler_base::fstat_helper (struct __stat64 *buf, { /* symlinks are everything for everyone! */ buf->st_mode = S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO; - get_file_attribute (pc->has_acls (), get_win32_name (), NULL, + get_file_attribute (pc.has_acls (), get_win32_name (), NULL, &buf->st_uid, &buf->st_gid); goto done; } @@ -425,18 +412,7 @@ fhandler_base::open_fs (int flags, mode_t mode) && !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_fs_flags (pc.fs_flags ()); set_symlink_p (pc.issymlink ()); set_execable_p (pc.exec_state ()); set_socket_p (pc.issocket ()); diff --git a/winsup/cygwin/fhandler_proc.cc b/winsup/cygwin/fhandler_proc.cc index e6a065f..2ab9fad 100644 --- a/winsup/cygwin/fhandler_proc.cc +++ b/winsup/cygwin/fhandler_proc.cc @@ -392,8 +392,8 @@ format_proc_meminfo (char *destbuf, size_t maxsize) GlobalMemoryStatus (&memory_status); mem_total = memory_status.dwTotalPhys; mem_free = memory_status.dwAvailPhys; - swap_total = memory_status.dwTotalPageFile; - swap_free = memory_status.dwAvailPageFile; + swap_total = memory_status.dwTotalPageFile - mem_total; + swap_free = memory_status.dwAvailPageFile - mem_total; return __small_sprintf (destbuf, " total: used: free:\n" "Mem: %10lu %10lu %10lu\n" "Swap: %10lu %10lu %10lu\n" diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index 7277b18..1c46f6f 100644 --- a/winsup/cygwin/fhandler_process.cc +++ b/winsup/cygwin/fhandler_process.cc @@ -475,7 +475,7 @@ format_process_stat (_pinfo *p, char *destbuf, size_t maxsize) start_time = (spt.KernelTime.QuadPart + spt.UserTime.QuadPart) * HZ / 10000000ULL; priority = pbi.BasePriority; unsigned page_size = getpagesize (); - vmsize = vmc.VirtualSize; + vmsize = vmc.PagefileUsage; vmrss = vmc.WorkingSetSize / page_size; vmmaxrss = ql.MaximumWorkingSetSize / page_size; } @@ -740,7 +740,7 @@ get_mem_values (DWORD dwProcessId, unsigned long *vmsize, unsigned long *vmrss, res = false; goto out; } - *vmsize = vmc.VirtualSize / page_size; + *vmsize = vmc.PagefileUsage / page_size; out: delete [] p; CloseHandle (hProcess); diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index 2e4bf11..5a16073 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -34,9 +34,6 @@ #include "wsock_event.h" #include <unistd.h> -#define SECRET_EVENT_NAME "cygwin.local_socket.secret.%d.%08x-%08x-%08x-%08x" -#define ENTROPY_SOURCE_NAME "/dev/urandom" - extern bool fdsock (cygheap_fdmanip& fd, const device *, SOCKET soc); extern "C" { int sscanf (const char *, const char *, ...); @@ -44,6 +41,16 @@ int sscanf (const char *, const char *, ...); fhandler_dev_random* entropy_source; +static void +secret_event_name (char *buf, short port, int *secret_ptr) +{ + __small_sprintf (buf, "%scygwin.local_socket.secret.%d.%08x-%08x-%08x-%08x", + wincap.has_terminal_services () ? "Global\\" : "", + port, + secret_ptr [0], secret_ptr [1], + secret_ptr [2], secret_ptr [3]); +} + /* cygwin internal: map sockaddr into internet domain address */ static int get_inet_addr (const struct sockaddr *in, int inlen, @@ -219,7 +226,7 @@ fhandler_socket::set_connect_secret () delete entropy_source; entropy_source = NULL; } - if (!entropy_source) + if (entropy_source) { size_t len = sizeof (connect_secret); entropy_source->read (connect_secret, len); @@ -239,8 +246,6 @@ fhandler_socket::get_connect_secret (char* buf) HANDLE fhandler_socket::create_secret_event (int* secret) { - char buf [128]; - int* secret_ptr = (secret ? : connect_secret); struct sockaddr_in sin; int sin_len = sizeof (sin); @@ -250,13 +255,12 @@ fhandler_socket::create_secret_event (int* secret) return NULL; } - __small_sprintf (buf, SECRET_EVENT_NAME, sin.sin_port, - secret_ptr [0], secret_ptr [1], - secret_ptr [2], secret_ptr [3]); + char event_name[MAX_PATH]; + secret_event_name (event_name, sin.sin_port, secret ?: connect_secret); LPSECURITY_ATTRIBUTES sec = get_inheritance (true); - secret_event = CreateEvent (sec, FALSE, FALSE, buf); + secret_event = CreateEvent (sec, FALSE, FALSE, event_name); if (!secret_event && GetLastError () == ERROR_ALREADY_EXISTS) - secret_event = OpenEvent (EVENT_ALL_ACCESS, FALSE, buf); + secret_event = OpenEvent (EVENT_ALL_ACCESS, FALSE, event_name); if (!secret_event) /* nothing to do */; @@ -291,18 +295,15 @@ fhandler_socket::close_secret_event () int fhandler_socket::check_peer_secret_event (struct sockaddr_in* peer, int* secret) { - char buf [128]; - HANDLE ev; - int* secret_ptr = (secret ? : connect_secret); - - __small_sprintf (buf, SECRET_EVENT_NAME, peer->sin_port, - secret_ptr [0], secret_ptr [1], - secret_ptr [2], secret_ptr [3]); - ev = CreateEvent (&sec_all_nih, FALSE, FALSE, buf); + + char event_name[MAX_PATH]; + + secret_event_name (event_name, peer->sin_port, secret ?: connect_secret); + HANDLE ev = CreateEvent (&sec_all_nih, FALSE, FALSE, event_name); if (!ev && GetLastError () == ERROR_ALREADY_EXISTS) { - debug_printf ("event \"%s\" already exists", buf); - ev = OpenEvent (EVENT_ALL_ACCESS, FALSE, buf); + debug_printf ("event \"%s\" already exists", event_name); + ev = OpenEvent (EVENT_ALL_ACCESS, FALSE, event_name); } signal_secret_event (); @@ -433,14 +434,14 @@ fhandler_socket::fstat (struct __stat64 *buf) if (get_socket_type ()) /* fstat */ { buf->st_dev = 0; - buf->st_ino = (ino_t) get_handle (); + buf->st_ino = (__ino64_t) ((DWORD) get_handle ()); buf->st_mode = S_IFSOCK | S_IRWXU | S_IRWXG | S_IRWXO; } else { path_conv spc ("/dev", PC_SYM_NOFOLLOW | PC_NULLEMPTY, NULL); buf->st_dev = spc.volser (); - buf->st_ino = (ino_t) get_namehash (); + buf->st_ino = get_namehash (); buf->st_mode &= ~S_IRWXO; buf->st_rdev = (get_device () << 16) | get_unit (); } @@ -553,7 +554,7 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen) if (!get_inet_addr (name, namelen, &sin, &namelen, secret)) return -1; - if (!is_nonblocking () && !is_connect_pending ()) + if (winsock2_active && !is_nonblocking () && !is_connect_pending ()) if (!evt.load (get_socket (), FD_CONNECT_BIT)) { set_winsock_errno (); @@ -562,7 +563,7 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen) res = ::connect (get_socket (), (sockaddr *) &sin, namelen); - if (res && !is_nonblocking () && !is_connect_pending () && + if (winsock2_active && res && !is_nonblocking () && !is_connect_pending () && WSAGetLastError () == WSAEWOULDBLOCK) switch (evt.wait ()) { @@ -673,7 +674,7 @@ fhandler_socket::accept (struct sockaddr *peer, int *len) if (len && ((unsigned) *len < sizeof (struct sockaddr_in))) *len = sizeof (struct sockaddr_in); - if (!is_nonblocking ()) + if (winsock2_active && !is_nonblocking ()) { sock_event evt; if (!evt.load (get_socket (), FD_ACCEPT_BIT)) diff --git a/winsup/cygwin/fhandler_virtual.cc b/winsup/cygwin/fhandler_virtual.cc index 410f667..baf8e79 100644 --- a/winsup/cygwin/fhandler_virtual.cc +++ b/winsup/cygwin/fhandler_virtual.cc @@ -22,7 +22,6 @@ details. */ #include "cygheap.h" #include <assert.h> -#define _COMPILING_NEWLIB #include <dirent.h> fhandler_virtual::fhandler_virtual (): diff --git a/winsup/cygwin/include/cygwin/config.h b/winsup/cygwin/include/cygwin/config.h index 4bafa3c..77815a0 100644 --- a/winsup/cygwin/include/cygwin/config.h +++ b/winsup/cygwin/include/cygwin/config.h @@ -23,6 +23,14 @@ extern "C" { #define _READ_WRITE_RETURN_TYPE _ssize_t #define __LARGE64_FILES 1 #define __CYGWIN_USE_BIG_TYPES__ 1 +#ifdef __CYGWIN_USE_BIG_TYPES__ +/* __USE_INTERNAL_STAT64 is needed when building newlib for Cygwin. + It must be set when __CYGWIN_USE_BIG_TYPES__ is set. In this case + newlib will call the 64 bit stat calls internally. Otherwise the + struct stat used in newlib is not matching the struct stat used in + Cygwin. */ +#define __USE_INTERNAL_STAT64 1 +#endif #if defined(__INSIDE_CYGWIN__) || defined(_COMPILING_NEWLIB) #define __IMPORT #else diff --git a/winsup/cygwin/include/cygwin/stat.h b/winsup/cygwin/include/cygwin/stat.h index a21e731..d35e1ed 100644 --- a/winsup/cygwin/include/cygwin/stat.h +++ b/winsup/cygwin/include/cygwin/stat.h @@ -19,9 +19,9 @@ extern "C" { #ifdef __INSIDE_CYGWIN__ struct __stat32 { - __dev16_t st_dev; - ino_t st_ino; - mode_t st_mode; + __dev16_t st_dev; + __ino32_t st_ino; + mode_t st_mode; nlink_t st_nlink; __uid16_t st_uid; __gid16_t st_gid; @@ -38,7 +38,7 @@ struct __stat32 struct __stat64 { __dev32_t st_dev; - ino_t st_ino; + __ino64_t st_ino; mode_t st_mode; nlink_t st_nlink; __uid32_t st_uid; diff --git a/winsup/cygwin/include/cygwin/types.h b/winsup/cygwin/include/cygwin/types.h index 8a26ef0..0afa285 100644 --- a/winsup/cygwin/include/cygwin/types.h +++ b/winsup/cygwin/include/cygwin/types.h @@ -90,9 +90,20 @@ typedef __gid16_t gid_t; #ifndef __ino_t_defined #define __ino_t_defined -typedef unsigned long ino_t; +typedef unsigned long __ino32_t; +typedef unsigned long long __ino64_t; +#ifdef __CYGWIN_USE_BIG_TYPES__ +typedef __ino64_t ino_t; +#else +typedef __ino32_t ino_t; +#endif #endif /*__ino_t_defined*/ +#ifndef __key_t_defined +#define __key_t_defined +typedef long key_t; +#endif /* __key_t_defined */ + #ifndef __BIT_TYPES_DEFINED #define __BIT_TYPES_DEFINED__ 1 diff --git a/winsup/cygwin/ipc.cc b/winsup/cygwin/ipc.cc index 5387915..d37f459 100644 --- a/winsup/cygwin/ipc.cc +++ b/winsup/cygwin/ipc.cc @@ -1,8 +1,9 @@ /* ipc.cc: Single unix specification IPC interface for Cygwin - Copyright 2001, 2002 Red Hat, Inc. + Copyright 2001, 2002, 2003 Red Hat, Inc. Originally written by Robert Collins <robert.collins@hotmail.com> + Updated to 64 bit key_t by Charles Wilson <cygwin@cwilson.fastmail.fm> This file is part of Cygwin. @@ -14,26 +15,78 @@ #include <cygwin/ipc.h> #include <sys/stat.h> -extern "C" -{ - /* Notes: we return a valid key even if id's low order 8 bits are 0. */ -key_t +extern "C" key_t ftok (const char *path, int id) { - struct stat statbuf; - if (stat (path, &statbuf)) + struct __stat64 statbuf; + key_t tmp; + if (stat64 (path, &statbuf)) { /* stat set the appropriate errno for us */ return (key_t) -1; } - /* dev_t is short for cygwin - * ino_t is long for cygwin - * and we need 8 bits for the id. - * thus key_t is long long. - */ - return ((long long) statbuf.st_dev << (5*8)) | (statbuf.st_ino << (8) ) | (id & 0x00ff); -} + /* Since __CYGWIN_USE_BIG_TYPES__, + dev_t is 32bits for cygwin + ino_t is 64bits for cygwin + and we need 8 bits for the id. + thus key_t needs 104 bits total -- but we only have 64 (long long) + We will have to alias; leaving open the possibility that the same + key will be returned for multiple files. This possibility exists + also on Linux; the question is, how to minimize this possibility. + + How to solve? Well, based on C. Vinschen's research, the nFileIndex* + words vary as follows, on a partition with > 110,000 files + nFileIndexHigh: 564 values between 0x00010000 -- 0xffff0000 + nFileIndexLow : 103812 values between 0x00000000 -- 0x0003ffff + R. Collins suggests that these may represent a tree path, + and that it would require ~2.9M files to force the tree depth + to increase and reveal more bit usage. + + Implementation details: dev_t is 32bits, but is formed by + device(32bits) << 16 | unit(32bits) + But device is ACTUALLY == status & FH_DEVMASK, where FH_DEVMASK + is 0x00000fff --> 12 bits + + As it happens, the maximum number of devices is actually + FH_NDEV, not FH_DEVMASK, where FH_NDEV is currently 0x0000001d. + However, FH_NDEV grows as new device types are added. So + currently the device number needs 5 bits, but later? Let's + take a cue from Linux, and use the lower 8 bits (instead of the + lower 12 or 16) for the device (major?) number. + + Similarly, while 'units' is an int (32bits), it is unclear + how many of these are significant. For most devices, it seems that + 'units' is equivalent to 'minor'. For FH_TAPE, it's obvious that + only 8 bits are important. However, for FH_SOCKET...it might be + as high as 16 significant bits. + + Let's assume that we only need 8 bits from device (major) and + only 8 bits from unit (minor). (On linux, only 8 bits of minor + are used, and none from major). + ---> so, we only need 0x00ff00ff (16 bits) of dev_t + + ---> we MUST have all 8 bits of id. + + ---> So, we only have 64 - 8 - 16 = 40 bits for ino_t. But, we + need 0xffff0000 for nFileIndexHigh and 0x0003ffff for nFileIndexLow + minimum, or 16 + 18 = 34 bits. Lucky us - we have 6 more bits + to distribute. + + For lack of a better idea, we'll allocate 2 of the extra bits to + nFileIndexHigh and 4 to nFileIndexLow. */ + /* get 8 bits from dev_t (major), put into 0xff00000000000000L */ + tmp = (((key_t) statbuf.st_dev) & 0x0000000000ff0000LL) << 40; + /* get 8 bits from dev_t (minor), put into 0x00ff000000000000L */ + tmp |= (((key_t) statbuf.st_dev) & 0x00000000000000ffLL) << 48; + /* get upper 16+2 bits from nFileInfoHigh, put into 0x0000ffffc0000000L + shift down first, then mask, to avoid sign extension on rightshift */ + tmp |= (((key_t) statbuf.st_ino) & 0xffffc00000000000LL) >> 16; + /* get lower 18+4 bits from nFileInfoLow, put into 0x000000003fffff00L */ + tmp |= (((key_t) statbuf.st_ino) & 0x00000000003fffffLL) << 8; + /* use all 8 bits of id, and put into 0x00000000000000ffL */ + tmp |= (id & 0x00ff); + return tmp; } diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 3d4131f..df30ce9 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -3011,8 +3011,8 @@ readlink (const char *path, char *buf, int buflen) the directory. FIXME: Not bullet-proof. */ /* Cygwin internal */ -unsigned long __stdcall -hash_path_name (ino_t hash, const char *name) +__ino64_t __stdcall +hash_path_name (__ino64_t hash, const char *name) { if (!*name) return hash; diff --git a/winsup/cygwin/shared.cc b/winsup/cygwin/shared.cc index 8eb5444..7ab3d19 100644 --- a/winsup/cygwin/shared.cc +++ b/winsup/cygwin/shared.cc @@ -33,15 +33,16 @@ mount_info NO_COPY *mount_table; HANDLE NO_COPY cygwin_mount_h; char * __stdcall -shared_name (const char *str, int num) +shared_name (char *ret_buf, const char *str, int num) { - static NO_COPY char buf[MAX_PATH] = {0}; extern bool _cygwin_testing; - __small_sprintf (buf, "%s.%s.%d", cygwin_version.shared_id, str, num); + __small_sprintf (ret_buf, "%s%s.%s.%d", + wincap.has_terminal_services () ? "Global\\" : "", + cygwin_version.shared_id, str, num); if (_cygwin_testing) - strcat (buf, cygwin_version.dll_build_date); - return buf; + strcat (ret_buf, cygwin_version.dll_build_date); + return ret_buf; } #define page_const (65535) @@ -86,11 +87,12 @@ open_shared (const char *name, int n, HANDLE &shared_h, DWORD size, shared_locat if (!shared_h) { char *mapname; + char map_buf[MAX_PATH]; if (!name) mapname = NULL; else { - mapname = shared_name (name, n); + mapname = shared_name (map_buf, name, n); shared_h = OpenFileMappingA (FILE_MAP_READ | FILE_MAP_WRITE, TRUE, mapname); } diff --git a/winsup/cygwin/shared_info.h b/winsup/cygwin/shared_info.h index 77e57a2..4f137d6 100644 --- a/winsup/cygwin/shared_info.h +++ b/winsup/cygwin/shared_info.h @@ -187,5 +187,5 @@ struct console_state }; #endif -char *__stdcall shared_name (const char *, int); +char *__stdcall shared_name (char *, const char *, int); void *__stdcall open_shared (const char *name, int n, HANDLE &shared_h, DWORD size, shared_locations); diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index e3795a0..dafaad8 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -883,6 +883,7 @@ static HANDLE __stdcall getsem (_pinfo *p, const char *str, int init, int max) { HANDLE h; + char sem_name[MAX_PATH]; if (p != NULL) { @@ -906,7 +907,7 @@ getsem (_pinfo *p, const char *str, int init, int max) DWORD winpid = GetCurrentProcessId (); h = CreateSemaphore (sec_user_nih (sa_buf), init, max, - str = shared_name (str, winpid)); + str = shared_name (sem_name, str, winpid)); p = myself; if (!h) { @@ -917,7 +918,7 @@ getsem (_pinfo *p, const char *str, int init, int max) else { h = OpenSemaphore (SEMAPHORE_ALL_ACCESS, FALSE, - shared_name (str, p->dwProcessId)); + shared_name (sem_name, str, p->dwProcessId)); if (!h) { diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index d9e7fbf..afa54d0 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -341,7 +341,7 @@ spawn_guts (const char * prog_arg, const char *const *argv, return -1; } - syscall_printf ("spawn_guts (%d, %.132s)", mode, prog_arg); + syscall_printf ("spawn_guts (%d, %.9500s)", mode, prog_arg); if (argv == NULL) { @@ -613,7 +613,7 @@ spawn_guts (const char * prog_arg, const char *const *argv, const char *runpath = null_app_name ? NULL : (const char *) real_path; - syscall_printf ("null_app_name %d (%s, %.132s)", null_app_name, runpath, one_line.buf); + syscall_printf ("null_app_name %d (%s, %.9500s)", null_app_name, runpath, one_line.buf); void *newheap; /* Preallocated buffer for `sec_user' call */ @@ -727,7 +727,7 @@ spawn_guts (const char * prog_arg, const char *const *argv, cygpid = myself->pid; /* We print the original program name here so the user can see that too. */ - syscall_printf ("%d = spawn_guts (%s, %.132s)", + syscall_printf ("%d = spawn_guts (%s, %.9500s)", rc ? cygpid : (unsigned int) -1, prog_arg, one_line.buf); /* Name the handle similarly to proc_subproc. */ diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 96b0c2a..5625f1a 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -1014,7 +1014,7 @@ static void stat64_to_stat32 (struct __stat64 *src, struct __stat32 *dst) { dst->st_dev = ((src->st_dev >> 8) & 0xff00) | (src->st_dev & 0xff); - dst->st_ino = src->st_ino; + dst->st_ino = ((unsigned) (src->st_ino >> 32)) | (unsigned) src->st_ino; dst->st_mode = src->st_mode; dst->st_nlink = src->st_nlink; dst->st_uid = src->st_uid; @@ -1056,8 +1056,16 @@ fstat64 (int fd, struct __stat64 *buf) return res; } -extern "C" int _fstat64 (int fd, _off64_t pos, int dir) - __attribute__ ((alias ("fstat64"))); +extern "C" int +_fstat64_r (struct _reent *ptr, int fd, struct __stat64 *buf) +{ + int ret; + + set_errno (0); + if ((ret = fstat64 (fd, buf)) == -1 && get_errno () != 0) + ptr->_errno = get_errno (); + return ret; +} extern "C" int fstat (int fd, struct __stat32 *buf) @@ -1069,8 +1077,16 @@ fstat (int fd, struct __stat32 *buf) return ret; } -extern "C" int _fstat (int fd, _off64_t pos, int dir) - __attribute__ ((alias ("fstat"))); +extern "C" int +_fstat_r (struct _reent *ptr, int fd, struct __stat32 *buf) +{ + int ret; + + set_errno (0); + if ((ret = fstat (fd, buf)) == -1 && get_errno () != 0) + ptr->_errno = get_errno (); + return ret; +} /* fsync: P96 6.6.1.1 */ extern "C" int @@ -1149,9 +1165,6 @@ stat_worker (const char *name, struct __stat64 *buf, int nofollow) return res; } -extern "C" int _stat (int fd, _off64_t pos, int dir) - __attribute__ ((alias ("stat"))); - extern "C" int stat64 (const char *name, struct __stat64 *buf) { @@ -1161,6 +1174,17 @@ stat64 (const char *name, struct __stat64 *buf) } extern "C" int +_stat64_r (struct _reent *ptr, const char *name, struct __stat64 *buf) +{ + int ret; + + set_errno (0); + if ((ret = stat64 (name, buf)) == -1 && get_errno () != 0) + ptr->_errno = get_errno (); + return ret; +} + +extern "C" int stat (const char *name, struct __stat32 *buf) { struct __stat64 buf64; @@ -1170,6 +1194,17 @@ stat (const char *name, struct __stat32 *buf) return ret; } +extern "C" int +_stat_r (struct _reent *ptr, const char *name, struct __stat32 *buf) +{ + int ret; + + set_errno (0); + if ((ret = stat (name, buf)) == -1 && get_errno () != 0) + ptr->_errno = get_errno (); + return ret; +} + /* lstat: Provided by SVR4 and 4.3+BSD, POSIX? */ extern "C" int lstat64 (const char *name, struct __stat64 *buf) @@ -1862,7 +1897,12 @@ statfs (const char *fname, struct statfs *sfs) syscall_printf ("statfs %s", root); - DWORD spc, bps, freec, totalc; + /* GetDiskFreeSpaceEx must be called before GetDiskFreeSpace on + WinME, to avoid the MS KB 314417 bug */ + ULARGE_INTEGER availb, freeb, totalb; + BOOL status = GetDiskFreeSpaceEx (root, &availb, &totalb, &freeb); + + DWORD spc, bps, availc, freec, totalc; if (!GetDiskFreeSpace (root, &spc, &bps, &freec, &totalc)) { @@ -1870,6 +1910,15 @@ statfs (const char *fname, struct statfs *sfs) return -1; } + if (status) + { + availc = availb.QuadPart / (spc*bps); + totalc = totalb.QuadPart / (spc*bps); + freec = freeb.QuadPart / (spc*bps); + } + else + availc = freec; + DWORD vsn, maxlen, flags; if (!GetVolumeInformation (root, NULL, 0, &vsn, &maxlen, &flags, NULL, 0)) @@ -1880,7 +1929,8 @@ statfs (const char *fname, struct statfs *sfs) sfs->f_type = flags; sfs->f_bsize = spc*bps; sfs->f_blocks = totalc; - sfs->f_bfree = sfs->f_bavail = freec; + sfs->f_bavail = availc; + sfs->f_bfree = freec; sfs->f_files = -1; sfs->f_ffree = -1; sfs->f_fsid = vsn; @@ -2571,7 +2621,9 @@ login (struct utmp *ut) pututline (ut); endutent (); /* Writing to wtmp must be atomic to prevent mixed up data. */ - HANDLE mutex = CreateMutex (NULL, FALSE, shared_name ("wtmp_mutex", 0)); + char mutex_name[MAX_PATH]; + HANDLE mutex = CreateMutex (NULL, FALSE, + shared_name (mutex_name, "wtmp_mutex", 0)); if (mutex) while (WaitForSingleObject (mutex, INFINITE) == WAIT_ABANDONED) ; @@ -2609,7 +2661,9 @@ logout (char *line) memset (ut_buf.ut_user, 0, sizeof ut_buf.ut_user); time (&ut_buf.ut_time); /* Writing to wtmp must be atomic to prevent mixed up data. */ - HANDLE mutex = CreateMutex (NULL, FALSE, shared_name ("wtmp_mutex", 0)); + char mutex_name[MAX_PATH]; + HANDLE mutex = CreateMutex (NULL, FALSE, + shared_name (mutex_name, "wtmp_mutex", 0)); if (mutex) while (WaitForSingleObject (mutex, INFINITE) == WAIT_ABANDONED) ; @@ -2778,7 +2832,9 @@ pututline (struct utmp *ut) return; /* Read/write to utmp must be atomic to prevent overriding data by concurrent processes. */ - HANDLE mutex = CreateMutex (NULL, FALSE, shared_name ("utmp_mutex", 0)); + char mutex_name[MAX_PATH]; + HANDLE mutex = CreateMutex (NULL, FALSE, + shared_name (mutex_name, "utmp_mutex", 0)); if (mutex) while (WaitForSingleObject (mutex, INFINITE) == WAIT_ABANDONED) ; diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index de5392f..0321ea4 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -188,14 +188,12 @@ ResourceLocks::Delete () } void -MTinterface::Init (int forked) +MTinterface::Init () { reents._clib = _impure_ptr; reents._winsup = &winsup_reent; winsup_reent._process_logmask = LOG_UPTO (LOG_DEBUG); - - if (!forked) - reent_key.set (&reents); + reent_key.set (&reents); pthread_mutex::init_mutex (); pthread_cond::init_mutex (); @@ -215,7 +213,7 @@ MTinterface::fixup_after_fork (void) pthread_key::fixup_after_fork (); threadcount = 1; - pthread::init_mainthread (true); + pthread::init_mainthread (); pthread_mutex::fixup_after_fork (); pthread_cond::fixup_after_fork (); @@ -227,11 +225,8 @@ MTinterface::fixup_after_fork (void) /* static methods */ void -pthread::init_mainthread (bool do_init) +pthread::init_mainthread () { - if (!do_init) - return; - pthread *thread = get_tls_self_pointer (); if (!thread) { diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h index e162b32..55d9415 100644 --- a/winsup/cygwin/thread.h +++ b/winsup/cygwin/thread.h @@ -401,7 +401,7 @@ public: pthread (); virtual ~pthread (); - static void init_mainthread (bool); + static void init_mainthread (); static bool is_good_object(pthread_t const *); static void atforkprepare(); static void atforkparent(); @@ -679,7 +679,7 @@ public: pthread_key reent_key; pthread_key thread_self_key; - void Init (int); + void Init (); void fixup_before_fork (void); void fixup_after_fork (void); diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc index b5385f2..37ec6ef 100644 --- a/winsup/cygwin/wincap.cc +++ b/winsup/cygwin/wincap.cc @@ -48,7 +48,8 @@ static NO_COPY wincaps wincap_unknown = { has_process_io_counters:false, supports_reading_modem_output_lines:false, needs_memory_protection:false, - pty_needs_alloc_console:false + pty_needs_alloc_console:false, + has_terminal_services:false }; static NO_COPY wincaps wincap_95 = { @@ -88,7 +89,8 @@ static NO_COPY wincaps wincap_95 = { has_process_io_counters:false, supports_reading_modem_output_lines:false, needs_memory_protection:false, - pty_needs_alloc_console:false + pty_needs_alloc_console:false, + has_terminal_services:false }; static NO_COPY wincaps wincap_95osr2 = { @@ -128,7 +130,8 @@ static NO_COPY wincaps wincap_95osr2 = { has_process_io_counters:false, supports_reading_modem_output_lines:false, needs_memory_protection:false, - pty_needs_alloc_console:false + pty_needs_alloc_console:false, + has_terminal_services:false }; static NO_COPY wincaps wincap_98 = { @@ -168,7 +171,8 @@ static NO_COPY wincaps wincap_98 = { has_process_io_counters:false, supports_reading_modem_output_lines:false, needs_memory_protection:false, - pty_needs_alloc_console:false + pty_needs_alloc_console:false, + has_terminal_services:false }; static NO_COPY wincaps wincap_98se = { @@ -208,7 +212,8 @@ static NO_COPY wincaps wincap_98se = { has_process_io_counters:false, supports_reading_modem_output_lines:false, needs_memory_protection:false, - pty_needs_alloc_console:false + pty_needs_alloc_console:false, + has_terminal_services:false }; static NO_COPY wincaps wincap_me = { @@ -248,7 +253,8 @@ static NO_COPY wincaps wincap_me = { has_process_io_counters:false, supports_reading_modem_output_lines:false, needs_memory_protection:false, - pty_needs_alloc_console:false + pty_needs_alloc_console:false, + has_terminal_services:false }; static NO_COPY wincaps wincap_nt3 = { @@ -288,7 +294,8 @@ static NO_COPY wincaps wincap_nt3 = { has_process_io_counters:false, supports_reading_modem_output_lines:true, needs_memory_protection:true, - pty_needs_alloc_console:true + pty_needs_alloc_console:true, + has_terminal_services:false }; static NO_COPY wincaps wincap_nt4 = { @@ -328,7 +335,8 @@ static NO_COPY wincaps wincap_nt4 = { has_process_io_counters:false, supports_reading_modem_output_lines:true, needs_memory_protection:true, - pty_needs_alloc_console:true + pty_needs_alloc_console:true, + has_terminal_services:false }; static NO_COPY wincaps wincap_nt4sp4 = { @@ -368,7 +376,8 @@ static NO_COPY wincaps wincap_nt4sp4 = { has_process_io_counters:false, supports_reading_modem_output_lines:true, needs_memory_protection:true, - pty_needs_alloc_console:true + pty_needs_alloc_console:true, + has_terminal_services:false }; static NO_COPY wincaps wincap_2000 = { @@ -408,7 +417,8 @@ static NO_COPY wincaps wincap_2000 = { has_process_io_counters:true, supports_reading_modem_output_lines:true, needs_memory_protection:true, - pty_needs_alloc_console:true + pty_needs_alloc_console:true, + has_terminal_services:true }; static NO_COPY wincaps wincap_xp = { @@ -448,7 +458,49 @@ static NO_COPY wincaps wincap_xp = { has_process_io_counters:true, supports_reading_modem_output_lines:true, needs_memory_protection:true, - pty_needs_alloc_console:true + pty_needs_alloc_console:true, + has_terminal_services:true +}; + +static NO_COPY wincaps wincap_2003 = { + lock_file_highword:0xffffffff, + chunksize:0, + shared:FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + is_winnt:true, + access_denied_on_delete:false, + has_delete_on_close:true, + has_page_guard:true, + has_security:true, + has_security_descriptor_control:true, + has_get_process_times:true, + has_lseek_bug:false, + has_lock_file_ex:true, + has_signal_object_and_wait:true, + has_eventlog:true, + has_ip_helper_lib:true, + has_set_handle_information:true, + has_set_handle_information_on_console_handles:true, + supports_smp:true, + map_view_of_file_ex_sucks:false, + altgr_is_ctrl_alt:true, + has_physical_mem_access:true, + has_working_copy_on_write:true, + share_mmaps_only_by_name:false, + virtual_protect_works_on_shared_pages:true, + has_hard_links:true, + can_open_directories:true, + has_move_file_ex:true, + has_negative_pids:false, + has_unreliable_pipes:false, + has_try_enter_critical_section:true, + has_raw_devices:true, + has_valid_processorlevel:true, + has_64bit_file_access:true, + has_process_io_counters:true, + supports_reading_modem_output_lines:true, + needs_memory_protection:true, + pty_needs_alloc_console:true, + has_terminal_services:true }; wincapc wincap; @@ -483,10 +535,19 @@ wincapc::init () break; case 5: os = "NT"; - if (version.dwMinorVersion == 0) - caps = &wincap_2000; - else - caps = &wincap_xp; + switch (version.dwMinorVersion) + { + case 0: + caps = &wincap_2000; + break; + + case 1: + caps = &wincap_xp; + break; + + default: + caps = &wincap_2003; + } break; default: os = "??"; diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h index 066374f..b1f43d6 100644 --- a/winsup/cygwin/wincap.h +++ b/winsup/cygwin/wincap.h @@ -50,6 +50,7 @@ struct wincaps unsigned supports_reading_modem_output_lines : 1; unsigned needs_memory_protection : 1; unsigned pty_needs_alloc_console : 1; + unsigned has_terminal_services : 1; }; class wincapc @@ -104,6 +105,7 @@ public: bool IMPLEMENT (supports_reading_modem_output_lines) bool IMPLEMENT (needs_memory_protection) bool IMPLEMENT (pty_needs_alloc_console) + bool IMPLEMENT (has_terminal_services) #undef IMPLEMENT }; diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h index 17ac895..092f502 100644 --- a/winsup/cygwin/winsup.h +++ b/winsup/cygwin/winsup.h @@ -24,6 +24,7 @@ details. */ #endif #define NO_COPY __attribute__((nocommon)) __attribute__((section(".data_cygwin_nocopy"))) +#define NO_COPY_INIT __attribute__((section(".data_cygwin_nocopy"))) #if !defined(__STDC_VERSION__) || __STDC_VERSION__ >= 199900L #define NEW_MACRO_VARARGS @@ -198,7 +199,7 @@ int __stdcall writable_directory (const char *file); int __stdcall stat_dev (DWORD, int, unsigned long, struct __stat64 *); extern BOOL allow_ntsec; -unsigned long __stdcall hash_path_name (ino_t hash, const char *name) __attribute__ ((regparm(2))); +__ino64_t __stdcall hash_path_name (__ino64_t hash, const char *name) __attribute__ ((regparm(2))); void __stdcall nofinalslash (const char *src, char *dst) __attribute__ ((regparm(2))); extern "C" char *__stdcall rootdir (char *full_path) __attribute__ ((regparm(1))); |