⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 environ.cc

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 CC
📖 第 1 页 / 共 2 页
字号:
      } values[2];  } known[] NO_COPY ={  {"binmode", {x: &binmode}, justset, NULL, {{O_TEXT}, {O_BINARY}}},  {"check_case", {func: &check_case_init}, isfunc, NULL, {{0}, {0}}},  {"codepage", {func: &codepage_init}, isfunc, NULL, {{0}, {0}}},  {"daemon", {&allow_daemon}, 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}}},  {"forkchunk", {func: set_chunksize}, isfunc, NULL, {{0}, {0}}},  {"glob", {func: &glob_init}, isfunc, NULL, {{0}, {s: "normal"}}},  {"ntea", {&allow_ntea}, justset, NULL, {{FALSE}, {TRUE}}},  {"ntsec", {&allow_ntsec}, justset, NULL, {{FALSE}, {TRUE}}},  {"smbntsec", {&allow_smbntsec}, justset, NULL, {{FALSE}, {TRUE}}},  {"reset_com", {&reset_com}, justset, NULL, {{FALSE}, {TRUE}}},  {"strip_title", {&strip_title_path}, justset, NULL, {{FALSE}, {TRUE}}},  {"subauth_id", {func: &subauth_id_init}, isfunc, NULL, {{0}, {0}}},  {"title", {&display_title}, justset, NULL, {{FALSE}, {TRUE}}},  {"tty", {NULL}, set_process_state, NULL, {{0}, {PID_USETTY}}},  {"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 __stdcallparse_options (char *buf){  int istrue;  char *p, *lasts;  parse_thing *k;  if (buf == NULL)    {      char newbuf[MAX_PATH + 7];      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 = !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 (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 set_process_state:		k->setting.x = &myself->process_state;		/* fall through */	      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");  return;}/* Set options from the registry. */static bool __stdcallregopt (const char *name){  bool parsed_something = false;  /* FIXME: should not be under mount */  reg_key r (KEY_READ, CYGWIN_INFO_PROGRAM_OPTIONS_NAME, NULL);  char buf[MAX_PATH];  char lname[strlen (name) + 1];  strlwr (strcpy (lname, name));  if (r.get_string (lname, buf, sizeof (buf) - 1, "") == ERROR_SUCCESS)    {      parse_options (buf);      parsed_something = true;    }  else    {      reg_key r1 (HKEY_LOCAL_MACHINE, KEY_READ, "SOFTWARE",		  CYGWIN_INFO_CYGNUS_REGISTRY_NAME,		  CYGWIN_INFO_CYGWIN_REGISTRY_NAME,		  CYGWIN_INFO_PROGRAM_OPTIONS_NAME, NULL);      if (r1.get_string (lname, buf, sizeof (buf) - 1, "") == ERROR_SUCCESS)	{	  parse_options (buf);	  parsed_something = true;	}    }  MALLOC_CHECK;  return parsed_something;}/* Initialize the environ array.  Look for the CYGWIN environment   environment variable and set appropriate options from it.  */voidenviron_init (char **envp, int envc){  char *rawenv;  int i;  char *p;  char *newp;  int sawTERM = 0;  bool envp_passed_in;  bool got_something_from_registry;  static char NO_COPY cygterm[] = "TERM=cygwin";  static int initted;  if (!initted)    {      for (int i = 0; conv_envvars[i].name != NULL; i++)	{	  conv_start_chars[(int) cyg_tolower (conv_envvars[i].name[0])] = 1;	  conv_start_chars[(int) cyg_toupper (conv_envvars[i].name[0])] = 1;	}      initted = 1;    }  got_something_from_registry = regopt ("default");  if (myself->progname[0])    got_something_from_registry = regopt (myself->progname) || got_something_from_registry;  /* Set ntsec explicit as default, if NT is running */  if (wincap.has_security ())    allow_ntsec = TRUE;  if (!envp)    envp_passed_in = 0;  else    {      envc++;      envc *= sizeof (char *);      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;    }  /* Allocate space for environment + trailing NULL + CYGWIN env. */  lastenviron = envp = (char **) malloc ((4 + (envc = 100)) * sizeof (char *));  rawenv = GetEnvironmentStrings ();  /* Current directory information is recorded as variables of the     form "=X:=X:\foo\bar; these must be changed into something legal     (we could just ignore them but maybe an application will     eventually want to use them).  */  for (i = 0, p = rawenv; *p != '\0'; p = strchr (p, '\0') + 1, i++)    {      newp = strdup (p);      if (i >= envc)	envp = (char **) realloc (envp, (4 + (envc += 100)) * sizeof (char *));      envp[i] = newp;      if (*newp == '=')	*newp = '!';      char *eq;      if ((eq = strchr (newp, '=')) == NULL)	eq = strchr (newp, '\0');      if (!child_proc_info)	ucenv (newp, eq);      if (*newp == 'T' && strncmp (newp, "TERM=", 5) == 0)	sawTERM = 1;      if (*newp == 'C' && strncmp (newp, "CYGWIN=", sizeof ("CYGWIN=") - 1) == 0)	parse_options (newp + sizeof ("CYGWIN=") - 1);      if (*eq && conv_start_chars[(unsigned char)envp[i][0]])	posify (envp + i, *++eq ? eq : --eq);      debug_printf ("%p: %s", envp[i], envp[i]);    }  if (!sawTERM)    envp[i++] = cygterm;  envp[i] = NULL;  FreeEnvironmentStrings (rawenv);out:  __cygwin_environ = envp;  update_envptrs ();  if (envp_passed_in)    {      p = getenv ("CYGWIN");      if (p)	parse_options (p);    }  if (got_something_from_registry)    parse_options (NULL);	/* possibly export registry settings to				   environment */  MALLOC_CHECK;}/* Function called by qsort to sort environment strings.  */static intenv_sort (const void *a, const void *b){  const char **p = (const char **) a;  const char **q = (const char **) b;  return strcmp (*p, *q);}char * __stdcallgetwinenveq (const char *name, size_t namelen, int x){  char dum[1];  char name0[namelen - 1];  memcpy (name0, name, namelen - 1);  name0[namelen - 1] = '\0';  int totlen = GetEnvironmentVariable (name0, dum, 0);  if (totlen > 0)    {      totlen++;      if (x == HEAP_1_STR)	totlen += namelen;      else	namelen = 0;      char *p = (char *) cmalloc ((cygheap_types) x, totlen);      if (namelen)	strcpy (p, name);      if (GetEnvironmentVariable (name0, p + namelen, totlen))	{	  debug_printf ("using value from GetEnvironmentVariable for '%s'",			name0);	  return p;	}      else	cfree (p);    }  debug_printf ("warning: %s not present in environment", name);  return NULL;}struct spenv{  const char *name;  size_t namelen;  const char * (cygheap_user::*from_cygheap) (const char *, size_t);  char *retrieve (bool, const char * const = NULL)    __attribute__ ((regparm (3)));};#define env_dontadd almost_null/* Keep this list in upper case and sorted */static NO_COPY spenv spenvs[] ={  {NL ("HOMEDRIVE="), &cygheap_user::env_homedrive},  {NL ("HOMEPATH="), &cygheap_user::env_homepath},  {NL ("LOGONSERVER="), &cygheap_user::env_logsrv},  {NL ("SYSTEMDRIVE="), NULL},  {NL ("SYSTEMROOT="), NULL},  {NL ("USERDOMAIN="), &cygheap_user::env_domain},  {NL ("USERNAME="), &cygheap_user::env_name},  {NL ("USERPROFILE="), &cygheap_user::env_userprofile},};char *spenv::retrieve (bool no_envblock, const char *const envname){  if (envname && !strncasematch (envname, name, namelen))    return NULL;  debug_printf ("no_envblock %d", no_envblock);  if (from_cygheap)    {      const char *p;      if (envname && !cygheap->user.issetuid ())	{	  debug_printf ("duping existing value for '%s'", name);	  return cstrdup1 (envname);	/* Don't really care what it's set to					   if we're calling a cygwin program */	}      /* Calculate (potentially) value for given environment variable.  */      p = (cygheap->user.*from_cygheap) (name, namelen);      if (!p || (no_envblock && !envname) || (p == env_dontadd))	return env_dontadd;      char *s = (char *) cmalloc (HEAP_1_STR, namelen + strlen (p) + 1);      strcpy (s, name);      (void) strcpy (s + namelen, p);      debug_printf ("using computed value for '%s'", name);      return s;    }  if (envname)    return cstrdup1 (envname);  return getwinenveq (name, namelen, HEAP_1_STR);}#define SPENVS_SIZE (sizeof (spenvs) / sizeof (spenvs[0]))/* 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.  */char ** __stdcallbuild_env (const char * const *envp, char *&envblock, int &envc,	   bool no_envblock){  int len, n;  const char * const *srcp;  char **dstp;  bool saw_spenv[SPENVS_SIZE] = {0};  debug_printf ("envp %p", envp);  /* How many elements? */  for (n = 0; envp[n]; n++)    continue;  /* Allocate a new "argv-style" environ list with room for extra stuff. */  char **newenv = (char **) cmalloc (HEAP_1_ARGV, sizeof (char *) *						  (n + SPENVS_SIZE + 1));  int tl = 0;  /* Iterate over input list, generating a new environment list and refreshing     "special" entries, if necessary. */  for (srcp = envp, dstp = newenv; *srcp; srcp++)    {      /* Look for entries that require special attention */      for (unsigned i = 0; i < SPENVS_SIZE; i++)	if (!saw_spenv[i] && (*dstp = spenvs[i].retrieve (no_envblock, *srcp)))	  {	    saw_spenv[i] = 1;	    if (*dstp == env_dontadd)	      goto next1;	    goto  next0;	  }      /* Add entry to new environment */      *dstp = cstrdup1 (*srcp);    next0:      /* If necessary, calculate rough running total for envblock size */      if (!no_envblock)	tl += strlen (*dstp) + 1;      dstp++;    next1:      continue;    }  assert ((srcp - envp) == n);  /* Fill in any required-but-missing environment variables. */  for (unsigned i = 0; i < SPENVS_SIZE; i++)    if (!saw_spenv[i])      {	*dstp = spenvs[i].retrieve (no_envblock);	if (*dstp && !no_envblock && *dstp != env_dontadd)	  {	    tl += strlen (*dstp) + 1;	    dstp++;	  }      }  envc = dstp - newenv;		/* Number of entries in newenv */  assert ((size_t) envc <= (n + SPENVS_SIZE));  *dstp = NULL;			/* Terminate */  if (no_envblock)    envblock = NULL;  else    {      debug_printf ("env count %d, bytes %d", envc, tl);      /* Windows programs expect the environment block to be sorted.  */      qsort (newenv, envc, sizeof (char *), env_sort);      /* Create an environment block suitable for passing to CreateProcess.  */      char *s;      envblock = (char *) malloc (2 + tl);      int new_tl = 0;      for (srcp = newenv, s = envblock; *srcp; srcp++)	{	  const char *p;	  win_env *conv;	  len = strcspn (*srcp, "=") + 1;	  /* See if this entry requires posix->win32 conversion. */	  conv = getwinenv (*srcp, *srcp + len);	  if (conv)	    p = conv->native;	/* Use win32 path */	  else	    p = *srcp;		/* Don't worry about it */	  len = strlen (p);	  new_tl += len + 1;	/* Keep running total of block length so far */	  /* See if we need to increase the size of the block. */	  if (new_tl > tl)	    {	      tl = new_tl + 100;	      char *new_envblock =			(char *) realloc (envblock, 2 + tl);	      /* If realloc moves the block, move `s' with it. */	      if (new_envblock != envblock)		{		  s += new_envblock - envblock;		  envblock = new_envblock;		}	    }	  memcpy (s, p, len + 1);	  /* See if environment variable is "special" in a Windows sense.	     Under NT, the current directories for visited drives are stored	     as =C:=\bar.  Cygwin converts the '=' to '!' for hopefully obvious	     reasons.  We need to convert it back when building the envblock */	  if (s[0] == '!' && (isdrive (s + 1) || (s[1] == ':' && s[2] == ':'))	      && s[3] == '=')	    *s = '=';	  s += len + 1;	}      *s = '\0';			/* Two null bytes at the end */      assert ((s - envblock) <= tl);	/* Detect if we somehow ran over end					   of buffer */    }  debug_printf ("envp %p, envc %d", newenv, envc);  return newenv;}/* This idiocy is necessary because the early implementers of cygwin   did not seem to know about importing data variables from the DLL.   So, we have to synchronize cygwin's idea of the environment with the   main program's with each reference to the environment. */extern "C" char ** __stdcallcur_environ (){  if (*main_environ != __cygwin_environ)    {      __cygwin_environ = *main_environ;      update_envptrs ();    }  return __cygwin_environ;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -