mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-28 12:05:47 +08:00
* environ.c: Move code earlier to allow:
(_addenv): Call parse_options() when CYGWIN environment variable is being changed. (parse_options): Change parameter to 'const'.
This commit is contained in:
parent
e720cf09bd
commit
b9cf88ddba
@ -1,3 +1,10 @@
|
|||||||
|
2011-06-09 Christopher Faylor <me.cygwin2011@cgf.cx>
|
||||||
|
|
||||||
|
* 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 <me.cygwin2011@cgf.cx>
|
2011-06-08 Christopher Faylor <me.cygwin2011@cgf.cx>
|
||||||
|
|
||||||
* environ.cc (tty_is_gone): Add missing space to message.
|
* environ.cc (tty_is_gone): Add missing space to message.
|
||||||
|
@ -41,6 +41,184 @@ static bool create_upcaseenv = false;
|
|||||||
|
|
||||||
static char **lastenviron;
|
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
|
/* Helper functions for the below environment variables which have to
|
||||||
be converted Win32<->POSIX. */
|
be converted Win32<->POSIX. */
|
||||||
extern "C" ssize_t env_PATH_to_posix (const void *, void *, size_t);
|
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;
|
win_env *spenv;
|
||||||
if ((spenv = getwinenv (envhere)))
|
if ((spenv = getwinenv (envhere)))
|
||||||
spenv->add_cache (value);
|
spenv->add_cache (value);
|
||||||
|
if (strcmp (name, "CYGWIN") == 0)
|
||||||
|
parse_options (value);
|
||||||
|
|
||||||
MALLOC_CHECK;
|
MALLOC_CHECK;
|
||||||
return 0;
|
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. */
|
/* Set options from the registry. */
|
||||||
static bool __stdcall
|
static bool __stdcall
|
||||||
regopt (const WCHAR *name, char *buf)
|
regopt (const WCHAR *name, char *buf)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user