summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorscottc <scottc>2002-09-06 09:48:09 +0000
committerscottc <scottc>2002-09-06 09:48:09 +0000
commit973c6bfc07b4cd6fa51325c0c03aa0457e6487ed (patch)
treeeda734fc08fa557374e36fe57528c7cfceef7838
parent4f4b2cc75928c8d49d32537492c6c77d31763a38 (diff)
downloadgdb-973c6bfc07b4cd6fa51325c0c03aa0457e6487ed.tar.gz
Merged changes from HEAD
-rw-r--r--winsup/cygwin/ChangeLog19
-rw-r--r--winsup/cygwin/Makefile.in45
-rw-r--r--winsup/cygwin/how-autoload-works.txt66
-rw-r--r--winsup/cygwin/path.cc91
-rw-r--r--winsup/cygwin/path.h3
-rw-r--r--winsup/cygwin/shortcut.c170
-rw-r--r--winsup/cygwin/shortcut.h28
-rw-r--r--winsup/cygwin/winsup.h4
8 files changed, 199 insertions, 227 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 04bf33a76a4..42d55190969 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,20 @@
+2002-09-06 Christopher Faylor <cgf@redhat.com>
+
+ * winsup.h (_WIN32_WINNT): Protect.
+
+2002-09-06 Christopher Faylor <cgf@redhat.com>
+
+ * winsup.h (_WIN32_WINNT): Define.
+
+2002-09-03 Corinna Vinschen <corinna@vinschen.de>
+
+ * Makefile.in (DLL_OFILES): Drop shortcut.o.
+ * path.cc: Move all shortcut functions from shortcut.c to here.
+ (check_shortcut): Implement without using COM interface.
+ * path.h: Move definition of SHORTCUT_HDR_SIZE to here.
+ * shortcut.c: Remove.
+ * shortcut.h: Ditto.
+
2002-09-03 Conrad Scott <conrad.scott@dsl.pipex.com>
* fhandler.h (fhandler_socket::read): Remove method.
@@ -47,7 +64,7 @@
(fhandler_tty_slave::read): Don't do anything special with vtime when
vmin == 0.
-2002-07-25 Egor Duda <deo@logos-m.ru>
+2002-08-30 Egor Duda <deo@logos-m.ru>
* autoload.cc (GetConsoleWindow): Correct parameter count.
diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in
index 2bba7a71d37..86db505aae3 100644
--- a/winsup/cygwin/Makefile.in
+++ b/winsup/cygwin/Makefile.in
@@ -118,29 +118,28 @@ MALLOC_OFILES=@MALLOC_OFILES@
DLL_IMPORTS:=$(w32api_lib)/libuuid.a $(w32api_lib)/libshell32.a $(w32api_lib)/libkernel32.a
# Please maintain this list in sorted order, with maximum files per 80 col line
-
-DLL_OFILES:=assert.o autoload.o cygheap.o cygserver_client.o \
- cygserver_transport.o cygserver_transport_pipes.o \
- cygserver_transport_sockets.o cygthread.o dcrt0.o debug.o \
- delqueue.o dir.o dlfcn.o dll_init.o dtable.o environ.o errno.o \
- exceptions.o exec.o external.o fcntl.o fhandler.o \
- fhandler_clipboard.o fhandler_console.o fhandler_disk_file.o \
- fhandler_dsp.o fhandler_floppy.o fhandler_mem.o \
- fhandler_proc.o fhandler_process.o fhandler_random.o \
- fhandler_raw.o fhandler_registry.o fhandler_serial.o \
- fhandler_socket.o fhandler_tape.o fhandler_termios.o \
- fhandler_tty.o fhandler_virtual.o fhandler_windows.o \
- fhandler_zero.o fnmatch.o fork.o glob.o grp.o heap.o init.o \
- ioctl.o ipc.o localtime.o malloc.o malloc_wrapper.o \
- miscfuncs.o mmap.o msg.o \
- net.o ntea.o passwd.o path.o pinfo.o pipe.o poll.o pthread.o \
- regcomp.o regerror.o regexec.o regfree.o registry.o resource.o \
- scandir.o sched.o sec_acl.o sec_helper.o security.o select.o \
- sem.o shared.o shm.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 v8_regexp.o v8_regerror.o v8_regsub.o wait.o wincap.o \
- window.o \
+DLL_OFILES:= \
+ assert.o autoload.o cygheap.o cygserver_client.o \
+ cygserver_transport.o cygserver_transport_pipes.o \
+ cygserver_transport_sockets.o cygthread.o dcrt0.o debug.o \
+ delqueue.o dir.o dlfcn.o dll_init.o dtable.o environ.o errno.o \
+ exceptions.o exec.o external.o fcntl.o fhandler.o \
+ fhandler_clipboard.o fhandler_console.o fhandler_disk_file.o \
+ fhandler_dsp.o fhandler_floppy.o fhandler_mem.o \
+ fhandler_proc.o fhandler_process.o fhandler_random.o \
+ fhandler_raw.o fhandler_registry.o fhandler_serial.o \
+ fhandler_socket.o fhandler_tape.o fhandler_termios.o \
+ fhandler_tty.o fhandler_virtual.o fhandler_windows.o \
+ fhandler_zero.o fnmatch.o fork.o glob.o grp.o heap.o init.o \
+ ioctl.o ipc.o localtime.o malloc.o malloc_wrapper.o \
+ miscfuncs.o mmap.o msg.o net.o ntea.o passwd.o path.o pinfo.o \
+ pipe.o poll.o pthread.o regcomp.o regerror.o regexec.o \
+ regfree.o registry.o resource.o scandir.o sched.o sec_acl.o \
+ sec_helper.o security.o select.o sem.o shared.o shm.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 v8_regexp.o v8_regerror.o v8_regsub.o wait.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/how-autoload-works.txt b/winsup/cygwin/how-autoload-works.txt
new file mode 100644
index 00000000000..27c2426d877
--- /dev/null
+++ b/winsup/cygwin/how-autoload-works.txt
@@ -0,0 +1,66 @@
+Copyright 2002 Red Hat Inc., Egor Duda
+
+How does function autoloading work?
+
+Cygwin has the ability to handle win32 functions which are present on
+some platforms and not present on others via autoload mechanism. It's
+essentially a lazy binding of symbols. It works as following. For
+(almost) every function from OS API which cygwin uses, a stub is created
+in file autoload.cc. Each reference to the such function from win32 API
+in cygwin dll source code is actually pointing to this stub.
+
+When the function, say GetConsoleWindow(), is called for the first time,
+the control is passed to its stub. The stub tries to load the
+appropriate system dll via LoadModule() and get the actual function
+address via GetProcAddress(). If this operation succeeds, the stub is
+"patched" to pass control to actual address of GetConsoleWindow() in
+appropriate system dll, so that next time we won't have to load dll and
+perform address lookup in it again. From this point on, the call to the
+function is performed as if the dll/function were linked statically.
+
+If LoadModule() or GetProcAddress() fail, (and on nt4 the latter indeed
+fails because GetConsoleWindow() is not available in kernel32.dll), then
+the application, depending on what kind of stub is created in
+autoload.cc, will either:
+
+1) Exit with fatal error.
+
+2) Or return a predefined value indicating an error; and set the windows
+error code to 127 (ERROR_PROC_NOT_FOUND).
+
+Almost all w32api functions are linked into the cygwin dll in this
+manner, dynamically, at runtime.
+
+The costs:
+1) A tiny overhead in the initial call to a function call as each call
+is performed, indirectly, via a stub. For the first lookup of a symbol
+of an unloaded dll, there is also some overhead in loading the dll for
+the first time. The dll is only loaded by the first call to a symbol
+in the dll. After the first call to a function, subsequent calls are
+as fast as a normal, statically loaded function.
+
+The benefits:
+1) Speedup at startup time. Applications only load those dlls which are
+actually needed. For example, if application never uses socket
+functions, winsock dlls are never loaded.
+
+2) Greatly simplify wincap system -- we don't need to have a separate
+capability for every win32 function which may or may not be present on
+particular win32 platform.
+
+3) Allows a single cygwin1.dll for all win32 platforms.
+
+If you're changing in cygwin1.dll source code and if you use some
+function that was not used there before, you should add a stub so it
+will be autoloaded. To do so, add one of the LoadDllfunc* macros to
+autoload.cc. All macros eventually resolve to the following form:
+
+LoadDLLfuncEx2 (function name, parameter block length, dll name,
+ non-fatality flag , value to return if function not available)
+
+Parameter block length is a sum of sizes (in bytes) of parameters which are
+being passed to the function. If non-fatality flag is set to 0, then failure
+to load dll and find a function will cause fatal error. If non fatality flag
+is set to 1, then call to the function will return default value.
+You can also use shorter versions -- LoadDLLfuncEx and LoadDLLfunc, if the
+defaults they provide suit your needs.
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index f4527afd847..eea04ab1ba7 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -74,7 +74,6 @@ details. */
#include "shared_info.h"
#include "registry.h"
#include <assert.h>
-#include "shortcut.h"
#ifdef _MT_SAFE
#define iteration _reent_winsup ()->_iteration
@@ -105,6 +104,26 @@ struct symlink_info
int pcheck_case = PCHECK_RELAXED; /* Determines the case check behaviour. */
+static char shortcut_header[SHORTCUT_HDR_SIZE];
+static BOOL shortcut_initalized;
+
+static void
+create_shortcut_header (void)
+{
+ if (!shortcut_initalized)
+ {
+ shortcut_header[0] = 'L';
+ shortcut_header[4] = '\001';
+ shortcut_header[5] = '\024';
+ shortcut_header[6] = '\002';
+ shortcut_header[12] = '\300';
+ shortcut_header[19] = 'F';
+ shortcut_header[20] = '\f';
+ shortcut_header[60] = '\001';
+ shortcut_initalized = TRUE;
+ }
+}
+
#define CYGWIN_REGNAME (cygheap->cygwin_regname ?: CYGWIN_INFO_CYGWIN_REGISTRY_NAME)
/* Determine if path prefix matches current cygdrive */
@@ -387,7 +406,7 @@ path_conv::fillin (HANDLE h)
fs.serial = local.dwVolumeSerialNumber;
}
fs.drive_type = DRIVE_UNKNOWN;
-}
+}
/* Convert an arbitrary path SRC to a pure Win32 path, suitable for
passing to Win32 API routines.
@@ -2622,7 +2641,7 @@ symlink (const char *topath, const char *frompath)
set_security_attribute (S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO,
&sa, alloca (4096), 4096);
- h = CreateFileA(win32_path, GENERIC_WRITE, 0, &sa,
+ h = CreateFile (win32_path, GENERIC_WRITE, 0, &sa,
CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
if (h == INVALID_HANDLE_VALUE)
__seterrno ();
@@ -2696,6 +2715,68 @@ done:
return res;
}
+static BOOL
+cmp_shortcut_header (const char *file_header)
+{
+ create_shortcut_header ();
+ return memcmp (shortcut_header, file_header, SHORTCUT_HDR_SIZE);
+}
+
+static int
+check_shortcut (const char *path, DWORD fileattr, HANDLE h,
+ char *contents, int *error, unsigned *pflags)
+{
+ char file_header[SHORTCUT_HDR_SIZE];
+ unsigned short len;
+ int res = 0;
+ DWORD got = 0;
+
+ /* Valid Cygwin & U/WIN shortcuts are R/O. */
+ if (!(fileattr & FILE_ATTRIBUTE_READONLY))
+ goto file_not_symlink;
+ /* Read the files header information. This is used to check for a
+ Cygwin or U/WIN shortcut or later to check for executable files. */
+ if (!ReadFile (h, file_header, SHORTCUT_HDR_SIZE, &got, 0))
+ {
+ *error = EIO;
+ goto close_it;
+ }
+ /* Check header if the shortcut is really created by Cygwin or U/WIN. */
+ if (got != SHORTCUT_HDR_SIZE || cmp_shortcut_header (file_header))
+ goto file_not_symlink;
+ /* Next 2 byte are USHORT, containing length of description entry. */
+ if (!ReadFile (h, &len, sizeof len, &got, 0))
+ {
+ *error = EIO;
+ goto close_it;
+ }
+ if (got != sizeof len || len == 0 || len > MAX_PATH)
+ goto file_not_symlink;
+ /* Now read description entry. */
+ if (!ReadFile (h, contents, len, &got, 0))
+ {
+ *error = EIO;
+ goto close_it;
+ }
+ if (got != len)
+ goto file_not_symlink;
+ contents[len] = '\0';
+ res = len;
+ if (res) /* It's a symlink. */
+ *pflags = PATH_SYMLINK;
+ goto close_it;
+
+file_not_symlink:
+ /* Not a symlink, see if executable. */
+ if (!(*pflags & PATH_ALL_EXEC) && has_exec_chars (file_header, got))
+ *pflags |= PATH_EXEC;
+
+close_it:
+ CloseHandle (h);
+ return res;
+}
+
+
static int
check_sysfile (const char *path, DWORD fileattr, HANDLE h,
char *contents, int *error, unsigned *pflags)
@@ -2956,8 +3037,8 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt)
/* Open the file. */
- h = CreateFileA (suffix.path, GENERIC_READ, FILE_SHARE_READ, &sec_none_nih, OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL, 0);
+ h = CreateFile (suffix.path, GENERIC_READ, FILE_SHARE_READ,
+ &sec_none_nih, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
res = -1;
if (h == INVALID_HANDLE_VALUE)
goto file_not_symlink;
diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h
index f9f55035e78..c8bb7ceadb9 100644
--- a/winsup/cygwin/path.h
+++ b/winsup/cygwin/path.h
@@ -170,6 +170,9 @@ class path_conv
/* Socket marker */
#define SOCKET_COOKIE "!<socket >"
+/* The sizeof header written to a shortcut by Cygwin or U/WIN. */
+#define SHORTCUT_HDR_SIZE 76
+
/* Maximum depth of symlinks (after which ELOOP is issued). */
#define MAX_LINK_DEPTH 10
int __stdcall slash_unc_prefix_p (const char *path) __attribute__ ((regparm(1)));
diff --git a/winsup/cygwin/shortcut.c b/winsup/cygwin/shortcut.c
deleted file mode 100644
index 55710e86b22..00000000000
--- a/winsup/cygwin/shortcut.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/* shortcut.c: Read shortcuts. This part of the code must be in C because
- the C++ interface to COM doesn't work without -fvtable-thunk
- which is too dangerous to use.
-
- 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. */
-
-#define WIN32_LEAN_AND_MEAN
-#include "winsup.h"
-#include <shlobj.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/mount.h>
-#include <errno.h>
-#include "shortcut.h"
-
-/* TODO:
- Currently duplicated from path.h. Later rearrangement of path.h
- to allow including from plain C would be better. */
-/* This is needed to avoid including path.h which is a pure C++ header. */
-#define PATH_SYMLINK MOUNT_SYMLINK
-#define PATH_EXEC MOUNT_EXEC
-#define PATH_CYGWIN_EXEC MOUNT_CYGWIN_EXEC
-#define PATH_ALL_EXEC (PATH_CYGWIN_EXEC | PATH_EXEC)
-
-/* TODO: Ditto. */
-static BOOL
-has_exec_chars (const char *buf, int len)
-{
- return len >= 2 &&
- ((buf[0] == '#' && buf[1] == '!') ||
- (buf[0] == ':' && buf[1] == '\n') ||
- (buf[0] == 'M' && buf[1] == 'Z'));
-}
-
-char shortcut_header[SHORTCUT_HDR_SIZE];
-BOOL shortcut_initalized;
-
-void
-create_shortcut_header (void)
-{
- if (!shortcut_initalized)
- {
- shortcut_header[0] = 'L';
- shortcut_header[4] = '\001';
- shortcut_header[5] = '\024';
- shortcut_header[6] = '\002';
- shortcut_header[12] = '\300';
- shortcut_header[19] = 'F';
- shortcut_header[20] = '\f';
- shortcut_header[60] = '\001';
- shortcut_initalized = TRUE;
- }
-}
-
-static BOOL
-cmp_shortcut_header (const char *file_header)
-{
- create_shortcut_header ();
- return memcmp (shortcut_header, file_header, SHORTCUT_HDR_SIZE);
-}
-
-int
-check_shortcut (const char *path, DWORD fileattr, HANDLE h,
- char *contents, int *error, unsigned *pflags)
-{
- HRESULT hres;
- IShellLink *psl = NULL;
- IPersistFile *ppf = NULL;
- WCHAR wc_path[MAX_PATH];
- char file_header[SHORTCUT_HDR_SIZE];
- DWORD len = 0;
- int res = 0;
- DWORD got = 0;
-
- /* Initialize COM library. */
- CoInitialize (NULL);
-
- /* Get a pointer to the IShellLink interface. */
- hres = CoCreateInstance (&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
- &IID_IShellLink, (void **)&psl);
- if (FAILED (hres))
- goto close_it;
- /* Get a pointer to the IPersistFile interface. */
- hres = psl->lpVtbl->QueryInterface (psl, &IID_IPersistFile, (void **)&ppf);
- if (FAILED (hres))
- goto close_it;
- /* Load the shortcut. */
- MultiByteToWideChar(CP_ACP, 0, path, -1, wc_path, MAX_PATH);
- hres = ppf->lpVtbl->Load (ppf, wc_path, STGM_READ);
- if (FAILED (hres))
- goto close_it;
- /* Read the files header information. This is used to check for a
- Cygwin or U/WIN shortcut or later to check for executable files. */
- if (!ReadFile (h, file_header, SHORTCUT_HDR_SIZE, &got, 0))
- {
- *error = EIO;
- goto close_it;
- }
- /* Try the description (containing a POSIX path) first. */
- if (fileattr & FILE_ATTRIBUTE_READONLY)
- {
- /* Check header if the shortcut is really created by Cygwin or U/WIN. */
- if (got == SHORTCUT_HDR_SIZE && !cmp_shortcut_header (file_header))
- {
- hres = psl->lpVtbl->GetDescription (psl, contents, MAX_PATH);
- if (FAILED (hres))
- goto file_not_symlink;
- len = strlen (contents);
- }
- }
-#if TREAT_NATIVE_SHORTCUTS_AS_SYMLINKS
- /* No description or not R/O: Check the "official" path. */
- if (len == 0)
- {
- char full_path[MAX_PATH];
- WIN32_FIND_DATA wfd;
-
- /* Convert to full path (easy way) */
- if ((path[0] == '\\' && path[1] == '\\')
- || (_toupper (path[0]) >= 'A' && _toupper (path[0]) <= 'Z'
- && path[1] == ':'))
- len = 0;
- else
- {
- len = GetCurrentDirectory (MAX_PATH, full_path);
- if (path[0] == '\\')
- len = 2;
- else if (full_path[len - 1] != '\\')
- strcpy (full_path + len++, "\\");
- }
- strcpy (full_path + len, path);
- /* Set relative path inside of IShellLink interface. */
- hres = psl->lpVtbl->SetRelativePath (psl, full_path, 0);
- if (FAILED (hres))
- goto file_not_symlink;
- /* Get the path to the shortcut target. */
- hres = psl->lpVtbl->GetPath (psl, contents, MAX_PATH, &wfd, 0);
- if (FAILED(hres))
- goto file_not_symlink;
- }
-#endif
- res = strlen (contents);
- if (res) /* It's a symlink. */
- *pflags = PATH_SYMLINK;
- goto close_it;
-
-file_not_symlink:
- /* Not a symlink, see if executable. */
- if (!(*pflags & PATH_ALL_EXEC) && has_exec_chars (file_header, got))
- *pflags |= PATH_EXEC;
-
-close_it:
- /* Release the pointer to IPersistFile. */
- if (ppf)
- ppf->lpVtbl->Release(ppf);
- /* Release the pointer to IShellLink. */
- if (psl)
- psl->lpVtbl->Release(psl);
- /* Uninitialize COM library. */
- CoUninitialize ();
- CloseHandle (h);
-
- return res;
-}
diff --git a/winsup/cygwin/shortcut.h b/winsup/cygwin/shortcut.h
deleted file mode 100644
index 447e320b4a4..00000000000
--- a/winsup/cygwin/shortcut.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* shortcut.h: Header file for shortcut.c
-
- 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. */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* The header written to a shortcut by Cygwin or U/WIN. */
-#define SHORTCUT_HDR_SIZE 76
-
-extern char shortcut_header[];
-extern BOOL shortcut_initalized;
-
-extern void create_shortcut_header ();
-
-int check_shortcut (const char *path, DWORD fileattr, HANDLE h,
- char *contents, int *error, unsigned *pflags);
-
-#ifdef __cplusplus
-};
-#endif
diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h
index 9e39728cca0..18aaf8a9e66 100644
--- a/winsup/cygwin/winsup.h
+++ b/winsup/cygwin/winsup.h
@@ -31,6 +31,10 @@ details. */
#define NEW_MACRO_VARARGS
#endif
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0500
+#endif
+
#include <sys/types.h>
#include <sys/strace.h>