diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 0b5ce3f8e..4725a014b 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,48 @@ +Fri Jun 30 23:21:40 2000 Christopher Faylor + + * Makefile.in: Use variables rather than configure constructs where + appropriate. + (LIBCOS): Find additional stub library stuff in their own subdirectory. + * dcrt0.cc: Convert user_data pointer to static __cygwin_user_data + area. + (do_global_ctors): Check magic_bisquit for initialization. + (dll_crt0_1): First group of premain functions prior to fd + initialization. Run second group before calling main. + (dll_crt0 ()): New function, called from new initialization code. + (dll_crt0 (per_process *uptr)): Call new dll_crt0 () function on + initialization. + * debug.cc (thread_stub): Initialize bottom of stack with per-thread + info. + * environ.cc (parse_thing): Use binmode global to control + CYGWIN=binmode behavior. + * fhandler.cc (fhandler_base::open): Allow explicit setting of __fmode + to O_BINARY or O_TEXT to override disk mount settings. + * libcmain.cc: Move to lib subdirectory. + * libccrt0.cc: Ditto. + * dll_main.cc: Ditto. + * dll_entry.cc: Ditto. + * getopt.c: Ditto. + * thread.cc (thread_init_wrapper): Call ExitThread explicitly rather + than returning, as a preliminary step towards placing per thread info + at the bottom of the stack. + * winsup.h: Move per_process class to include/sys/cygwin.h. Declare + new dll_crt0(). + * include/cygwin/version.h: Bump API minor version. + * binmode.c: New file. + * textmode.c: Ditto. + * lib/_cygwin_crt0_common.cc: Ditto. + * lib/crt0.h: Ditto. + * lib/cygwin_attach_dll.c: Ditto. + * lib/cygwin_crt0.c: Ditto. + * lib/dll_entry.cc: Ditto. + * lib/dll_main.cc: Ditto. + * lib/getopt.c: Ditto. + * lib/libcmain.c: Ditto. + * lib/premain0.c: Ditto. + * lib/premain1.c: Ditto. + * lib/premain2.c: Ditto. + * lib/premain3.c: Ditto. + Wed Jun 28 19:36:00 2000 Corinna Vinschen * syscalls.cc (seteuid): Initialize pi.token before calling diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index 97f568796..263d0ad28 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -9,12 +9,13 @@ # This makefile requires GNU make. -CONFIG_DIR:=@srcdir@/config/@CONFIG_DIR@ SHELL:=@SHELL@ -VPATH:=@srcdir@:$(CONFIG_DIR):@srcdir@/regexp srcdir:=@srcdir@ objdir:=. +CONFIG_DIR:=$(srcdir)/config/@CONFIG_DIR@ +VPATH:=$(srcdir):$(CONFIG_DIR):$(srcdir)/regexp:$(srcdir)/lib + target_alias:=@target_alias@ build_alias:=@build_alias@ host_alias:=@host_alias@ @@ -106,7 +107,8 @@ GMON_START:=gcrt0.o # data which apps can get to, which is a pain in the dll, so we # include them directly into the library. -LIBCOS:=libccrt0.o libcmain.o getopt.o dll_entry.o dll_main.o +LIBCOS:=${sort ${addsuffix .o,${basename ${notdir ${wildcard $(srcdir)/lib/*.c}}}} \ + ${addsuffix .o,${basename ${notdir ${wildcard $(srcdir)/lib/*.cc}}}}} # Build all source files in the config directory @@ -143,7 +145,7 @@ install_host=@install_host@ all: new-$(DLL_NAME) $(all_host) all_target -all_target: $(LIBGMON_A) $(LIB_NAME) +all_target: $(LIBGMON_A) $(LIB_NAME) binmode.o textmode.o all_host: new-$(LIB_NAME) cygrun.exe @@ -151,7 +153,7 @@ force: install: all $(install_host) $(install_target) $(INSTALL_DATA) new-$(DLL_NAME) $(bindir)/$(DLL_NAME); \ - for i in $(LIB_NAME) $(GMON_START) $(LIBGMON_A) ; do \ + for i in $(LIB_NAME) $(GMON_START) $(LIBGMON_A) binmode.o ; do \ $(INSTALL_DATA) $$i $(tooldir)/lib/$$i ; \ done ; \ cd $(srcdir); \ diff --git a/winsup/cygwin/binmode.c b/winsup/cygwin/binmode.c new file mode 100644 index 000000000..b49842032 --- /dev/null +++ b/winsup/cygwin/binmode.c @@ -0,0 +1,19 @@ +/* binmode.c + + 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. */ + +#include + +extern int _fmode; +void +cygwin_premain0(int argc, char **argv) +{ + _fmode &= _O_TEXT; + _fmode |= _O_BINARY; +} diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din index 84f75192a..f69659fdd 100644 --- a/winsup/cygwin/cygwin.din +++ b/winsup/cygwin/cygwin.din @@ -124,6 +124,7 @@ difftime _difftime = difftime div _div = div +dll_crt0@0 dll_crt0__FP11per_process cygwin_dll_init dll_dllcrt0 @@ -1006,6 +1007,7 @@ getpgid killpg pause __cygwin_environ DATA +__cygwin_user_data DATA _ctype_ DATA _sys_errlist DATA _sys_nerr DATA diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 801016a31..6cfc60820 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -19,14 +19,13 @@ details. */ #define MAX_AT_FILE_LEVEL 10 +#define PREMAIN_LEN (sizeof(user_data->premain) / sizeof (user_data->premain[0])) + HANDLE NO_COPY hMainProc = NULL; HANDLE NO_COPY hMainThread = NULL; sigthread NO_COPY mainthread; // ID of the main thread -static NO_COPY char dummy_user_data[sizeof (per_process)] = {0}; -per_process NO_COPY *user_data = (per_process *) &dummy_user_data; - per_thread_waitq NO_COPY waitq_storage; per_thread_vfork NO_COPY vfork_storage; per_thread_signal_dispatch NO_COPY signal_dispatch_storage; @@ -56,12 +55,11 @@ extern "C" which use cygwin.dll. */ char **__cygwin_environ; /* __progname used in getopt error message */ - char *__progname; + char *__progname = NULL; struct _reent reent_data; + struct per_process __cygwin_user_data; }; -static void dll_crt0_1 (); - char *old_title = NULL; char title_buf[TITLESIZE + 1]; @@ -96,13 +94,12 @@ do_global_ctors (void (**in_pfunc)(), int force) while (--pfunc > in_pfunc) (*pfunc) (); - if (user_data != (per_process *) &dummy_user_data) + if (user_data->magic_biscuit == SIZEOF_PER_PROCESS) 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]; /* set_os_type: Set global variable os_being_run with type of Win32 @@ -576,7 +573,6 @@ dll_crt0_1 () be on the stack. */ /* FIXME: Verify forked children get their exception handler set up ok. */ exception_list cygwin_except_entry; - do_global_ctors (&__CTOR_LIST__, 1); #ifdef DEBUGGING @@ -734,6 +730,10 @@ dll_crt0_1 () /* Connect to tty. */ tty_init (); + if (user_data->premain[0]) + for (unsigned int i = 0; i < PREMAIN_LEN / 2; i++) + user_data->premain[i] (argc, argv); + /* Set up standard fds in file descriptor table. */ hinfo_init (); @@ -758,13 +758,18 @@ dll_crt0_1 () DllList::the().initAll(); set_errno (0); - debug_printf ("user_data->main %p", user_data->main); /* Flush signals and ensure that signal thread is up and running. Can't do this for noncygwin case since the signal thread is blocked due to LoadLibrary serialization. */ sig_send (NULL, __SIGFLUSH); /* also initializes uid, gid */ + /* Execute any specified "premain" functions */ + if (user_data->premain[0]) + for (unsigned int i = PREMAIN_LEN / 2; i < PREMAIN_LEN; i++) + user_data->premain[i] (argc, argv); + + debug_printf ("user_data->main %p", user_data->main); if (user_data->main) exit (user_data->main (argc, argv, *user_data->envptr)); } @@ -775,12 +780,20 @@ dll_crt0_1 () UPTR is a pointer to global data that lives on the libc side of the line [if one distinguishes the application from the dll]. */ -void -dll_crt0 (per_process *uptr) +void __stdcall +dll_crt0 () { char zeros[sizeof (ciresrv->zero)] = {0}; - /* Set the local copy of the pointer into the user space. */ - user_data = uptr; + +#ifdef DEBUGGING + char buf[80]; + if (GetEnvironmentVariable ("CYGWIN_SLEEP", buf, sizeof (buf))) + { + small_printf ("Sleeping %d, pid %u\n", atoi (buf), GetCurrentProcessId ()); + Sleep (atoi(buf)); + } +#endif + user_data->heapbase = user_data->heapptr = user_data->heaptop = NULL; set_console_handler (); @@ -845,6 +858,15 @@ dll_crt0 (per_process *uptr) dll_crt0_1 (); } +void +dll_crt0 (per_process *uptr) +{ + /* Set the local copy of the pointer into the user space. */ + if (uptr) + *user_data = *uptr; + dll_crt0 (); +} + extern "C" void *export_malloc (unsigned int); extern "C" void export_free (void *); extern "C" void *export_realloc (void *, unsigned int); diff --git a/winsup/cygwin/debug.cc b/winsup/cygwin/debug.cc index ecc689d8f..509f98d91 100644 --- a/winsup/cygwin/debug.cc +++ b/winsup/cygwin/debug.cc @@ -9,6 +9,7 @@ details. */ #define NO_DEBUG_DEFINES #include "winsup.h" #include "exceptions.h" +#include "perthread.h" static muto NO_COPY *threadname_lock = NULL; #define lock_threadname() \ @@ -82,11 +83,12 @@ thread_stub (VOID *arg) /* Give up our slot in the start_buf array */ InterlockedExchange (&((thread_start *) arg)->notavail, 0); - /* Initialize this threads ability to respond to things like + /* Initialize this thread's ability to respond to things like SIGSEGV or SIGFPE. */ init_exceptions (&except_entry); - return threadfunc (threadarg); + set_reent (&reent_data); + ExitThread (threadfunc (threadarg)); } /* Wrapper for CreateThread. Registers the thread name/id and ensures that diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc index 494775219..719a1712b 100644 --- a/winsup/cygwin/environ.cc +++ b/winsup/cygwin/environ.cc @@ -19,6 +19,7 @@ extern BOOL allow_glob; extern BOOL allow_ntea; extern BOOL strip_title_path; extern DWORD chunksize; +extern BOOL binmode; BOOL threadsafe; BOOL reset_com = TRUE; static BOOL envcache = TRUE; @@ -322,7 +323,7 @@ struct parse_thing } values[2]; } known[] = { - {"binmode", {&__fmode}, justset, NULL, {{O_TEXT}, {O_BINARY}}}, + {"binmode", {&binmode}, justset, NULL, {{FALSE}, {TRUE}}}, {"envcache", {&envcache}, justset, NULL, {{TRUE}, {FALSE}}}, {"error_start", {func: &error_start_init}, isfunc, NULL, {{0}, {0}}}, {"export", {&export_settings}, justset, NULL, {{FALSE}, {TRUE}}}, diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index b2a8054a0..c68ac0d04 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -18,6 +18,8 @@ static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */ static char fhandler_disk_dummy_name[] = "some disk file"; +DWORD binmode; + int fhandler_base::puts_readahead (const char *s, size_t len = (size_t) -1) { @@ -352,10 +354,14 @@ fhandler_base::open (int flags, mode_t mode) int bin; if (flags & (O_BINARY | O_TEXT)) bin = flags & O_TEXT ? 0 : O_BINARY; + else if (__fmode & O_BINARY) + bin = O_BINARY; + else if (__fmode & O_TEXT) + bin = O_TEXT; else if (get_device () == FH_DISK) bin = get_w_binary () || get_r_binary (); else - bin = (__fmode & O_BINARY) || get_w_binary () || get_r_binary (); + bin = binmode || get_w_binary () || get_r_binary (); set_r_binary (bin); set_w_binary (bin); diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index 2143bbba4..334a719ea 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -111,10 +111,12 @@ details. */ getuid, getgid return real uid/gid. seteuid, setegid set only effective uid/gid. setuid, setgid set effective and real uid/gid. + 23: Export new dll_crt0 interface and cygwin_user_data for use + with crt0 startup code. */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 22 +#define CYGWIN_VERSION_API_MINOR 23 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible diff --git a/winsup/cygwin/include/sys/cygwin.h b/winsup/cygwin/include/sys/cygwin.h index cd563ff70..ff7821299 100644 --- a/winsup/cygwin/include/sys/cygwin.h +++ b/winsup/cygwin/include/sys/cygwin.h @@ -36,8 +36,105 @@ extern void cygwin_premain1 (int argc, char **argv); extern void cygwin_premain2 (int argc, char **argv); extern void cygwin_premain3 (int argc, char **argv); -#ifdef WINVER +#ifdef __cplusplus +/* This lives in the app and is initialized before jumping into the DLL. + It should only contain stuff which the user's process needs to see, or + which is needed before the user pointer is initialized, or is needed to + carry inheritance information from parent to child. Note that it cannot + be used to carry inheritance information across exec! + + Remember, this structure is linked into the application's executable. + Changes to this can invalidate existing executables, so we go to extra + lengths to avoid having to do it. + + When adding/deleting members, remember to adjust {public,internal}_reserved. + The size of the class shouldn't change [unless you really are prepared to + invalidate all existing executables]. The program does a check (using + SIZEOF_PER_PROCESS) to make sure you remember to make the adjustment. +*/ + +class per_process +{ + public: + char *initial_sp; + + /* The offset of these 3 values can never change. */ + /* magic_biscuit is the size of this class and should never change. */ + unsigned long magic_biscuit; + unsigned long dll_major; + unsigned long dll_minor; + + struct _reent **impure_ptr_ptr; + char ***envptr; + + /* Used to point to the memory machine we should use. Usually these + point back into the dll, but they can be overridden by the user. */ + void *(*malloc)(size_t); + void (*free)(void *); + void *(*realloc)(void *, size_t); + + int *fmode_ptr; + + int (*main)(int, char **, char **); + void (**ctors)(void); + void (**dtors)(void); + + /* For fork */ + void *data_start; + void *data_end; + void *bss_start; + void *bss_end; + + void *(*calloc)(size_t, size_t); + /* For future expansion of values set by the app. */ + void (*premain[4]) (int, char **); + + /* The rest are *internal* to cygwin.dll. + Those that are here because we want the child to inherit the value from + the parent (which happens when bss is copied) are marked as such. */ + + /* non-zero of ctors have been run. Inherited from parent. */ + int run_ctors_p; + + /* These will be non-zero if the above (malloc,free,realloc) have been + overridden. */ + /* FIXME: not currently used */ + int __imp_malloc; + int __imp_free; + int __imp_realloc; + + /* Heap management. Inherited from parent. */ + void *heapbase; /* bottom of the heap */ + void *heapptr; /* current index into heap */ + void *heaptop; /* current top of heap */ + + HANDLE unused1; /* unused */ + + /* Non-zero means the task was forked. The value is the pid. + Inherited from parent. */ + int forkee; + + HMODULE hmodule; + + DWORD api_major; /* API version that this program was */ + DWORD api_minor; /* linked with */ + /* For future expansion, so apps won't have to be relinked if we + add an item. */ +#ifdef _MT_SAFE + ResourceLocks *resourcelocks; + MTinterface *threadinterface; + void *internal_reserved[6]; +#else + void *internal_reserved[8]; +#endif +}; +#endif /* __cplusplus */ + +#ifdef _PATH_PASSWD extern HANDLE cygwin_logon_user (const struct passwd *, const char *); +#endif + +#ifdef WINVER extern void cygwin_set_impersonation_token (const HANDLE); /* included if is included */ diff --git a/winsup/cygwin/lib/_cygwin_crt0_common.cc b/winsup/cygwin/lib/_cygwin_crt0_common.cc new file mode 100644 index 000000000..ca249c69b --- /dev/null +++ b/winsup/cygwin/lib/_cygwin_crt0_common.cc @@ -0,0 +1,76 @@ +/* common.cc: common crt0 function for cygwin crt0's. + + Copyright 2000 Cygnus Solutions. + +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" +#include "crt0.h" +#include +#include + +extern __declspec(dllimport) per_process __cygwin_user_data; + +extern "C" +{ +char **environ; +void cygwin_crt0 (MainFunc); +int cygwin_attach_dll (HMODULE, MainFunc); +int cygwin_attach_noncygwin_dll (HMODULE, MainFunc); +int main (int, char **, char **); +struct _reent *_impure_ptr; +int _fmode; + +/* Set up pointers to various pieces so the dll can then use them, + and then jump to the dll. */ + +void +_cygwin_crt0_common (MainFunc f) +{ + /* This is used to record what the initial sp was. The value is needed + when copying the parent's stack to the child during a fork. */ + int onstack; + + /* The version numbers are the main source of compatibility checking. + As a backup to them, we use the size of the per_process struct. */ + __cygwin_user_data.magic_biscuit = sizeof (per_process); + + /* cygwin.dll version number in effect at the time the app was created. */ + __cygwin_user_data.dll_major = CYGWIN_VERSION_DLL_MAJOR; + __cygwin_user_data.dll_minor = CYGWIN_VERSION_DLL_MINOR; + __cygwin_user_data.api_major = CYGWIN_VERSION_API_MAJOR; + __cygwin_user_data.api_minor = CYGWIN_VERSION_API_MINOR; + + __cygwin_user_data.ctors = &__CTOR_LIST__; + __cygwin_user_data.dtors = &__DTOR_LIST__; + __cygwin_user_data.envptr = &environ; + __cygwin_user_data.impure_ptr_ptr = &_impure_ptr; + __cygwin_user_data.main = f; + __cygwin_user_data.premain[0] = cygwin_premain0; + __cygwin_user_data.premain[1] = cygwin_premain1; + __cygwin_user_data.premain[2] = cygwin_premain2; + __cygwin_user_data.premain[3] = cygwin_premain3; + __cygwin_user_data.fmode_ptr = &_fmode; + __cygwin_user_data.initial_sp = (char *) &onstack; + + /* Remember whatever the user linked his application with - or + point to entries in the dll. */ + __cygwin_user_data.malloc = &malloc; + __cygwin_user_data.free = &free; + __cygwin_user_data.realloc = &realloc; + __cygwin_user_data.calloc = &calloc; + + /* Setup the module handle so fork can get the path name. */ + __cygwin_user_data.hmodule = GetModuleHandle (0); + + /* variables for fork */ + __cygwin_user_data.data_start = &_data_start__; + __cygwin_user_data.data_end = &_data_end__; + __cygwin_user_data.bss_start = &_bss_start__; + __cygwin_user_data.bss_end = &_bss_end__; +} +} /* "C" */ diff --git a/winsup/cygwin/lib/crt0.h b/winsup/cygwin/lib/crt0.h new file mode 100644 index 000000000..74c2c4be4 --- /dev/null +++ b/winsup/cygwin/lib/crt0.h @@ -0,0 +1,22 @@ +/* crt0.h: header file for crt0. + + Copyright 2000 Cygnus Solutions. + +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 + +struct per_process; +typedef int (*MainFunc) (int argc, char *argv[], char **env); +void _cygwin_crt0_common (MainFunc); +int dll_dllcrt0 (HMODULE, struct per_process *); + +#ifdef __cplusplus +} +#endif diff --git a/winsup/cygwin/lib/cygwin_attach_dll.c b/winsup/cygwin/lib/cygwin_attach_dll.c new file mode 100644 index 000000000..18d9d7fad --- /dev/null +++ b/winsup/cygwin/lib/cygwin_attach_dll.c @@ -0,0 +1,22 @@ +/* attach_dll.cc: crt0 for attaching cygwin DLL from a non-cygwin app. + + Copyright 2000 Cygnus Solutions. + +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 +#include "crt0.h" + +/* for a loaded dll */ +int +cygwin_attach_dll (HMODULE h, MainFunc f) +{ + _cygwin_crt0_common (f); + + /* jump into the dll. */ + return dll_dllcrt0 (h, NULL); +} diff --git a/winsup/cygwin/lib/cygwin_crt0.c b/winsup/cygwin/lib/cygwin_crt0.c new file mode 100644 index 000000000..deed1a054 --- /dev/null +++ b/winsup/cygwin/lib/cygwin_crt0.c @@ -0,0 +1,24 @@ +/* crt0.cc: crt0 for libc + + Copyright 2000 Cygnus Solutions. + +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 +#include "crt0.h" + +extern void __stdcall dll_crt0 (void) __declspec (dllimport); + +/* for main module */ +void +cygwin_crt0 (MainFunc f) +{ + _cygwin_crt0_common (f); + + /* Jump into the dll. */ + dll_crt0 (); +} diff --git a/winsup/cygwin/dll_entry.cc b/winsup/cygwin/lib/dll_entry.c similarity index 100% rename from winsup/cygwin/dll_entry.cc rename to winsup/cygwin/lib/dll_entry.c diff --git a/winsup/cygwin/dll_main.cc b/winsup/cygwin/lib/dll_main.cc similarity index 99% rename from winsup/cygwin/dll_main.cc rename to winsup/cygwin/lib/dll_main.cc index 44ed13e55..43a3c32de 100644 --- a/winsup/cygwin/dll_main.cc +++ b/winsup/cygwin/lib/dll_main.cc @@ -39,4 +39,3 @@ DllMain ( } return TRUE; } - diff --git a/winsup/cygwin/libc/getopt.c b/winsup/cygwin/lib/getopt.c similarity index 100% rename from winsup/cygwin/libc/getopt.c rename to winsup/cygwin/lib/getopt.c diff --git a/winsup/cygwin/libcmain.cc b/winsup/cygwin/lib/libcmain.c similarity index 76% rename from winsup/cygwin/libcmain.cc rename to winsup/cygwin/lib/libcmain.c index a8ae34139..c2b3ef0d3 100644 --- a/winsup/cygwin/libcmain.cc +++ b/winsup/cygwin/lib/libcmain.c @@ -1,6 +1,6 @@ -/* libcmain.cc +/* libcmain.c - Copyright 1996, 1997, 1998 Cygnus Solutions. + Copyright 1996, 1997, 1998, 2000 Cygnus Solutions. This file is part of Cygwin. @@ -11,7 +11,8 @@ details. */ #include /* Allow apps which don't have a main work, as long as they define WinMain */ -extern "C" int main () +int +main () { HMODULE x = GetModuleHandleA(0); char *s = GetCommandLineA (); @@ -27,8 +28,8 @@ extern "C" int main () GetStartupInfo (&si); - WinMain (x, 0, s, - ((si.dwFlags & STARTF_USESHOWWINDOW) != 0 - ? si.wShowWindow - : SW_SHOWNORMAL)); + return WinMain (x, 0, s, + ((si.dwFlags & STARTF_USESHOWWINDOW) != 0 + ? si.wShowWindow + : SW_SHOWNORMAL)); } diff --git a/winsup/cygwin/lib/premain0.c b/winsup/cygwin/lib/premain0.c new file mode 100644 index 000000000..b77e02e8e --- /dev/null +++ b/winsup/cygwin/lib/premain0.c @@ -0,0 +1,14 @@ +/* premain0.c + + 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. */ + +void +cygwin_premain0(int argc, char **argv) +{ +} diff --git a/winsup/cygwin/lib/premain1.c b/winsup/cygwin/lib/premain1.c new file mode 100644 index 000000000..99aeac916 --- /dev/null +++ b/winsup/cygwin/lib/premain1.c @@ -0,0 +1,14 @@ +/* premain1.c + + 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. */ + +void +cygwin_premain1(int argc, char **argv) +{ +} diff --git a/winsup/cygwin/lib/premain2.c b/winsup/cygwin/lib/premain2.c new file mode 100644 index 000000000..a89e76ec3 --- /dev/null +++ b/winsup/cygwin/lib/premain2.c @@ -0,0 +1,14 @@ +/* premain2.c + + 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. */ + +void +cygwin_premain2(int argc, char **argv) +{ +} diff --git a/winsup/cygwin/lib/premain3.c b/winsup/cygwin/lib/premain3.c new file mode 100644 index 000000000..c5b99b918 --- /dev/null +++ b/winsup/cygwin/lib/premain3.c @@ -0,0 +1,14 @@ +/* premain3.c + + 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. */ + +void +cygwin_premain3(int argc, char **argv) +{ +} diff --git a/winsup/cygwin/libccrt0.cc b/winsup/cygwin/libccrt0.cc deleted file mode 100644 index 6f7d534b8..000000000 --- a/winsup/cygwin/libccrt0.cc +++ /dev/null @@ -1,95 +0,0 @@ -/* libccrt0.cc: crt0 for libc [newlib calls this one] - - Copyright 1996, 1998, 1999, 2000 Cygnus Solutions. - -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. */ - -#undef MALLOC_DEBUG - -#include "winsup.h" -#include -#include - -typedef int (*MainFunc) (int argc, char *argc[], char **env); - -extern "C" -{ - char **environ; - void cygwin_crt0 (MainFunc); - int cygwin_attach_dll (HMODULE, MainFunc); - int cygwin_attach_noncygwin_dll (HMODULE, MainFunc); - int main (int, char **, char **); - struct _reent *_impure_ptr; - int _fmode; -}; - -static per_process this_proc; - -/* Set up pointers to various pieces so the dll can then use them, - and then jump to the dll. */ - -static void -cygwin_crt0_common (MainFunc f) -{ - /* This is used to record what the initial sp was. The value is needed - when copying the parent's stack to the child during a fork. */ - int onstack; - - /* The version numbers are the main source of compatibility checking. - As a backup to them, we use the size of the per_process struct. */ - this_proc.magic_biscuit = sizeof (per_process); - - /* cygwin.dll version number in effect at the time the app was created. */ - this_proc.dll_major = CYGWIN_VERSION_DLL_MAJOR; - this_proc.dll_minor = CYGWIN_VERSION_DLL_MINOR; - this_proc.api_major = CYGWIN_VERSION_API_MAJOR; - this_proc.api_minor = CYGWIN_VERSION_API_MINOR; - - this_proc.ctors = &__CTOR_LIST__; - this_proc.dtors = &__DTOR_LIST__; - this_proc.envptr = &environ; - this_proc.impure_ptr_ptr = &_impure_ptr; - this_proc.main = f; - this_proc.fmode_ptr = &_fmode; - this_proc.initial_sp = (char *) &onstack; - - /* Remember whatever the user linked his application with - or - point to entries in the dll. */ - this_proc.malloc = &malloc; - this_proc.free = &free; - this_proc.realloc = &realloc; - this_proc.calloc = &calloc; - - /* Setup the module handle so fork can get the path name. */ - this_proc.hmodule = GetModuleHandle (0); - - /* variables for fork */ - this_proc.data_start = &_data_start__; - this_proc.data_end = &_data_end__; - this_proc.bss_start = &_bss_start__; - this_proc.bss_end = &_bss_end__; -} - -/* for main module */ -void -cygwin_crt0 (MainFunc f) -{ - cygwin_crt0_common (f); - - /* Jump into the dll. */ - dll_crt0 (&this_proc); -} - -/* for a loaded dll */ -int -cygwin_attach_dll (HMODULE h, MainFunc f) -{ - cygwin_crt0_common (f); - - /* jump into the dll. */ - return dll_dllcrt0 (h, &this_proc); -} diff --git a/winsup/cygwin/textmode.c b/winsup/cygwin/textmode.c new file mode 100644 index 000000000..83766a2c5 --- /dev/null +++ b/winsup/cygwin/textmode.c @@ -0,0 +1,19 @@ +/* binmode.c + + 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. */ + +#include + +extern int _fmode; +void +cygwin_premain0(int argc, char **argv) +{ + _fmode &= _O_BINARY; + _fmode |= _O_TEXT; +} diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index ee18948de..5c4b40275 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -524,7 +524,7 @@ thread_init_wrapper (void *_arg) // thread->used = false; // release thread entry thread->return_ptr = ret; - return ret; + ExitThread (0); } int diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h index 29eca9dcc..714955a5a 100644 --- a/winsup/cygwin/winsup.h +++ b/winsup/cygwin/winsup.h @@ -93,99 +93,8 @@ extern HANDLE hMainProc; /********************** Application Interface **************************/ -/* This lives in the app and is initialized before jumping into the DLL. - It should only contain stuff which the user's process needs to see, or - which is needed before the user pointer is initialized, or is needed to - carry inheritance information from parent to child. Note that it cannot - be used to carry inheritance information across exec! - - Remember, this structure is linked into the application's executable. - Changes to this can invalidate existing executables, so we go to extra - lengths to avoid having to do it. - - When adding/deleting members, remember to adjust {public,internal}_reserved. - The size of the class shouldn't change [unless you really are prepared to - invalidate all existing executables]. The program does a check (using - SIZEOF_PER_PROCESS) to make sure you remember to make the adjustment. -*/ - -class per_process -{ - public: - char *initial_sp; - - /* The offset of these 3 values can never change. */ - /* magic_biscuit is the size of this class and should never change. */ - DWORD magic_biscuit; - DWORD dll_major; - DWORD dll_minor; - - struct _reent **impure_ptr_ptr; - char ***envptr; - - /* Used to point to the memory machine we should use. Usually these - point back into the dll, but they can be overridden by the user. */ - void *(*malloc)(size_t); - void (*free)(void *); - void *(*realloc)(void *, size_t); - - int *fmode_ptr; - - int (*main)(int, char **, char **); - void (**ctors)(void); - void (**dtors)(void); - - /* For fork */ - void *data_start; - void *data_end; - void *bss_start; - void *bss_end; - - void *(*calloc)(size_t, size_t); - /* For future expansion of values set by the app. */ - void (*premain[4]) (int, char **); - - /* The rest are *internal* to cygwin.dll. - Those that are here because we want the child to inherit the value from - the parent (which happens when bss is copied) are marked as such. */ - - /* non-zero of ctors have been run. Inherited from parent. */ - int run_ctors_p; - - /* These will be non-zero if the above (malloc,free,realloc) have been - overridden. */ - /* FIXME: not currently used */ - int __imp_malloc; - int __imp_free; - int __imp_realloc; - - /* Heap management. Inherited from parent. */ - void *heapbase; /* bottom of the heap */ - void *heapptr; /* current index into heap */ - void *heaptop; /* current top of heap */ - - HANDLE unused1; /* unused */ - - /* Non-zero means the task was forked. The value is the pid. - Inherited from parent. */ - int forkee; - - HMODULE hmodule; - - DWORD api_major; /* API version that this program was */ - DWORD api_minor; /* linked with */ - /* For future expansion, so apps won't have to be relinked if we - add an item. */ -#ifdef _MT_SAFE - ResourceLocks *resourcelocks; - MTinterface *threadinterface; - void *internal_reserved[6]; -#else - void *internal_reserved[8]; -#endif -}; - -extern per_process *user_data; /* Pointer into application's static data */ +extern "C" per_process __cygwin_user_data; /* Pointer into application's static data */ +#define user_data (&__cygwin_user_data) /* We use the following to test that sizeof hasn't changed. When adding or deleting members, insert fillers or use the reserved entries. @@ -363,9 +272,10 @@ extern unsigned int signal_shift_subtract; /* cygwin .dll initialization */ void dll_crt0 (per_process *); +void __stdcall dll_crt0 () __asm__ ("dll_crt0"); /* dynamically loaded dll initialization */ -extern "C" int dll_dllcrt0 (HMODULE,per_process*); +extern "C" int dll_dllcrt0 (HMODULE, per_process*); /* dynamically loaded dll initialization for non-cygwin apps */ extern "C" int dll_noncygwin_dllcrt0 (HMODULE, per_process *);