diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 1fa72cd31..6d60f59ec 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,22 @@ +2000-12-09 Egor Duda + + * autoload.cc: Autoload CharToOemA. + * dcrt0.cc (dll_crt0_1): Translate command line to OEM if current + codepage is OEM. + * environ.cc: Add new option 'codepage' to CYGWIN environment variable. + * fhandler_clipboard.cc (fhandler_clipboard::read): Read clipboard in + OEM mode if current codepage is OEM. + * fhandler_console.cc (fhandler_console::read): Only translate console + input if current codepage is ANSI. + * fhandler_console.cc (fhandler_console::write_normal): Translate + output data if current codepage is ANSI. + * pinfo.cc (codepage_init): New function. Setup current codepage from + CYGWIN environment variable and set codepage for file APIs. + * security.cc (read_sd): Translate file name to it if current codepage + is OEM. + * winsup.h: (sys_wcstombs,sys_mbstowcs): Use current codepage for + translations between multibyte and widechar string and vice versa. + Sat Dec 9 16:29:45 2000 Christopher Faylor * path.cc (normalize_win32_path): Check for explicit use of two slashes diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index e82aa5a42..77c37249e 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -247,6 +247,7 @@ LoadDLLfuncEx (RtlNtStatusToDosError, 4, ntdll, 1) LoadDLLfuncEx (ZwQuerySystemInformation, 16, ntdll, 1) LoadDLLinit (user32) +LoadDLLfunc (CharToOemA, 8, user32) LoadDLLfunc (CharToOemBuffA, 12, user32) LoadDLLfunc (CloseClipboard, 0, user32) LoadDLLfunc (CreateWindowExA, 48, user32) diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 1acffca4c..d4a6bb952 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -15,6 +15,8 @@ details. */ #include "exceptions.h" #include #include +#include +#include #include "sync.h" #include "sigproc.h" #include "pinfo.h" @@ -55,6 +57,7 @@ per_thread NO_COPY *threadstuff[] = {&waitq_storage, BOOL display_title = FALSE; BOOL strip_title_path = FALSE; BOOL allow_glob = TRUE; +codepage_type current_codepage = ansi_cp; int cygwin_finished_initializing = 0; @@ -789,6 +792,9 @@ dll_crt0_1 () char *line = GetCommandLineA (); line = strcpy ((char *) alloca (strlen (line) + 1), line); + if (current_codepage == oem_cp) + CharToOemA ( line, line ); + /* Scan the command line and build argv. Expand wildcards if not called from another cygwin process. */ build_argv (line, __argv, __argc, diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc index f71ccd92d..615ce1726 100644 --- a/winsup/cygwin/environ.cc +++ b/winsup/cygwin/environ.cc @@ -1,7 +1,7 @@ /* environ.cc: Cygwin-adopted functions from newlib to manipulate process's environment. - Copyright 1997, 1998, 1999, 2000 Cygnus Solutions. + Copyright 1997, 1998, 1999, 2000 Red Hat, Inc. This software is a copyrighted work licensed under the terms of the Cygwin license. Please consult the file "CYGWIN_LICENSE" for @@ -42,12 +42,11 @@ static char **lastenviron = NULL; /* List of names which are converted from dos to unix - * on the way in and back again on the way out. - * - * PATH needs to be here because CreateProcess uses it and gdb uses - * CreateProcess. HOME is here because most shells use it and would be - * confused by Windows style path names. - */ + on the way in and back again on the way out. + + PATH needs to be here because CreateProcess uses it and gdb uses + CreateProcess. HOME is here because most shells use it and would be + confused by Windows style path names. */ static int return_MAX_PATH (const char *) {return MAX_PATH;} static win_env conv_envvars[] = { @@ -282,10 +281,7 @@ _addenv (const char *name, const char *value, int overwrite) return 0; } -/* putenv -- - * Sets an environment variable - */ - +/* putenv Sets an environment variable */ extern "C" int putenv (const char *str) { @@ -306,12 +302,8 @@ putenv (const char *str) return 0; } -/* - * setenv -- - * Set the value of the environment variable "name" to be - * "value". If overwrite is set, replace any current value. - */ - +/* setenv -- Set the value of the environment variable "name" to be + "value". If overwrite is set, replace any current value. */ extern "C" int setenv (const char *name, const char *value, int overwrite) { @@ -333,11 +325,7 @@ setenv (const char *name, const char *value, int overwrite) return _addenv (name, value, !!overwrite); } -/* - * unsetenv(name) -- - * Delete environment variable "name". - */ - +/* unsetenv(name) -- Delete environment variable "name". */ extern "C" void unsetenv (const char *name) { @@ -352,7 +340,6 @@ unsetenv (const char *name) } /* Turn environment variable part of a=b string into uppercase. */ - static __inline__ void ucenv (char *p, char *eq) { @@ -382,10 +369,9 @@ enum settings }; /* When BUF is: - * null or empty: disables globbing - * "ignorecase": enables case-insensitive globbing - * anything else: enables case-sensitive globbing - */ + null or empty: disables globbing + "ignorecase": enables case-insensitive globbing + anything else: enables case-sensitive globbing */ static void glob_init (const char *buf) { @@ -407,9 +393,8 @@ glob_init (const char *buf) } /* 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. - */ + parse the CYGWIN environment variable or, if enabled, options from + the registry. */ struct parse_thing { const char *name; @@ -431,6 +416,7 @@ struct parse_thing } known[] = { {"binmode", {x: &binmode}, justset, NULL, {{O_TEXT}, {O_BINARY}}}, + {"codepage", {func: &codepage_init}, isfunc, NULL, {{0}, {0}}}, {"envcache", {&envcache}, justset, NULL, {{TRUE}, {FALSE}}}, {"error_start", {func: &error_start_init}, isfunc, NULL, {{0}, {0}}}, {"export", {&export_settings}, justset, NULL, {{FALSE}, {TRUE}}}, @@ -446,8 +432,7 @@ struct parse_thing }; /* Parse a string of the form "something=stuff somethingelse=more-stuff", - * silently ignoring unknown "somethings". - */ + silently ignoring unknown "somethings". */ static void __stdcall parse_options (char *buf) { @@ -531,7 +516,6 @@ parse_options (char *buf) } /* Set options from the registry. */ - static void __stdcall regopt (const char *name) { @@ -557,8 +541,7 @@ regopt (const char *name) } /* Initialize the environ array. Look for the CYGWIN environment - * environment variable and set appropriate options from it. - */ + environment variable and set appropriate options from it. */ void environ_init (char **envp, int envc) { @@ -661,8 +644,7 @@ out: MALLOC_CHECK; } -/* Function called by qsort to sort environment strings. - */ +/* Function called by qsort to sort environment strings. */ static int env_sort (const void *a, const void *b) { @@ -673,10 +655,9 @@ env_sort (const void *a, const void *b) } /* Create a Windows-style environment block, i.e. a typical character buffer - * filled with null terminated strings, terminated by double null characters. - * Converts environment variables noted in conv_envvars into win32 form - * prior to placing them in the string. - */ + filled with null terminated strings, terminated by double null characters. + Converts environment variables noted in conv_envvars into win32 form + prior to placing them in the string. */ char * __stdcall winenv (const char * const *envp, int keep_posix) { diff --git a/winsup/cygwin/fhandler_clipboard.cc b/winsup/cygwin/fhandler_clipboard.cc index 9c7ba9565..7b6d05362 100644 --- a/winsup/cygwin/fhandler_clipboard.cc +++ b/winsup/cygwin/fhandler_clipboard.cc @@ -52,7 +52,7 @@ fhandler_dev_clipboard::read (void *ptr, size_t len) if (!clipboard_eof) { OpenClipboard(0); - hglb = GetClipboardData(CF_TEXT); + hglb = GetClipboardData((current_codepage==ansi_cp ? CF_TEXT : CF_OEMTEXT)); lpstr = (LPSTR) GlobalLock(hglb); if (len < sizeof (lpstr)) { diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index cfc569b29..270e3856a 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -217,7 +217,7 @@ fhandler_console::read (void *pv, size_t buflen) tmp[1] = ich; /* Need this check since US code page seems to have a bug when converting a CTRL-U. */ - if ((unsigned char)ich > 0x7f) + if ((unsigned char)ich > 0x7f && current_codepage == ansi_cp) OemToCharBuff (tmp + 1, tmp + 1, 1); if (!(input_rec.Event.KeyEvent.dwControlKeyState & LEFT_ALT_PRESSED)) toadd = tmp + 1; @@ -1163,7 +1163,10 @@ fhandler_console::write_normal (const unsigned char *src, size_t len = found - src; do { size_t l2 = min (sizeof (buf), len); - CharToOemBuff ((LPCSTR)src, buf, l2); + if (current_codepage == ansi_cp) + CharToOemBuff ((LPCSTR)src, buf, l2); + else + strncpy (buf, (LPCSTR)src, l2); if (! WriteFile (get_output_handle (), buf, l2, &done, 0)) { debug_printf ("write failed, handle %p", get_output_handle ()); diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index c2932fc98..eea05c03e 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -87,6 +87,31 @@ set_myself (pid_t pid, HANDLE h) return; } +extern "C" void +codepage_init (const char *buf) +{ + if (!buf || !*buf) + return; + + if ( strcmp ( buf, "oem" ) == 0 ) + { + current_codepage = oem_cp; + SetFileApisToOEM (); + debug_printf ( "File APIs set to OEM" ); + } + else if ( strcmp ( buf, "ansi" ) == 0 ) + { + current_codepage = ansi_cp; + SetFileApisToANSI (); + debug_printf ( "File APIs set to ANSI" ); + } + else + { + debug_printf ( "Wrong codepage name: %s", buf ); + } +} + + /* Initialize the process table entry for the current task. This is not called for fork'd tasks, only exec'd ones. */ void __stdcall diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc index 740c2fae3..04915781d 100644 --- a/winsup/cygwin/security.cc +++ b/winsup/cygwin/security.cc @@ -22,6 +22,8 @@ details. */ #include #include #include +#include +#include #include "cygerrno.h" #include "fhandler.h" #include "path.h" @@ -513,8 +515,18 @@ read_sd(const char *file, PSECURITY_DESCRIPTOR sd_buf, LPDWORD sd_size) debug_printf("file = %s", file); DWORD len = 0; - if (! GetFileSecurity (file, - OWNER_SECURITY_INFORMATION + const char *pfile = file; + char fbuf [PATH_MAX]; + if (current_codepage == oem_cp) + { + DWORD fname_len = min (sizeof (fbuf) - 1, strlen (file)); + bzero (fbuf, sizeof (fbuf)); + OemToCharBuff(file, fbuf, fname_len); + pfile = fbuf; + } + + if (! GetFileSecurity (pfile, + OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, sd_buf, *sd_size, &len)) diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h index 308620e34..d2f475ba2 100644 --- a/winsup/cygwin/winsup.h +++ b/winsup/cygwin/winsup.h @@ -83,13 +83,16 @@ extern "C" DWORD WINAPI GetLastError (void); enum os_type {winNT = 1, win95, win98, winME, win32s, unknown}; extern os_type os_being_run; +enum codepage_type {ansi_cp, oem_cp}; +extern codepage_type current_codepage; + /* Used to check if Cygwin DLL is dynamically loaded. */ extern int dynamically_loaded; #define sys_wcstombs(tgt,src,len) \ - WideCharToMultiByte(CP_ACP,0,(src),-1,(tgt),(len),NULL,NULL) + WideCharToMultiByte((current_codepage==ansi_cp?CP_ACP:CP_OEMCP),0,(src),-1,(tgt),(len),NULL,NULL) #define sys_mbstowcs(tgt,src,len) \ - MultiByteToWideChar(CP_ACP,0,(src),-1,(tgt),(len)) + MultiByteToWideChar((current_codepage==ansi_cp?CP_ACP:CP_OEMCP),0,(src),-1,(tgt),(len)) #define TITLESIZE 1024 #define MAX_USER_NAME 20 @@ -182,6 +185,8 @@ extern HANDLE netapi32_handle; extern "C" void error_start_init (const char*); extern "C" int try_to_debug (); +extern "C" void codepage_init (const char*); + extern int cygwin_finished_initializing; /**************************** Miscellaneous ******************************/