From b9cf88ddbaf6c95a05a2c7b3fb044575f2bdb9f9 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Thu, 9 Jun 2011 17:50:41 +0000 Subject: [PATCH] * environ.c: Move code earlier to allow: (_addenv): Call parse_options() when CYGWIN environment variable is being changed. (parse_options): Change parameter to 'const'. --- winsup/cygwin/ChangeLog | 7 + winsup/cygwin/environ.cc | 358 ++++++++++++++++++++------------------- 2 files changed, 187 insertions(+), 178 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 18a997953..74fe237aa 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,10 @@ +2011-06-09 Christopher Faylor + + * environ.c: Move code earlier to allow: + (_addenv): Call parse_options() when CYGWIN environment variable is + being changed. + (parse_options): Change parameter to 'const'. + 2011-06-08 Christopher Faylor * environ.cc (tty_is_gone): Add missing space to message. diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc index 5e994652e..3e71cbf2c 100644 --- a/winsup/cygwin/environ.cc +++ b/winsup/cygwin/environ.cc @@ -41,6 +41,184 @@ static bool create_upcaseenv = false; static char **lastenviron; +/* Parse CYGWIN options */ + +static NO_COPY bool export_settings = false; + +enum settings + { + justset, + isfunc, + setbit + }; + +/* When BUF is: + null or empty: disables globbing + "ignorecase": enables case-insensitive globbing + anything else: enables case-sensitive globbing */ +static void +glob_init (const char *buf) +{ + if (!buf || !*buf) + { + allow_glob = false; + ignore_case_with_glob = false; + } + else if (ascii_strncasematch (buf, "ignorecase", 10)) + { + allow_glob = true; + ignore_case_with_glob = true; + } + else + { + allow_glob = true; + ignore_case_with_glob = false; + } +} + +static void +set_proc_retry (const char *buf) +{ + child_info::retry_count = strtoul (buf, NULL, 0); +} + +static void +tty_is_gone (const char *buf) +{ + if (!user_shared->warned_notty) + { + small_printf ("\"tty\" option detected in CYGWIN environment variable.\n" + "CYGWIN=tty is no longer supported. Please remove it from your\n" + "CYGWIN environment variable and use a terminal emulator like mintty, " + "xterm, or rxvt\n"); + user_shared->warned_notty = 1; + } +} + +/* 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. */ +static struct parse_thing + { + const char *name; + union parse_setting + { + bool *b; + DWORD *x; + int *i; + void (*func)(const char *); + } setting; + + enum settings disposition; + char *remember; + union parse_values + { + DWORD i; + const char *s; + } values[2]; + } known[] NO_COPY = +{ + {"dosfilewarning", {&dos_file_warning}, 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}}}, + {"glob", {func: glob_init}, isfunc, NULL, {{0}, {s: "normal"}}}, + {"proc_retry", {func: set_proc_retry}, isfunc, NULL, {{0}, {5}}}, + {"reset_com", {&reset_com}, justset, NULL, {{false}, {true}}}, + {"strip_title", {&strip_title_path}, justset, NULL, {{false}, {true}}}, + {"title", {&display_title}, justset, NULL, {{false}, {true}}}, + {"tty", {func: tty_is_gone}, isfunc, NULL, {{0}, {0}}}, + {"upcaseenv", {&create_upcaseenv}, justset, NULL, {{false}, {true}}}, + {"winsymlinks", {&allow_winsymlinks}, justset, NULL, {{false}, {true}}}, + {NULL, {0}, justset, 0, {{0}, {0}}} +}; + +/* Parse a string of the form "something=stuff somethingelse=more-stuff", + silently ignoring unknown "somethings". */ +static void __stdcall +parse_options (const char *inbuf) +{ + int istrue; + char *p, *lasts; + parse_thing *k; + + if (inbuf == NULL) + { + tmp_pathbuf tp; + char *newbuf = tp.c_get (); + newbuf[0] = '\0'; + for (k = known; k->name != NULL; k++) + if (k->remember) + { + strcat (strcat (newbuf, " "), k->remember); + free (k->remember); + k->remember = NULL; + } + + if (export_settings) + { + debug_printf ("%s", newbuf + 1); + setenv ("CYGWIN", newbuf + 1, 1); + } + return; + } + + char *buf = strcpy ((char *) alloca (strlen (inbuf) + 1), inbuf); + for (p = strtok_r (buf, " \t", &lasts); + p != NULL; + p = strtok_r (NULL, " \t", &lasts)) + { + char *keyword_here = p; + if (!(istrue = !ascii_strncasematch (p, "no", 2))) + p += 2; + else if (!(istrue = *p != '-')) + p++; + + char ch, *eq; + if ((eq = strchr (p, '=')) != NULL || (eq = strchr (p, ':')) != NULL) + ch = *eq, *eq++ = '\0'; + else + ch = 0; + + for (parse_thing *k = known; k->name != NULL; k++) + if (ascii_strcasematch (p, k->name)) + { + switch (k->disposition) + { + case isfunc: + k->setting.func ((!eq || !istrue) ? + k->values[istrue].s : eq); + debug_printf ("%s (called func)", k->name); + break; + case justset: + if (!istrue || !eq) + *k->setting.x = k->values[istrue].i; + else + *k->setting.x = strtol (eq, NULL, 0); + debug_printf ("%s %d", k->name, *k->setting.x); + break; + case setbit: + *k->setting.x &= ~k->values[istrue].i; + if (istrue || (eq && strtol (eq, NULL, 0))) + *k->setting.x |= k->values[istrue].i; + debug_printf ("%s %x", k->name, *k->setting.x); + break; + } + + if (eq) + *--eq = ch; + + int n = eq - p; + p = strdup (keyword_here); + if (n > 0) + p[n] = ':'; + k->remember = p; + break; + } + } + debug_printf ("returning"); +} + /* Helper functions for the below environment variables which have to be converted Win32<->POSIX. */ extern "C" ssize_t env_PATH_to_posix (const void *, void *, size_t); @@ -383,6 +561,8 @@ _addenv (const char *name, const char *value, int overwrite) win_env *spenv; if ((spenv = getwinenv (envhere))) spenv->add_cache (value); + if (strcmp (name, "CYGWIN") == 0) + parse_options (value); MALLOC_CHECK; return 0; @@ -522,184 +702,6 @@ ucenv (char *p, const char *eq) } } -/* Parse CYGWIN options */ - -static NO_COPY bool export_settings = false; - -enum settings - { - justset, - isfunc, - setbit - }; - -/* When BUF is: - null or empty: disables globbing - "ignorecase": enables case-insensitive globbing - anything else: enables case-sensitive globbing */ -static void -glob_init (const char *buf) -{ - if (!buf || !*buf) - { - allow_glob = false; - ignore_case_with_glob = false; - } - else if (ascii_strncasematch (buf, "ignorecase", 10)) - { - allow_glob = true; - ignore_case_with_glob = true; - } - else - { - allow_glob = true; - ignore_case_with_glob = false; - } -} - -static void -set_proc_retry (const char *buf) -{ - child_info::retry_count = strtoul (buf, NULL, 0); -} - -static void -tty_is_gone (const char *buf) -{ - if (!user_shared->warned_notty) - { - small_printf ("\"tty\" option detected in CYGWIN environment variable.\n" - "CYGWIN=tty is no longer supported. Please remove it from your\n" - "CYGWIN environment variable and use a terminal emulator like mintty, " - "xterm, or rxvt\n"); - user_shared->warned_notty = 1; - } -} - -/* 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. */ -static struct parse_thing - { - const char *name; - union parse_setting - { - bool *b; - DWORD *x; - int *i; - void (*func)(const char *); - } setting; - - enum settings disposition; - char *remember; - union parse_values - { - DWORD i; - const char *s; - } values[2]; - } known[] NO_COPY = -{ - {"dosfilewarning", {&dos_file_warning}, 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}}}, - {"glob", {func: glob_init}, isfunc, NULL, {{0}, {s: "normal"}}}, - {"proc_retry", {func: set_proc_retry}, isfunc, NULL, {{0}, {5}}}, - {"reset_com", {&reset_com}, justset, NULL, {{false}, {true}}}, - {"strip_title", {&strip_title_path}, justset, NULL, {{false}, {true}}}, - {"title", {&display_title}, justset, NULL, {{false}, {true}}}, - {"tty", {func: tty_is_gone}, isfunc, NULL, {{0}, {0}}}, - {"upcaseenv", {&create_upcaseenv}, justset, NULL, {{false}, {true}}}, - {"winsymlinks", {&allow_winsymlinks}, justset, NULL, {{false}, {true}}}, - {NULL, {0}, justset, 0, {{0}, {0}}} -}; - -/* Parse a string of the form "something=stuff somethingelse=more-stuff", - silently ignoring unknown "somethings". */ -static void __stdcall -parse_options (char *buf) -{ - int istrue; - char *p, *lasts; - parse_thing *k; - - if (buf == NULL) - { - tmp_pathbuf tp; - char *newbuf = tp.c_get (); - newbuf[0] = '\0'; - for (k = known; k->name != NULL; k++) - if (k->remember) - { - strcat (strcat (newbuf, " "), k->remember); - free (k->remember); - k->remember = NULL; - } - - if (export_settings) - { - debug_printf ("%s", newbuf + 1); - setenv ("CYGWIN", newbuf + 1, 1); - } - return; - } - - buf = strcpy ((char *) alloca (strlen (buf) + 1), buf); - for (p = strtok_r (buf, " \t", &lasts); - p != NULL; - p = strtok_r (NULL, " \t", &lasts)) - { - char *keyword_here = p; - if (!(istrue = !ascii_strncasematch (p, "no", 2))) - p += 2; - else if (!(istrue = *p != '-')) - p++; - - char ch, *eq; - if ((eq = strchr (p, '=')) != NULL || (eq = strchr (p, ':')) != NULL) - ch = *eq, *eq++ = '\0'; - else - ch = 0; - - for (parse_thing *k = known; k->name != NULL; k++) - if (ascii_strcasematch (p, k->name)) - { - switch (k->disposition) - { - case isfunc: - k->setting.func ((!eq || !istrue) ? - k->values[istrue].s : eq); - debug_printf ("%s (called func)", k->name); - break; - case justset: - if (!istrue || !eq) - *k->setting.x = k->values[istrue].i; - else - *k->setting.x = strtol (eq, NULL, 0); - debug_printf ("%s %d", k->name, *k->setting.x); - break; - case setbit: - *k->setting.x &= ~k->values[istrue].i; - if (istrue || (eq && strtol (eq, NULL, 0))) - *k->setting.x |= k->values[istrue].i; - debug_printf ("%s %x", k->name, *k->setting.x); - break; - } - - if (eq) - *--eq = ch; - - int n = eq - p; - p = strdup (keyword_here); - if (n > 0) - p[n] = ':'; - k->remember = p; - break; - } - } - debug_printf ("returning"); -} - /* Set options from the registry. */ static bool __stdcall regopt (const WCHAR *name, char *buf) -- 2.43.5