diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index ac02b4038..7b7843f93 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,27 @@ +Wed Nov 8 15:35:32 2000 Christopher Faylor + + * environ.cc (_addenv): malloc space for setenv if cygwin1.dll is used + in conjunction with older binaries. + (environ_init): Ditto. + +Wed Nov 8 08:49:27 2000 Jason Tishler + + * external.cc (get_cygdrive_info): New function. + * external.cc (get_cygdrive_prefixes): Change to use get_cygdrive_info + but toss the user and system flags. + * external.cc (cygwin_internal): Add new CW_GET_CYGDRIVE_INFO case. + * path.cc (mount_info::get_cygdrive_prefixes): Remove method. + * path.cc (mount_info::get_cygdrive_info): New method. Actually, + get_cygdrive_info is really an enhanced version of + get_cygdrive_prefixes renamed to get_cygdrive_info that also gets the + user and system flags. + * shared_info.h (get_cygdrive_prefixes): Remove method. + * shared_info.h (get_cygdrive_info): New method. + * include/cygwin/version.h: Bump minor API version due to adding + CW_GET_CYGDRIVE_INFO to cygwin_internal. + * include/sys/cygwin.h (cygwin_getinfo_types): Add + CW_GET_CYGDRIVE_INFO. + Tue Nov 7 20:58:00 2000 Corinna Vinschen * autoload.cc: Add autoload statement for `WSASetLastError'. diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc index 71acab5cb..3b67bc760 100644 --- a/winsup/cygwin/environ.cc +++ b/winsup/cygwin/environ.cc @@ -24,6 +24,7 @@ details. */ #include "cygheap.h" #include "registry.h" #include "environ.h" +#include "perprocess.h" extern BOOL allow_glob; extern BOOL allow_ntea; @@ -34,6 +35,11 @@ static BOOL envcache = TRUE; static char **lastenviron = NULL; +#define ENVMALLOC \ + (CYGWIN_VERSION_DLL_MAKE_COMBINED (user_data->api_major, user_data->api_minor) \ + <= CYGWIN_VERSION_DLL_MALLOC_ENV) + + /* List of names which are converted from dos to unix * on the way in and back again on the way out. * @@ -247,8 +253,8 @@ _addenv (const char *name, const char *value, int overwrite) char *envhere; if (!issetenv) - envhere = cur_environ ()[offset] = (char *) name; /* Not setenv. Just - overwrite existing. */ + /* Not setenv. Just overwrite existing. */ + envhere = cur_environ ()[offset] = (char *) (ENVMALLOC ? strdup (name) : name); else { /* setenv */ /* Look for an '=' in the name and ignore anything after that if found. */ @@ -566,7 +572,17 @@ environ_init (char **envp, int envc) char **newenv = (char **) malloc (envc); memcpy (newenv, envp, envc); cfree (envp); + + /* Older applications relied on the fact that cygwin malloced elements of the + environment list. */ envp = newenv; + if (ENVMALLOC) + for (char **e = newenv; *e; e++) + { + char *p = *e; + *e = strdup (p); + cfree (p); + } envp_passed_in = 1; goto out; } diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc index 0199aedd3..cf026eb20 100644 --- a/winsup/cygwin/external.cc +++ b/winsup/cygwin/external.cc @@ -88,13 +88,24 @@ fillout_pinfo (pid_t pid, int winpid) } static DWORD -get_cygdrive_prefixes (char *user, char *system) +get_cygdrive_info (char *user, char *system, char *user_flags, + char *system_flags) { shared_info *info = cygwin_getshared(); - int res = info->mount.get_cygdrive_prefixes(user, system); + int res = info->mount.get_cygdrive_info (user, system, user_flags, + system_flags); return (res == ERROR_SUCCESS) ? 1 : 0; } +static DWORD +get_cygdrive_prefixes (char *user, char *system) +{ + char user_flags[MAX_PATH]; + char system_flags[MAX_PATH]; + DWORD res = get_cygdrive_info (user, system, user_flags, system_flags); + return res; +} + extern "C" DWORD cygwin_internal (cygwin_getinfo_types t, ...) { @@ -151,6 +162,15 @@ cygwin_internal (cygwin_getinfo_types t, ...) init_exceptions ((exception_list *) arg); return 0; + case CW_GET_CYGDRIVE_INFO: + { + char *user = va_arg (arg, char *); + char *system = va_arg (arg, char *); + char *user_flags = va_arg (arg, char *); + char *system_flags = va_arg (arg, char *); + return get_cygdrive_info (user, system, user_flags, system_flags); + } + default: return (DWORD) -1; } diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index 7d60b9b46..904b7c97c 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -72,6 +72,7 @@ details. */ (CYGWIN_VERSION_DLL_MAKE_COMBINED (user_data->api_major, user_data->api_minor) <= \ CYGWIN_VERSION_DLL_OLD_TERMIOS) +#define CYGWIN_VERSION_DLL_MALLOC_ENV 28 /* Old APIs had getc/putc macros that conflict with new CR/LF handling in the stdio buffers */ #define CYGWIN_VERSION_OLD_STDIO_CRLF_HANDLING \ @@ -119,10 +120,11 @@ details. */ 27: CW_GETPINFO_FULL addition to external.cc 28: Accidentally bumped by cgf 29: Export hstrerror + 30: CW_GET_CYGDRIVE_INFO addition to external.cc */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 29 +#define CYGWIN_VERSION_API_MINOR 30 /* 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 b04ecc742..2b3370cfa 100644 --- a/winsup/cygwin/include/sys/cygwin.h +++ b/winsup/cygwin/include/sys/cygwin.h @@ -58,7 +58,8 @@ typedef enum CW_PERFILE, CW_GET_CYGDRIVE_PREFIXES, CW_GETPINFO_FULL, - CW_INIT_EXCEPTIONS + CW_INIT_EXCEPTIONS, + CW_GET_CYGDRIVE_INFO } cygwin_getinfo_types; #define CW_NEXTPID 0x80000000 // or with pid to get next one diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 94cfb5a9d..34a2b983b 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -1623,12 +1623,20 @@ mount_info::remove_cygdrive_info_from_registry (const char *cygdrive_prefix, uns } int -mount_info::get_cygdrive_prefixes (char *user, char *system) +mount_info::get_cygdrive_info (char *user, char *system, char* user_flags, + char* system_flags) { /* Get the user path prefix from HKEY_CURRENT_USER. */ reg_key r; int res = r.get_string (CYGWIN_INFO_CYGDRIVE_PREFIX, user, MAX_PATH, ""); + /* Get the user flags, if appropriate */ + if (res == ERROR_SUCCESS) + { + int flags = r.get_int (CYGWIN_INFO_CYGDRIVE_FLAGS, MOUNT_AUTO); + strcpy (user_flags, (flags & MOUNT_BINARY) ? "binmode" : "textmode"); + } + /* Get the system path prefix from HKEY_LOCAL_MACHINE. */ reg_key r2 (HKEY_LOCAL_MACHINE, KEY_ALL_ACCESS, "SOFTWARE", CYGWIN_INFO_CYGNUS_REGISTRY_NAME, @@ -1637,6 +1645,13 @@ mount_info::get_cygdrive_prefixes (char *user, char *system) NULL); int res2 = r2.get_string (CYGWIN_INFO_CYGDRIVE_PREFIX, system, MAX_PATH, ""); + /* Get the system flags, if appropriate */ + if (res2 == ERROR_SUCCESS) + { + int flags = r2.get_int (CYGWIN_INFO_CYGDRIVE_FLAGS, MOUNT_AUTO); + strcpy (system_flags, (flags & MOUNT_BINARY) ? "binmode" : "textmode"); + } + return (res != ERROR_SUCCESS) ? res : res2; } diff --git a/winsup/cygwin/shared_info.h b/winsup/cygwin/shared_info.h index 6434da255..4b4b2f82f 100644 --- a/winsup/cygwin/shared_info.h +++ b/winsup/cygwin/shared_info.h @@ -85,7 +85,8 @@ public: int write_cygdrive_info_to_registry (const char *cygdrive_prefix, unsigned flags); int remove_cygdrive_info_from_registry (const char *cygdrive_prefix, unsigned flags); - int get_cygdrive_prefixes (char *user, char *system); + int get_cygdrive_info (char *user, char *system, char* user_flags, + char* system_flags); void import_v1_mounts (); diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 8e2e490be..e17541446 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -511,7 +511,7 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv, cygcwd.copy (ciresrv.moreinfo->cwd_posix, ciresrv.moreinfo->cwd_win32, ciresrv.moreinfo->cwd_hash); - ciresrv.moreinfo->envc = envsize (envp, 0); + ciresrv.moreinfo->envc = envsize (envp, 1); ciresrv.moreinfo->envp = (char **) cmalloc (HEAP_1_ARGV, ciresrv.moreinfo->envc); ciresrv.hexec_proc = hexec_proc; char **c;