From ba94682838272afc87b73833c02aaf6cea40815e Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 12 Sep 2001 17:46:37 +0000 Subject: [PATCH] * Makefile.in: Build wincap.o. * wincap.cc: New file. * wincap.h: Ditto. * autoload.cc: Add dynamic load statement for `CreateHardLinkA'. * dcrt0.cc (os_being_run): Eliminated. (osname): Ditto. (iswinnt): Ditto. (set_os_type): Ditto. (dll_crt0_1): Call wincap.init() instead of set_os_type(). (_dll_crt0): Ditto. * environ.cc (set_chunksize): New function. (parse_thing): `forkchunk' setting now invokes function `set_chunksize'. * fork.cc (chunksize): Eliminated. Moved to be member of wincap. * host_dependent.h: Removed. * syscalls.cc (_link): Try using `CreateHardLinkA' first, if available. * cygheap.cc, dcrt0.cc, delqueue.cc, dir.cc, environ.cc, fhandler.cc, fhandler.h, fhandler_console.cc, fhandler_mem.cc, fork.cc, mmap.cc, net.cc, pinfo.cc, pinfo.h, security.cc, syscalls.cc, sysconf.cc, syslog.cc, thread.cc, times.cc, tty.cc, uinfo.cc, uname.cc, winsup.h: Use new wincap capability check throughout. * winsup.h: Include wincap.h. Eliminate extern declarations of `os_being_run' and `iswinnt'. Eliminate `os_type" definition. * include/cygwin/version.h: Bump version to 1.3.4. --- winsup/cygwin/ChangeLog | 27 ++ winsup/cygwin/Makefile.in | 2 +- winsup/cygwin/autoload.cc | 1 + winsup/cygwin/cygheap.cc | 2 +- winsup/cygwin/dcrt0.cc | 100 +----- winsup/cygwin/delqueue.cc | 3 +- winsup/cygwin/dir.cc | 2 +- winsup/cygwin/environ.cc | 11 +- winsup/cygwin/fhandler.cc | 9 +- winsup/cygwin/fhandler.h | 2 +- winsup/cygwin/fhandler_console.cc | 2 +- winsup/cygwin/fhandler_mem.cc | 6 +- winsup/cygwin/fork.cc | 3 +- winsup/cygwin/host_dependent.h | 30 -- winsup/cygwin/include/cygwin/version.h | 4 +- winsup/cygwin/mmap.cc | 17 +- winsup/cygwin/net.cc | 26 +- winsup/cygwin/pinfo.cc | 5 +- winsup/cygwin/pinfo.h | 2 +- winsup/cygwin/security.cc | 16 +- winsup/cygwin/syscalls.cc | 25 +- winsup/cygwin/sysconf.cc | 56 +-- winsup/cygwin/syslog.cc | 8 +- winsup/cygwin/thread.cc | 14 +- winsup/cygwin/times.cc | 5 +- winsup/cygwin/tty.cc | 2 +- winsup/cygwin/uinfo.cc | 2 +- winsup/cygwin/uname.cc | 3 +- winsup/cygwin/wincap.cc | 462 +++++++++++++++++++++++++ winsup/cygwin/wincap.h | 99 ++++++ winsup/cygwin/winsup.h | 7 +- 31 files changed, 707 insertions(+), 246 deletions(-) delete mode 100644 winsup/cygwin/host_dependent.h create mode 100644 winsup/cygwin/wincap.cc create mode 100644 winsup/cygwin/wincap.h diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index ee21390be..bac1fd100 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,30 @@ +Wed Sep 12 19:00:00 2001 Corinna Vinschen + + * Makefile.in: Build wincap.o. + * wincap.cc: New file. + * wincap.h: Ditto. + * autoload.cc: Add dynamic load statement for `CreateHardLinkA'. + * dcrt0.cc (os_being_run): Eliminated. + (osname): Ditto. + (iswinnt): Ditto. + (set_os_type): Ditto. + (dll_crt0_1): Call wincap.init() instead of set_os_type(). + (_dll_crt0): Ditto. + * environ.cc (set_chunksize): New function. + (parse_thing): `forkchunk' setting now invokes function `set_chunksize'. + * fork.cc (chunksize): Eliminated. Moved to be member of wincap. + * host_dependent.h: Removed. + * syscalls.cc (_link): Try using `CreateHardLinkA' first, if available. + * cygheap.cc, dcrt0.cc, delqueue.cc, dir.cc, + environ.cc, fhandler.cc, fhandler.h, fhandler_console.cc, + fhandler_mem.cc, fork.cc, mmap.cc, net.cc, pinfo.cc, pinfo.h, + security.cc, syscalls.cc, sysconf.cc, syslog.cc, thread.cc, + times.cc, tty.cc, uinfo.cc, uname.cc, winsup.h: Use new wincap + capability check throughout. + * winsup.h: Include wincap.h. Eliminate extern declarations of + `os_being_run' and `iswinnt'. Eliminate `os_type" definition. + * include/cygwin/version.h: Bump version to 1.3.4. + Wed Sep 12 01:03:36 2001 Christopher Faylor * exceptions.cc (call_signal_handler_now): Add additional guard against diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index baa36b441..b9283a2d5 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -128,7 +128,7 @@ DLL_OFILES:=assert.o autoload.o cygheap.o dcrt0.o debug.o delqueue.o dir.o \ sched.o sec_acl.o sec_helper.o security.o select.o shared.o shortcut.o signal.o sigproc.o \ smallprint.o spawn.o strace.o strsep.o sync.o syscalls.o sysconf.o \ syslog.o termios.o thread.o times.o tty.o uinfo.o uname.o wait.o \ - window.o \ + wincap.o window.o \ $(EXTRA_DLL_OFILES) $(EXTRA_OFILES) $(MALLOC_OFILES) $(MT_SAFE_OBJECTS) GMON_OFILES:= gmon.o mcount.o profil.o diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index 253b56ede..d1cbd59cc 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -478,6 +478,7 @@ LoadDLLfuncEx (CancelIo, 4, kernel32, 1) LoadDLLfuncEx (Process32First, 8, kernel32, 1) LoadDLLfuncEx (Process32Next, 8, kernel32, 1) LoadDLLfuncEx (CreateToolhelp32Snapshot, 8, kernel32, 1) +LoadDLLfuncEx (CreateHardLinkA, 12, kernel32, 1) LoadDLLfunc (TryEnterCriticalSection, 4, kernel32) LoadDLLfuncEx (waveOutGetNumDevs, 0, winmm, 1) diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc index c6ea68419..42127eeff 100644 --- a/winsup/cygwin/cygheap.cc +++ b/winsup/cygwin/cygheap.cc @@ -96,7 +96,7 @@ cygheap_fixup_in_child (child_info *ci, bool execed) { cygheap = ci->cygheap; cygheap_max = ci->cygheap_max; - void *addr = iswinnt ? cygheap : NULL; + void *addr = !wincap.map_view_of_file_ex_sucks () ? cygheap : NULL; void *newaddr; newaddr = MapViewOfFileEx (ci->cygheap_h, MVMAP_OPTIONS, 0, 0, 0, addr); diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index ef0338651..8f43878b1 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -34,7 +34,6 @@ details. */ #include "shared_info.h" #include "cygwin_version.h" #include "dll_init.h" -#include "host_dependent.h" #define MAX_AT_FILE_LEVEL 10 @@ -155,94 +154,6 @@ do_global_ctors (void (**in_pfunc)(), int force) atexit (do_global_dtors); } -/* remember the type of Win32 OS being run for future use. */ -os_type NO_COPY os_being_run; -char NO_COPY osname[40]; -bool iswinnt; - -/* set_os_type: Set global variable os_being_run with type of Win32 - operating system being run. This information is used internally - to manage the inconsistency in Win32 API calls between Win32 OSes. */ -/* Cygwin internal */ -static void -set_os_type () -{ - OSVERSIONINFO os_version_info; - const char *os; - - memset (&os_version_info, 0, sizeof os_version_info); - os_version_info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); - GetVersionEx (&os_version_info); - - iswinnt = 0; - switch (os_version_info.dwPlatformId) - { - case VER_PLATFORM_WIN32_NT: - os_being_run = winNT; - os = "NT"; - iswinnt = 1; - break; - case VER_PLATFORM_WIN32_WINDOWS: - if (os_version_info.dwMinorVersion == 0) - { - os_being_run = win95; - os = "95"; - } - else if (os_version_info.dwMinorVersion < 90) - { - os_being_run = win98; - os = "98"; - } - else /* os_version_info.dwMinorVersion == 90 */ - { - os_being_run = winME; - os = "ME"; - } - break; - default: - os_being_run = unknown; - os = "??"; - break; - } - __small_sprintf (osname, "%s-%d.%d", os, os_version_info.dwMajorVersion, - os_version_info.dwMinorVersion); -} - -host_dependent_constants NO_COPY host_dependent; - -/* Constructor for host_dependent_constants. */ - -void -host_dependent_constants::init () -{ - extern DWORD chunksize; - /* fhandler_disk_file::lock needs a platform specific upper word - value for locking entire files. - - fhandler_base::open requires host dependent file sharing - attributes. */ - - switch (os_being_run) - { - case winNT: - win32_upper = 0xffffffff; - shared = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; - break; - - case winME: - case win98: - case win95: - case win32s: - win32_upper = 0x00000000; - shared = FILE_SHARE_READ | FILE_SHARE_WRITE; - chunksize = 32 * 1024 * 1024; - break; - - default: - api_fatal ("unrecognized system type"); - } -} - /* * Replaces -@file in the command line with the contents of the file. * There may be multiple -@file's in a single command line @@ -544,7 +455,7 @@ static NO_COPY STARTUPINFO si; child_info_fork NO_COPY *child_proc_info = NULL; static MEMORY_BASIC_INFORMATION sm; -#define CYGWIN_GUARD ((iswinnt) ? PAGE_GUARD : PAGE_NOACCESS) +#define CYGWIN_GUARD ((wincap.has_page_guard ()) ? PAGE_GUARD : PAGE_NOACCESS) // __inline__ void extern void @@ -649,7 +560,7 @@ dll_crt0_1 () do_global_ctors (&__CTOR_LIST__, 1); /* Set the os_being_run global. */ - set_os_type (); + wincap.init (); check_sanity_and_sync (user_data); /* Nasty static stuff needed by newlib -- point to a local copy of @@ -722,9 +633,6 @@ dll_crt0_1 () ProtectHandle (hMainProc); ProtectHandle (hMainThread); - /* Initialize the host dependent constants object. */ - host_dependent.init (); - /* Initialize the cygwin subsystem if this is the first process, or attach to shared data structures if it's already running. */ memory_init (); @@ -888,8 +796,8 @@ _dll_crt0 () strace.microseconds (); #endif - /* Set the os_being_run global. */ - set_os_type (); + /* Set the os capabilities. */ + wincap.init (); main_environ = user_data->envptr; *main_environ = NULL; diff --git a/winsup/cygwin/delqueue.cc b/winsup/cygwin/delqueue.cc index 7cd7389a8..b7314eab2 100644 --- a/winsup/cygwin/delqueue.cc +++ b/winsup/cygwin/delqueue.cc @@ -87,7 +87,8 @@ delqueue_list::process_queue () int res = GetLastError (); empty = 0; if (res == ERROR_SHARING_VIOLATION || - (!iswinnt && res == ERROR_ACCESS_DENIED)) + (wincap.access_denied_on_delete () + && res == ERROR_ACCESS_DENIED)) { /* File still inuse, that's ok */ syscall_printf ("Still using %s", name[i]); diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc index 1e752606c..ab2bfab64 100644 --- a/winsup/cygwin/dir.cc +++ b/winsup/cygwin/dir.cc @@ -405,7 +405,7 @@ rmdir (const char *dir) { /* On 9X ERROR_ACCESS_DENIED is returned if you try to remove a non-empty directory. */ - if (!iswinnt) + if (wincap.access_denied_on_delete ()) set_errno (ENOTEMPTY); else __seterrno (); diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc index cc127ad29..1be0b79b5 100644 --- a/winsup/cygwin/environ.cc +++ b/winsup/cygwin/environ.cc @@ -35,7 +35,6 @@ extern BOOL allow_smbntsec; extern BOOL allow_winsymlinks; extern BOOL strip_title_path; extern int pcheck_case; -extern DWORD chunksize; extern int subauth_id; BOOL reset_com = TRUE; static BOOL envcache = TRUE; @@ -474,6 +473,12 @@ subauth_id_init (const char *buf) subauth_id = i; } +static void +set_chunksize (const char *buf) +{ + wincap.set_chunksize (strtol (buf, NULL, 0)); +} + /* The structure below is used to set up an array which is used to parse the CYGWIN environment variable or, if enabled, options from the registry. */ @@ -503,7 +508,7 @@ static struct parse_thing {"envcache", {&envcache}, justset, NULL, {{TRUE}, {FALSE}}}, {"error_start", {func: &error_start_init}, isfunc, NULL, {{0}, {0}}}, {"export", {&export_settings}, justset, NULL, {{FALSE}, {TRUE}}}, - {"forkchunk", {x: &chunksize}, justset, NULL, {{8192}, {0}}}, + {"forkchunk", {func: set_chunksize}, isfunc, NULL, {{0}, {0}}}, {"glob", {func: &glob_init}, isfunc, NULL, {{0}, {s: "normal"}}}, {"ntea", {&allow_ntea}, justset, NULL, {{FALSE}, {TRUE}}}, {"ntsec", {&allow_ntsec}, justset, NULL, {{FALSE}, {TRUE}}}, @@ -658,7 +663,7 @@ environ_init (char **envp, int envc) #ifdef NTSEC_ON_BY_DEFAULT /* Set ntsec explicit as default, if NT is running */ - if (iswinnt) + if (wincap.has_security ()) allow_ntsec = TRUE; #endif diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index e8902562f..270c0d319 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -24,7 +24,6 @@ details. */ #include "cygheap.h" #include "path.h" #include "shared_info.h" -#include "host_dependent.h" static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */ @@ -364,7 +363,7 @@ fhandler_base::open (int flags, mode_t mode) set_append_p(); /* These flags are host dependent. */ - shared = host_dependent.shared; + shared = wincap.shared (); file_attributes = FILE_ATTRIBUTE_NORMAL; if (flags & O_DIROPEN) @@ -579,7 +578,7 @@ fhandler_base::write (const void *ptr, size_t len) if (get_append_p ()) SetFilePointer (get_handle(), 0, 0, FILE_END); - else if (!iswinnt && get_check_win95_lseek_bug ()) + else if (wincap.has_lseek_bug () && get_check_win95_lseek_bug ()) { /* Note: this bug doesn't happen on NT4, even though the documentation for WriteFile() says that it *may* happen on any OS. */ @@ -1419,14 +1418,14 @@ fhandler_disk_file::lock (int cmd, struct flock *fl) if (win32_len == 0) { win32_len = 0xffffffff; - win32_upper = host_dependent.win32_upper; + win32_upper = wincap.lock_file_highword (); } else win32_upper = 0; BOOL res; - if (iswinnt) + if (wincap.has_lock_file_ex ()) { DWORD lock_flags = (cmd == F_SETLK) ? LOCKFILE_FAIL_IMMEDIATELY : 0; lock_flags |= (fl->l_type == F_WRLCK) ? LOCKFILE_EXCLUSIVE_LOCK : 0; diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index ea698d640..f094ca463 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -442,7 +442,7 @@ public: /* This strange test is due to the fact that we can't rely on Windows shells to "do the right thing" with pipes. Apparently the can keep one end of the pipe open when it shouldn't be. */ - BOOL is_slow () {return iswinnt;} + BOOL is_slow () {return wincap.has_unreliable_pipes ();} select_record *select_read (select_record *s); select_record *select_write (select_record *s); select_record *select_except (select_record *s); diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index de21bc446..d061dee2f 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -315,7 +315,7 @@ fhandler_console::read (void *pv, size_t buflen) part is to distinguish whether the right Alt key should be recognized as Alt, or as AltGr. */ bool meta; - if (iswinnt) + if (wincap.altgr_is_ctrl_alt ()) /* WinNT: AltGr is reported as Ctrl+Alt, and Ctrl+Alt is treated just like AltGr. However, if Ctrl+Alt+key generates an ASCII control character, interpret is as META. */ diff --git a/winsup/cygwin/fhandler_mem.cc b/winsup/cygwin/fhandler_mem.cc index bc4cb36bf..b6b461a62 100644 --- a/winsup/cygwin/fhandler_mem.cc +++ b/winsup/cygwin/fhandler_mem.cc @@ -28,7 +28,7 @@ fhandler_dev_mem::fhandler_dev_mem (const char *name, int nunit) unit (nunit) { /* Reading physical memory only supported on NT/W2K. */ - if (!iswinnt) + if (!wincap.has_physical_mem_access ()) { mem_size = 0; return; @@ -74,7 +74,7 @@ fhandler_dev_mem::~fhandler_dev_mem (void) int fhandler_dev_mem::open (const char *, int flags, mode_t) { - if (!iswinnt) + if (!wincap.has_physical_mem_access ()) { set_errno (ENOENT); debug_printf ("%s is accessible under NT/W2K only", @@ -413,7 +413,7 @@ fhandler_dev_mem::fstat (struct stat *buf) memset (buf, 0, sizeof *buf); buf->st_mode = S_IFCHR; - if (!iswinnt) + if (!wincap.has_physical_mem_access ()) buf->st_mode |= S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index ccfc2aa26..3998cb56b 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -35,7 +35,6 @@ static int npid_max; static pid_t fork_pids[100]; #endif -DWORD NO_COPY chunksize = 0; /* Timeout to wait for child to start, parent to init child, etc. */ /* FIXME: Once things stabilize, bump up to a few minutes. */ #define FORK_WAIT_TIMEOUT (300 * 1000) /* 300 seconds */ @@ -87,7 +86,7 @@ fork_copy (PROCESS_INFORMATION &pi, const char *what, ...) while ((low = va_arg (args, char *))) { char *high = va_arg (args, char *); - DWORD todo = chunksize ?: high - low; + DWORD todo = wincap.chunksize () ?: high - low; char *here; for (here = low; here < high; here += todo) diff --git a/winsup/cygwin/host_dependent.h b/winsup/cygwin/host_dependent.h deleted file mode 100644 index 94e1546ca..000000000 --- a/winsup/cygwin/host_dependent.h +++ /dev/null @@ -1,30 +0,0 @@ -/* host_dependent.h: host dependent Cygwin header file. - - Copyright 2000 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. */ - -/* Portions of the cygwin DLL require special constants whose values - are dependent on the host system. Rather than dynamically - determine those values whenever they are required, initialize these - values once at process start-up. */ - -class host_dependent_constants -{ - public: - void init (void); - - /* Used by fhandler_disk_file::lock which needs a platform-specific - upper word value for locking entire files. */ - DWORD win32_upper; - - /* fhandler_base::open requires host dependent file sharing - attributes. */ - int shared; -}; - -extern host_dependent_constants host_dependent; diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index a8e027844..65adf7c9a 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -41,10 +41,10 @@ details. */ the Cygwin library". This version is used to track important changes to the DLL and is mainly informative in nature. */ - /* The current cygwin version is 1.3.1 */ + /* The current cygwin version is 1.3.4 */ #define CYGWIN_VERSION_DLL_MAJOR 1003 -#define CYGWIN_VERSION_DLL_MINOR 3 +#define CYGWIN_VERSION_DLL_MINOR 4 /* Major numbers before CYGWIN_VERSION_DLL_EPOCH are incompatible. */ diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc index 2ac18e9e4..b88deb872 100644 --- a/winsup/cygwin/mmap.cc +++ b/winsup/cygwin/mmap.cc @@ -83,7 +83,7 @@ class mmap_record /* Allocate one bit per page */ map_map_ = (DWORD *) calloc (MAPSIZE(PAGE_CNT (size_to_map_)), sizeof (DWORD)); - if (iswinnt) + if (wincap.virtual_protect_works_on_shared_pages ()) { DWORD old_prot; if (!VirtualProtect (base_address_, size_to_map_, @@ -144,7 +144,7 @@ mmap_record::map_map (DWORD off, DWORD len) off = find_empty (len); if (off != (DWORD)-1) { - if (iswinnt + if (wincap.virtual_protect_works_on_shared_pages () && !VirtualProtect (base_address_ + off * getpagesize (), len * getpagesize (), prot, &old_prot)) syscall_printf ("-1 = map_map (): %E"); @@ -157,7 +157,7 @@ mmap_record::map_map (DWORD off, DWORD len) } off -= offset_; DWORD start = off / getpagesize (); - if (iswinnt + if (wincap.virtual_protect_works_on_shared_pages () && !VirtualProtect (base_address_ + start * getpagesize (), len * getpagesize (), prot, &old_prot)) syscall_printf ("-1 = map_map (): %E"); @@ -174,7 +174,7 @@ mmap_record::unmap_map (caddr_t addr, DWORD len) DWORD off = addr - base_address_; off /= getpagesize (); len = PAGE_CNT (len); - if (iswinnt + if (wincap.virtual_protect_works_on_shared_pages () && !VirtualProtect (base_address_ + off * getpagesize (), len * getpagesize (), PAGE_NOACCESS, &old_prot)) syscall_printf ("-1 = unmap_map (): %E"); @@ -192,7 +192,7 @@ mmap_record::unmap_map (caddr_t addr, DWORD len) void mmap_record::fixup_map () { - if (!iswinnt) + if (!wincap.virtual_protect_works_on_shared_pages ()) return; DWORD prot, old_prot; @@ -426,7 +426,8 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off) /* copy-on-write doesn't work correctly on 9x. To have at least read access we use *READ mapping on 9x when appropriate. It will still fail when needing write access, though. */ - if ((flags & MAP_PRIVATE) && (iswinnt || (prot & ~PROT_READ))) + if ((flags & MAP_PRIVATE) && (wincap.has_working_copy_on_write () + || (prot & ~PROT_READ))) access = FILE_MAP_COPY; SetResourceLock(LOCK_MMAP_LIST, READ_LOCK | WRITE_LOCK, "mmap"); @@ -437,7 +438,7 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off) * CV: This assumption isn't correct. See Microsoft Platform SDK, Memory, * description of call `MapViewOfFileEx'. */ - if ((!iswinnt) && (flags & MAP_FIXED)) + if ((!wincap.is_winnt ()) && (flags & MAP_FIXED)) { set_errno (EINVAL); syscall_printf ("-1 = mmap(): win95 and MAP_FIXED"); @@ -745,7 +746,7 @@ fhandler_disk_file::mmap (caddr_t *addr, size_t len, DWORD access, /* On 9x/ME try first to open the mapping by name when opening a shared file object. This is needed since 9x/ME only shares objects between processes by name. What a mess... */ - if (!iswinnt + if (wincap.share_mmaps_only_by_name () && get_handle () != INVALID_HANDLE_VALUE && get_device () == FH_DISK && !(access & FILE_MAP_COPY)) diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index b51027a47..c53613abc 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -121,7 +121,7 @@ WSADATA wsadata; static SOCKET __stdcall set_socket_inheritance (SOCKET sock) { - if (iswinnt) + if (wincap.has_set_handle_information ()) (void) SetHandleInformation ((HANDLE) sock, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); else { @@ -1527,9 +1527,9 @@ getdomainname (char *domain, int len) * Punt for now and assume MS-TCP on Win95. */ reg_key r (HKEY_LOCAL_MACHINE, KEY_READ, - (!iswinnt) ? "System" : "SYSTEM", + (!wincap.is_winnt ()) ? "System" : "SYSTEM", "CurrentControlSet", "Services", - (!iswinnt) ? "MSTCP" : "Tcpip", + (!wincap.is_winnt ()) ? "MSTCP" : "Tcpip", NULL); /* FIXME: Are registry keys case sensitive? */ @@ -2107,22 +2107,12 @@ get_ifconf (struct ifconf *ifc, int what) memset (&os_version_info, 0, sizeof os_version_info); os_version_info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); GetVersionEx (&os_version_info); - /* We have a win95 version... */ - if (os_version_info.dwPlatformId != VER_PLATFORM_WIN32_NT - && (os_version_info.dwMajorVersion < 4 - || (os_version_info.dwMajorVersion == 4 - && os_version_info.dwMinorVersion == 0))) - get_95_ifconf (ifc, what); - /* ...and a NT <= SP3 version... */ - else if (os_version_info.dwPlatformId == VER_PLATFORM_WIN32_NT - && (os_version_info.dwMajorVersion < 4 - || (os_version_info.dwMajorVersion == 4 - && strcmp (os_version_info.szCSDVersion, "Service Pack 4") < 0))) - get_nt_ifconf (ifc, what); - /* ...and finally a "modern" version for win98/ME, NT >= SP4 and W2K! */ - else + if (wincap.has_ip_helper_lib ()) get_2k_ifconf (ifc, what); - + else if (wincap.is_winnt ()) + get_nt_ifconf (ifc, what); + else + get_95_ifconf (ifc, what); return 0; } diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 14e8b819b..14eba9b92 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -70,7 +70,6 @@ set_myself (pid_t pid, HANDLE h) sizeof(myself->progname)); if (strace.active) { - extern char osname[]; strace.prntf (1, NULL, "**********************************************"); strace.prntf (1, NULL, "Program name: %s (%d)", myself->progname, myself->pid); strace.prntf (1, NULL, "App version: %d.%d, api: %d.%d", @@ -80,7 +79,7 @@ set_myself (pid_t pid, HANDLE h) cygwin_version.dll_major, cygwin_version.dll_minor, cygwin_version.api_major, cygwin_version.api_minor); strace.prntf (1, NULL, "DLL build: %s", cygwin_version.dll_build_date); - strace.prntf (1, NULL, "OS version: Windows %s", osname); + strace.prntf (1, NULL, "OS version: Windows %s", wincap.osname ()); strace.prntf (1, NULL, "**********************************************"); } @@ -393,7 +392,7 @@ winpids::init (bool winpid) DWORD winpids::enum_init (bool winpid) { - if (iswinnt) + if (wincap.is_winnt ()) enum_processes = &winpids::enumNT; else enum_processes = &winpids::enum9x; diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h index fc9352ce6..950f2c272 100644 --- a/winsup/cygwin/pinfo.h +++ b/winsup/cygwin/pinfo.h @@ -185,7 +185,7 @@ public: extern __inline pid_t cygwin_pid (pid_t pid) { - return (pid_t) (iswinnt) ? pid : -(int) pid; + return (pid_t) (wincap.has_negative_pids ()) ? -(int) pid : pid; } void __stdcall pinfo_init (char **, int); diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc index 654100cbf..d4dd03c70 100644 --- a/winsup/cygwin/security.cc +++ b/winsup/cygwin/security.cc @@ -108,7 +108,7 @@ extern "C" HANDLE cygwin_logon_user (const struct passwd *pw, const char *password) { - if (!iswinnt) + if (!wincap.has_security ()) { set_errno (ENOSYS); return INVALID_HANDLE_VALUE; @@ -1063,7 +1063,7 @@ static int get_nt_attribute (const char *file, int *attribute, uid_t *uidret, gid_t *gidret) { - if (!iswinnt) + if (!wincap.has_security ()) return 0; syscall_printf ("file: %s", file); @@ -1286,7 +1286,7 @@ alloc_sd (uid_t uid, gid_t gid, const char *logsrv, int attribute, { BOOL dummy; - if (!iswinnt) + if (!wincap.has_security ()) return NULL; if (!sd_ret || !sd_size_ret) @@ -1334,13 +1334,7 @@ alloc_sd (uid_t uid, gid_t gid, const char *logsrv, int attribute, * This flag as well as the SetSecurityDescriptorControl call are available * only since Win2K. */ - static int win2KorHigher = -1; - if (win2KorHigher == -1) - { - DWORD version = GetVersion (); - win2KorHigher = (version & 0x80000000) || (version & 0xff) < 5 ? 0 : 1; - } - if (win2KorHigher > 0) + if (wincap.has_security_descriptor_control ()) SetSecurityDescriptorControl (&sd, SE_DACL_PROTECTED, SE_DACL_PROTECTED); /* Create owner for local security descriptor. */ @@ -1559,7 +1553,7 @@ static int set_nt_attribute (const char *file, uid_t uid, gid_t gid, const char *logsrv, int attribute) { - if (!iswinnt) + if (!wincap.has_security ()) return 0; DWORD sd_size = 4096; diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index e9ee64d81..d6ef25c58 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -150,7 +150,7 @@ _unlink (const char *ourname) /* Windows 9x seems to report ERROR_ACCESS_DENIED rather than sharing violation. So, set lasterr to ERROR_SHARING_VIOLATION in this case to simplify tests. */ - if (!iswinnt && lasterr == ERROR_ACCESS_DENIED + if (wincap.access_denied_on_delete () && lasterr == ERROR_ACCESS_DENIED && !win32_name.isremote ()) lasterr = ERROR_SHARING_VIOLATION; @@ -168,7 +168,8 @@ _unlink (const char *ourname) bool delete_on_close_ok; - delete_on_close_ok = !win32_name.isremote () && iswinnt; + delete_on_close_ok = !win32_name.isremote () + && wincap.has_delete_on_close (); /* Attempt to use "delete on close" semantics to handle removing a file which may be open. */ @@ -609,8 +610,14 @@ _link (const char *a, const char *b) } /* Try to make hard link first on Windows NT */ - if (iswinnt) + if (wincap.has_hard_links ()) { + if (CreateHardLinkA (real_b.get_win32 (), real_a.get_win32 (), NULL)) + { + res = 0; + goto done; + } + HANDLE hFileSource; WIN32_STREAM_ID StreamId; @@ -726,7 +733,7 @@ chown_worker (const char *name, unsigned fmode, uid_t uid, gid_t gid) if (check_null_empty_str_errno (name)) return -1; - if (!iswinnt) // real chown only works on NT + if (!wincap.has_security ()) // real chown only works on NT res = 0; // return zero (and do nothing) under Windows 9x else { @@ -1093,7 +1100,7 @@ stat_worker (const char *caller, const char *name, struct stat *buf, dtype = real_path.get_drive_type (); if ((atts == -1 || ! (atts & FILE_ATTRIBUTE_DIRECTORY) || - (iswinnt + (wincap.can_open_directories () && dtype != DRIVE_NO_ROOT_DIR && dtype != DRIVE_UNKNOWN))) { @@ -1357,7 +1364,7 @@ _rename (const char *oldpath, const char *newpath) && GetLastError () != ERROR_FILE_EXISTS)) goto done; - if (iswinnt) + if (wincap.has_move_file_ex ()) { if (MoveFileEx (real_old.get_win32 (), real_new.get_win32 (), MOVEFILE_REPLACE_EXISTING)) @@ -1481,7 +1488,7 @@ check_posix_perm (const char *fname, int v) extern int allow_ntea, allow_ntsec, allow_smbntsec; /* Windows 95/98/ME don't support file system security at all. */ - if (!iswinnt) + if (!wincap.has_security ()) return 0; /* ntea is ok for supporting permission bits but it doesn't support @@ -2022,7 +2029,7 @@ extern "C" int seteuid (uid_t uid) { sigframe thisframe (mainthread); - if (iswinnt) + if (wincap.has_security ()) { char orig_username[UNLEN + 1]; char orig_domain[INTERNET_MAX_HOST_NAME_LENGTH + 1]; @@ -2237,7 +2244,7 @@ extern "C" int setegid (gid_t gid) { sigframe thisframe (mainthread); - if (iswinnt) + if (wincap.has_security ()) { if (gid != (gid_t) -1) { diff --git a/winsup/cygwin/sysconf.cc b/winsup/cygwin/sysconf.cc index 8fc49ec81..aa1909141 100644 --- a/winsup/cygwin/sysconf.cc +++ b/winsup/cygwin/sysconf.cc @@ -56,37 +56,39 @@ sysconf (int in) #endif case _SC_NPROCESSORS_CONF: case _SC_NPROCESSORS_ONLN: - if (!iswinnt) + if (!wincap.supports_smp ()) return 1; /*FALLTHRU*/ case _SC_PHYS_PAGES: case _SC_AVPHYS_PAGES: - { - NTSTATUS ret; - SYSTEM_BASIC_INFORMATION sbi; - if ((ret = NtQuerySystemInformation (SystemBasicInformation, - (PVOID) &sbi, - sizeof sbi, NULL)) - != STATUS_SUCCESS) - { - __seterrno_from_win_error (RtlNtStatusToDosError (ret)); - debug_printf("NtQuerySystemInformation: ret = %d, " - "Dos(ret) = %d", - ret, RtlNtStatusToDosError (ret)); - return -1; - } - switch (in) - { - case _SC_NPROCESSORS_CONF: - return sbi.NumberProcessors; - case _SC_NPROCESSORS_ONLN: - return sbi.ActiveProcessors; - case _SC_PHYS_PAGES: - return sbi.NumberOfPhysicalPages; - case _SC_AVPHYS_PAGES: - return sbi.HighestPhysicalPage - sbi.LowestPhysicalPage + 1; - } - } + if (!wincap.supports_smp ()) + { + NTSTATUS ret; + SYSTEM_BASIC_INFORMATION sbi; + if ((ret = NtQuerySystemInformation (SystemBasicInformation, + (PVOID) &sbi, + sizeof sbi, NULL)) + != STATUS_SUCCESS) + { + __seterrno_from_win_error (RtlNtStatusToDosError (ret)); + debug_printf("NtQuerySystemInformation: ret = %d, " + "Dos(ret) = %d", + ret, RtlNtStatusToDosError (ret)); + return -1; + } + switch (in) + { + case _SC_NPROCESSORS_CONF: + return sbi.NumberProcessors; + case _SC_NPROCESSORS_ONLN: + return sbi.ActiveProcessors; + case _SC_PHYS_PAGES: + return sbi.NumberOfPhysicalPages; + case _SC_AVPHYS_PAGES: + return sbi.HighestPhysicalPage - sbi.LowestPhysicalPage + 1; + } + } + break; } /* Invalid input or unimplemented sysconf name */ diff --git a/winsup/cygwin/syslog.cc b/winsup/cygwin/syslog.cc index 2acf7e133..c11ff1170 100644 --- a/winsup/cygwin/syslog.cc +++ b/winsup/cygwin/syslog.cc @@ -300,10 +300,10 @@ syslog (int priority, const char *message, ...) return; } - if (!iswinnt) + if (!wincap.has_eventlog ()) { - /* Add a priority string - not needed for NT - as NT has its own priority codes. */ + /* Add a priority string - not needed for systems with + eventlog capability. */ switch (LOG_PRI (priority)) { case LOG_ERR: @@ -336,7 +336,7 @@ syslog (int priority, const char *message, ...) msg_strings[0] = total_msg; - if (iswinnt) + if (wincap.has_eventlog ()) { /* For NT, open the event log and send the message */ HANDLE hEventSrc = RegisterEventSourceA (NULL, (process_ident != NULL) ? diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index 241f734cd..e4712a0dc 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -499,7 +499,7 @@ int pthread_cond::TimedWait (DWORD dwMilliseconds) { DWORD rv; - if (!iswinnt) + if (!wincap.has_signal_object_and_wait ()) { // FIXME: race condition (potentially drop events // Possible solution (single process only) - place this in a critical section. @@ -621,7 +621,7 @@ pthread_mutex::pthread_mutex (pthread_mutexattr *attr):verifyable_object (PTHREA magic = 0; return; } - if (iswinnt) + if (wincap.has_try_enter_critical_section ()) InitializeCriticalSection (&criticalsection); else { @@ -637,7 +637,7 @@ pthread_mutex::pthread_mutex (pthread_mutexattr *attr):verifyable_object (PTHREA pthread_mutex::~pthread_mutex () { - if (iswinnt) + if (wincap.has_try_enter_critical_section ()) DeleteCriticalSection (&criticalsection); else { @@ -663,7 +663,7 @@ pthread_mutex::~pthread_mutex () int pthread_mutex::Lock () { - if (iswinnt) + if (wincap.has_try_enter_critical_section ()) { EnterCriticalSection (&criticalsection); return 0; @@ -676,7 +676,7 @@ pthread_mutex::Lock () int pthread_mutex::TryLock () { - if (iswinnt) + if (wincap.has_try_enter_critical_section ()) return (!TryEnterCriticalSection (&criticalsection)); return (WaitForSingleObject (win32_obj_id, 0) == WAIT_TIMEOUT); } @@ -684,7 +684,7 @@ pthread_mutex::TryLock () int pthread_mutex::UnLock () { - if (iswinnt) + if (wincap.has_try_enter_critical_section ()) { LeaveCriticalSection (&criticalsection); return 0; @@ -699,7 +699,7 @@ pthread_mutex::fixup_after_fork () if (pshared != PTHREAD_PROCESS_PRIVATE) api_fatal("pthread_mutex::fixup_after_fork () doesn'tunderstand PROCESS_SHARED mutex's\n"); /* FIXME: duplicate code here and in the constructor. */ - if (iswinnt) + if (wincap.has_try_enter_critical_section ()) InitializeCriticalSection(&criticalsection); else { diff --git a/winsup/cygwin/times.cc b/winsup/cygwin/times.cc index f75bc2a0e..ee5fe5f50 100644 --- a/winsup/cygwin/times.cc +++ b/winsup/cygwin/times.cc @@ -56,7 +56,7 @@ times (struct tms * buf) /* Ticks is in milliseconds, convert to our ticks. Use long long to prevent overflow. */ clock_t tc = (clock_t) ((long long) ticks * CLOCKS_PER_SEC / 1000); - if (iswinnt) + if (wincap.has_get_process_times ()) { GetProcessTimes (hMainProc, &creation_time, &exit_time, &kernel_time, &user_time); @@ -462,7 +462,8 @@ utimes (const char *path, struct timeval *tvp) /* Note: It's not documented in MSDN that FILE_WRITE_ATTRIBUTES is sufficient to change the timestamps... */ HANDLE h = CreateFileA (win32.get_win32 (), - iswinnt ? FILE_WRITE_ATTRIBUTES : GENERIC_WRITE, + wincap.has_specific_access_rights () ? + FILE_WRITE_ATTRIBUTES : GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &sec_none_nih, OPEN_EXISTING, diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc index 7edfdd217..b3d753c8d 100644 --- a/winsup/cygwin/tty.cc +++ b/winsup/cygwin/tty.cc @@ -392,7 +392,7 @@ tty::common_init (fhandler_pty_master *ptym) /* Allow the others to open us (for handle duplication) */ - if ((iswinnt) && + if (wincap.has_security () && (SetKernelObjectSecurity (hMainProc, DACL_SECURITY_INFORMATION, get_null_sd ()) == FALSE)) small_printf ("Can't set process security, %E"); diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index 9dcc7b5db..a6b94c803 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -40,7 +40,7 @@ internal_getlogin (cygheap_user &user) user.set_name (username); debug_printf ("GetUserName() = %s", user.name ()); - if (iswinnt) + if (wincap.has_security ()) { LPWKSTA_USER_INFO_1 wui; NET_API_STATUS ret; diff --git a/winsup/cygwin/uname.cc b/winsup/cygwin/uname.cc index 924bc9cf4..054033a8a 100644 --- a/winsup/cygwin/uname.cc +++ b/winsup/cygwin/uname.cc @@ -21,11 +21,10 @@ uname (struct utsname *name) { DWORD len; SYSTEM_INFO sysinfo; - extern char osname[]; char *snp = strstr (cygwin_version.dll_build_date, "SNP"); memset (name, 0, sizeof (*name)); - __small_sprintf (name->sysname, "CYGWIN_%s", osname); + __small_sprintf (name->sysname, "CYGWIN_%s", wincap.osname ()); GetSystemInfo (&sysinfo); diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc new file mode 100644 index 000000000..208f08972 --- /dev/null +++ b/winsup/cygwin/wincap.cc @@ -0,0 +1,462 @@ +/* wincap.cc -- figure out on which OS we're running. Set the + capability class to the appropriate values. + + Copyright 2001 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. */ + +#include "winsup.h" + +static wincaps wincap_unknown = { + lock_file_highword:0x0, + chunksize:0x0, + shared:FILE_SHARE_READ | FILE_SHARE_WRITE, + is_winnt:false, + access_denied_on_delete:false, + has_delete_on_close:false, + has_page_guard:false, + has_security:false, + has_security_descriptor_control:false, + has_get_process_times:false, + has_specific_access_rights:false, + has_lseek_bug:false, + has_lock_file_ex:false, + has_signal_object_and_wait:false, + has_eventlog:false, + has_ip_helper_lib:false, + has_set_handle_information:false, + supports_smp:false, + map_view_of_file_ex_sucks:false, + altgr_is_ctrl_alt:false, + has_physical_mem_access:false, + has_working_copy_on_write:false, + share_mmaps_only_by_name:false, + virtual_protect_works_on_shared_pages:false, + has_hard_links:false, + can_open_directories:false, + has_move_file_ex:false, + has_negative_pids:false, + has_unreliable_pipes:false, + has_try_enter_critical_section:false, +}; + +static wincaps wincap_95 = { + lock_file_highword:0x0, + chunksize:32 * 1024 * 1024, + shared:FILE_SHARE_READ | FILE_SHARE_WRITE, + is_winnt:false, + access_denied_on_delete:true, + has_delete_on_close:false, + has_page_guard:false, + has_security:false, + has_security_descriptor_control:false, + has_get_process_times:false, + has_specific_access_rights:false, + has_lseek_bug:true, + has_lock_file_ex:false, + has_signal_object_and_wait:false, + has_eventlog:false, + has_ip_helper_lib:false, + has_set_handle_information:false, + supports_smp:false, + map_view_of_file_ex_sucks:true, + altgr_is_ctrl_alt:false, + has_physical_mem_access:false, + has_working_copy_on_write:false, + share_mmaps_only_by_name:true, + virtual_protect_works_on_shared_pages:false, + has_hard_links:false, + can_open_directories:false, + has_move_file_ex:false, + has_negative_pids:true, + has_unreliable_pipes:true, + has_try_enter_critical_section:false, +}; + +static wincaps wincap_95osr2 = { + lock_file_highword:0x0, + chunksize:32 * 1024 * 1024, + shared:FILE_SHARE_READ | FILE_SHARE_WRITE, + is_winnt:false, + access_denied_on_delete:true, + has_delete_on_close:false, + has_page_guard:false, + has_security:false, + has_security_descriptor_control:false, + has_get_process_times:false, + has_specific_access_rights:false, + has_lseek_bug:true, + has_lock_file_ex:false, + has_signal_object_and_wait:false, + has_eventlog:false, + has_ip_helper_lib:false, + has_set_handle_information:false, + supports_smp:false, + map_view_of_file_ex_sucks:true, + altgr_is_ctrl_alt:false, + has_physical_mem_access:false, + has_working_copy_on_write:false, + share_mmaps_only_by_name:true, + virtual_protect_works_on_shared_pages:false, + has_hard_links:false, + can_open_directories:false, + has_move_file_ex:false, + has_negative_pids:true, + has_unreliable_pipes:true, + has_try_enter_critical_section:false, +}; + +static wincaps wincap_98 = { + lock_file_highword:0x0, + chunksize:32 * 1024 * 1024, + shared:FILE_SHARE_READ | FILE_SHARE_WRITE, + is_winnt:false, + access_denied_on_delete:true, + has_delete_on_close:false, + has_page_guard:false, + has_security:false, + has_security_descriptor_control:false, + has_get_process_times:false, + has_specific_access_rights:false, + has_lseek_bug:true, + has_lock_file_ex:false, + has_signal_object_and_wait:false, + has_eventlog:false, + has_ip_helper_lib:true, + has_set_handle_information:false, + supports_smp:false, + map_view_of_file_ex_sucks:true, + altgr_is_ctrl_alt:false, + has_physical_mem_access:false, + has_working_copy_on_write:false, + share_mmaps_only_by_name:true, + virtual_protect_works_on_shared_pages:false, + has_hard_links:false, + can_open_directories:false, + has_move_file_ex:false, + has_negative_pids:true, + has_unreliable_pipes:true, + has_try_enter_critical_section:false, +}; + +static wincaps wincap_98se = { + lock_file_highword:0x0, + chunksize:32 * 1024 * 1024, + shared:FILE_SHARE_READ | FILE_SHARE_WRITE, + is_winnt:false, + access_denied_on_delete:true, + has_delete_on_close:false, + has_page_guard:false, + has_security:false, + has_security_descriptor_control:false, + has_get_process_times:false, + has_specific_access_rights:false, + has_lseek_bug:true, + has_lock_file_ex:false, + has_signal_object_and_wait:false, + has_eventlog:false, + has_ip_helper_lib:true, + has_set_handle_information:false, + supports_smp:false, + map_view_of_file_ex_sucks:true, + altgr_is_ctrl_alt:false, + has_physical_mem_access:false, + has_working_copy_on_write:false, + share_mmaps_only_by_name:true, + virtual_protect_works_on_shared_pages:false, + has_hard_links:false, + can_open_directories:false, + has_move_file_ex:false, + has_negative_pids:true, + has_unreliable_pipes:true, + has_try_enter_critical_section:false, +}; + +static wincaps wincap_me = { + lock_file_highword:0x0, + chunksize:32 * 1024 * 1024, + shared:FILE_SHARE_READ | FILE_SHARE_WRITE, + is_winnt:false, + access_denied_on_delete:true, + has_delete_on_close:false, + has_page_guard:false, + has_security:false, + has_security_descriptor_control:false, + has_get_process_times:false, + has_specific_access_rights:false, + has_lseek_bug:true, + has_lock_file_ex:false, + has_signal_object_and_wait:false, + has_eventlog:false, + has_ip_helper_lib:true, + has_set_handle_information:false, + supports_smp:false, + map_view_of_file_ex_sucks:true, + altgr_is_ctrl_alt:false, + has_physical_mem_access:false, + has_working_copy_on_write:false, + share_mmaps_only_by_name:true, + virtual_protect_works_on_shared_pages:false, + has_hard_links:false, + can_open_directories:false, + has_move_file_ex:false, + has_negative_pids:true, + has_unreliable_pipes:true, + has_try_enter_critical_section:false, +}; + +static wincaps wincap_nt3 = { + 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:false, + has_get_process_times:true, + has_specific_access_rights:true, + has_lseek_bug:false, + has_lock_file_ex:true, + has_signal_object_and_wait:false, + has_eventlog:true, + has_ip_helper_lib:false, + has_set_handle_information:true, + supports_smp:false, + 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:false, +}; + +static wincaps wincap_nt4 = { + 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:false, + has_get_process_times:true, + has_specific_access_rights:true, + has_lseek_bug:false, + has_lock_file_ex:true, + has_signal_object_and_wait:true, + has_eventlog:true, + has_ip_helper_lib:false, + has_set_handle_information: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, +}; + +static wincaps wincap_nt4sp4 = { + 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:false, + has_get_process_times:true, + has_specific_access_rights: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, + 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, +}; + +static wincaps wincap_2000 = { + 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_specific_access_rights: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, + 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, +}; + +static wincaps wincap_xp = { + 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_specific_access_rights: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, + 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, +}; + +wincapc NO_COPY wincap; + +void +wincapc::init () +{ + const char *os; + + memset (&version, 0, sizeof version); + version.dwOSVersionInfoSize = sizeof version; + GetVersionEx (&version); + + switch (version.dwPlatformId) + { + case VER_PLATFORM_WIN32_NT: + switch (version.dwMajorVersion) + { + case 3: + os = "NT"; + caps = &wincap_nt3; + break; + case 4: + os = "NT"; + if (strcmp (version.szCSDVersion, "Service Pack 4") < 0) + caps = &wincap_nt4; + else + caps = &wincap_nt4sp4; + break; + case 5: + if (version.dwMinorVersion == 0) + { + os = "NT"; + caps = &wincap_2000; + } + else + { + os = "XP"; + caps = &wincap_xp; + } + break; + default: + os = "??"; + caps = &wincap_unknown; + break; + } + break; + case VER_PLATFORM_WIN32_WINDOWS: + switch (version.dwMinorVersion) + { + case 0: + os = "95"; + if (strchr(version.szCSDVersion, 'C')) + caps = &wincap_95osr2; + else + caps = &wincap_95; + break; + case 10: + os = "98"; + if (strchr(version.szCSDVersion, 'A')) + caps = &wincap_98se; + else + caps = &wincap_98; + break; + case 90: + os = "ME"; + caps = &wincap_me; + break; + default: + os = "??"; + caps = &wincap_unknown; + break; + } + break; + default: + os = "??"; + caps = &wincap_unknown; + break; + } + __small_sprintf (osnam, "%s-%d.%d", os, version.dwMajorVersion, + version.dwMinorVersion); +} + +void +wincapc::set_chunksize (DWORD nchunksize) +{ + ((wincaps *)this->caps)->chunksize = nchunksize; +} diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h new file mode 100644 index 000000000..903c719e8 --- /dev/null +++ b/winsup/cygwin/wincap.h @@ -0,0 +1,99 @@ +/* wincap.h: Header for OS capability class. + + Copyright 2001 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. */ + +#ifndef _WINCAP_H +#define _WINCAP_H + +struct wincaps +{ + DWORD lock_file_highword; + DWORD chunksize; + int shared; + unsigned is_winnt : 1; + unsigned access_denied_on_delete : 1; + unsigned has_delete_on_close : 1; + unsigned has_page_guard : 1; + unsigned has_security : 1; + unsigned has_security_descriptor_control : 1; + unsigned has_get_process_times : 1; + unsigned has_specific_access_rights : 1; + unsigned has_lseek_bug : 1; + unsigned has_lock_file_ex : 1; + unsigned has_signal_object_and_wait : 1; + unsigned has_eventlog : 1; + unsigned has_ip_helper_lib : 1; + unsigned has_set_handle_information : 1; + unsigned supports_smp : 1; + unsigned map_view_of_file_ex_sucks : 1; + unsigned altgr_is_ctrl_alt : 1; + unsigned has_physical_mem_access : 1; + unsigned has_working_copy_on_write : 1; + unsigned share_mmaps_only_by_name : 1; + unsigned virtual_protect_works_on_shared_pages : 1; + unsigned has_hard_links : 1; + unsigned can_open_directories : 1; + unsigned has_move_file_ex : 1; + unsigned has_negative_pids : 1; + unsigned has_unreliable_pipes : 1; + unsigned has_try_enter_critical_section : 1; +}; + +class wincapc +{ + OSVERSIONINFO version; + char osnam[40]; + void *caps; + +public: + void init (); + + void set_chunksize (DWORD nchunksize); + + const char *osname () const { return osnam; } + +#define IMPLEMENT(cap) cap() const { return ((wincaps *)this->caps)->cap; } + + DWORD IMPLEMENT (lock_file_highword) + DWORD IMPLEMENT (chunksize) + int IMPLEMENT (shared) + bool IMPLEMENT (is_winnt) + bool IMPLEMENT (access_denied_on_delete) + bool IMPLEMENT (has_delete_on_close) + bool IMPLEMENT (has_page_guard) + bool IMPLEMENT (has_security) + bool IMPLEMENT (has_security_descriptor_control) + bool IMPLEMENT (has_get_process_times) + bool IMPLEMENT (has_specific_access_rights) + bool IMPLEMENT (has_lseek_bug) + bool IMPLEMENT (has_lock_file_ex) + bool IMPLEMENT (has_signal_object_and_wait) + bool IMPLEMENT (has_eventlog) + bool IMPLEMENT (has_ip_helper_lib) + bool IMPLEMENT (has_set_handle_information) + bool IMPLEMENT (supports_smp) + bool IMPLEMENT (map_view_of_file_ex_sucks) + bool IMPLEMENT (altgr_is_ctrl_alt) + bool IMPLEMENT (has_physical_mem_access) + bool IMPLEMENT (has_working_copy_on_write) + bool IMPLEMENT (share_mmaps_only_by_name) + bool IMPLEMENT (virtual_protect_works_on_shared_pages) + bool IMPLEMENT (has_hard_links) + bool IMPLEMENT (can_open_directories) + bool IMPLEMENT (has_move_file_ex) + bool IMPLEMENT (has_negative_pids) + bool IMPLEMENT (has_unreliable_pipes) + bool IMPLEMENT (has_try_enter_critical_section) + +#undef IMPLEMENT +}; + +extern wincapc wincap; + +#endif /* _WINCAP_H */ diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h index 0e1e9fcc4..e1f59b761 100644 --- a/winsup/cygwin/winsup.h +++ b/winsup/cygwin/winsup.h @@ -61,14 +61,11 @@ extern const char case_folded_upper[]; #undef _WINNETWK_H #undef _WINSVC_H +#include "wincap.h" + /* The one function we use from winuser.h most of the time */ extern "C" DWORD WINAPI GetLastError (void); -/* Used for runtime OS check/decisions. */ -enum os_type {winNT = 1, win95, win98, winME, win32s, unknown}; -extern os_type os_being_run; -extern bool iswinnt; - enum codepage_type {ansi_cp, oem_cp}; extern codepage_type current_codepage;