Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2000-07-26 05:44:16 +0400
committerChristopher Faylor <me@cgf.cx>2000-07-26 05:44:16 +0400
commit2a1a9785eb7f0a9aca2244da48038ef9de53a8b9 (patch)
treeb7afb56558ced69ec4e6a7c2a37ae82f83bd9eec
parent738c2431e5f83a1a7be708b083abc106369f6799 (diff)
* syscalls.cc (_link): Avoid extraneous call to cygwin_conv_to_win32_path.
-rw-r--r--winsup/cygwin/ChangeLog5
-rw-r--r--winsup/cygwin/environ.cc192
-rw-r--r--winsup/cygwin/syscalls.cc8
3 files changed, 122 insertions, 83 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index a78698178..748acaba2 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,8 @@
+Tue Jul 25 21:40:51 2000 Christopher Faylor <cgf@cygnus.com>
+
+ * syscalls.cc (_link): Avoid extraneous call to
+ cygwin_conv_to_win32_path.
+
Mon Jul 24 21:10:00 2000 Corinna Vinschen <corinna@vinschen.de>
* syscalls.cc (_link): Corrected previous patch.
diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc
index 7c236df42..ccf61515a 100644
--- a/winsup/cygwin/environ.cc
+++ b/winsup/cygwin/environ.cc
@@ -7,8 +7,9 @@ This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
-#include "winsup.h"
+#include <errno.h>
#include <stdlib.h>
+#include "winsup.h"
#include <stddef.h>
#include <ctype.h>
#include <fcntl.h>
@@ -120,7 +121,6 @@ posify (int already_posix, char **here, const char *value)
debug_printf ("env var converted to %s", outenv);
*here = outenv;
- free (src);
}
}
@@ -170,87 +170,124 @@ getenv (const char *name)
return my_findenv (name, &offset);
}
-/* putenv --
- * Sets an environment variable
- */
-
-extern "C" int
-putenv (const char *str)
+/* Takes similar arguments to setenv except that overwrite is
+ either -1, 0, or 1. 0 or 1 signify that the function should
+ perform similarly to setenv. Otherwise putenv is assumed. */
+static int __stdcall
+_addenv (const char *name, const char *value, int overwrite)
{
- register char *p, *equal;
- int rval;
+ int issetenv = overwrite >= 0;
+ int offset;
+ char *p;
- if (!(p = strdup (str)))
- return 1;
- if (!(equal = index (p, '=')))
+ int res;
+ if ((res = check_null_empty_path (name)))
{
- (void) free (p);
- return 1;
+ set_errno (res);
+ return -1;
}
- *equal = '\0';
- rval = setenv (p, equal + 1, 1);
- (void) free (p);
- return rval;
-}
-
-/*
- * setenv --
- * Set the value of the environment variable "name" to be
- * "value". If rewrite is set, replace any current value.
- */
-extern "C" int
-setenv (const char *name, const char *value, int rewrite)
-{
- register char *C;
- unsigned int l_value;
- int offset;
+ unsigned int valuelen = strlen (value);
+ if ((p = my_findenv (name, &offset)))
+ { /* Already exists. */
+ if (!overwrite) /* Ok to overwrite? */
+ return 0; /* No. Wanted to add new value. FIXME: Right return value? */
- if (*value == '=') /* no `=' in value */
- ++value;
- l_value = strlen (value);
- if ((C = my_findenv (name, &offset)))
- { /* find if already exists */
- if (!rewrite)
- return 0;
- if (strlen (C) >= l_value)
- { /* old larger; copy over */
- while ((*C++ = *value++));
+ /* We've found the offset into environ. If this is a setenv call and
+ there is room in the current environment entry then just overwrite it.
+ Otherwise handle this case below. */
+ if (issetenv && strlen (p) >= valuelen)
+ {
+ strcpy (p, value);
return 0;
}
}
else
- { /* create new slot */
- register int cnt;
- register char **P;
-
- for (P = environ, cnt = 0; *P; ++P, ++cnt)
- ;
- __cygwin_environ = (char **) realloc ((char *) environ,
- (size_t) (sizeof (char *) * (cnt + 2)));
+ { /* Create new slot. */
+ char **env;
+
+ /* Search for the end of the environment. */
+ for (env = environ; *env; env++)
+ continue;
+
+ offset = env - environ; /* Number of elements currently in environ. */
+
+ /* Allocate space for additional element plus terminating NULL. */
+ __cygwin_environ = (char **) realloc (environ, (sizeof (char *) *
+ (offset + 2)));
if (!__cygwin_environ)
- return -1;
- __cygwin_environ[cnt + 1] = NULL;
- update_envptrs ();
- offset = cnt;
- }
+ return -1; /* Oops. No more memory. */
- for (C = (char *) name; *C && *C != '='; ++C); /* no `=' in name */
+ __cygwin_environ[offset + 1] = NULL; /* NULL terminate. */
+ update_envptrs (); /* Update any local copies of 'environ'. */
+ }
- if (!(environ[offset] = /* name + `=' + value */
- (char *) malloc ((size_t) ((int) (C - name) + l_value + 2))))
- return -1;
- for (C = environ[offset]; (*C = *name++) && *C != '='; ++C);
- *C++ = '=';
- strcpy (C, value);
+ char *envhere;
+ if (!issetenv)
+ envhere = environ[offset] = (char *) name; /* Not setenv. Just
+ overwrite existing. */
+ else
+ { /* setenv */
+ /* Look for an '=' in the name and ignore anything after that if found. */
+ for (p = (char *) name; *p && *p != '='; p++)
+ continue;
+
+ int namelen = p - name; /* Length of name. */
+ /* Allocate enough space for name + '=' + value + '\0' */
+ envhere = environ[offset] = (char *) malloc (namelen + valuelen + 2);
+ if (!envhere)
+ return -1; /* Oops. No more memory. */
+
+ /* Put name '=' value into current slot. */
+ strncpy (envhere, name, namelen);
+ envhere[namelen] = '=';
+ strcpy (envhere + namelen + 1, value);
+ }
+ /* Update cygwin's cache, if appropriate */
win_env *spenv;
- if ((spenv = getwinenv (environ[offset])))
+ if ((spenv = getwinenv (envhere)))
spenv->add_cache (value);
return 0;
}
+/* putenv --
+ * Sets an environment variable
+ */
+
+extern "C" int
+putenv (const char *str)
+{
+ char *eq = strchr (str, '=');
+ if (eq)
+ return _addenv (str, eq + 1, -1);
+
+ /* Remove str from the environment. */
+ unsetenv (str);
+ return 0;
+}
+
+/*
+ * 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)
+{
+ int res;
+ if ((res = check_null_empty_path (value)))
+ {
+ set_errno (res);
+ return -1;
+ }
+ if (*value == '=')
+ value++;
+ return _addenv (name, value, !!overwrite);
+}
+
/*
* unsetenv(name) --
* Delete environment variable "name".
@@ -453,11 +490,12 @@ regopt (const char *name)
void
environ_init (int already_posix)
{
- const char * const rawenv = GetEnvironmentStrings ();
+ char *rawenv = GetEnvironmentStrings ();
int envsize, i;
- char *newp, **envp;
- const char *p;
+ char *p;
+ char **envp;
int sawTERM = 0;
+ static char cygterm[] = "TERM=cygwin";
/* Allocate space for environment + trailing NULL + CYGWIN env. */
envp = (char **) malloc ((4 + (envsize = 100)) * sizeof (char *));
@@ -478,33 +516,31 @@ environ_init (int already_posix)
eventually want to use them). */
for (i = 0, p = rawenv; *p != '\0'; p = strchr (p, '\0') + 1, i++)
{
- newp = strdup (p);
if (i >= envsize)
envp = (char **) realloc (envp, (4 + (envsize += 100)) *
sizeof (char *));
- envp[i] = newp;
- if (*newp == '=')
- *newp = '!';
+ envp[i] = p;
+ if (*p == '=')
+ *p = '!';
char *eq;
- if ((eq = strchr (newp, '=')) == NULL)
- eq = strchr (newp, '\0');
+ if ((eq = strchr (p, '=')) == NULL)
+ eq = strchr (p, '\0');
if (!parent_alive)
- ucenv (newp, eq);
- if (strncmp (newp, "TERM=", 5) == 0)
+ ucenv (p, eq);
+ if (strncmp (p, "TERM=", 5) == 0)
sawTERM = 1;
- if (strncmp (newp, "CYGWIN=", sizeof("CYGWIN=") - 1) == 0)
- parse_options (newp + sizeof("CYGWIN=") - 1);
+ if (strncmp (p, "CYGWIN=", sizeof("CYGWIN=") - 1) == 0)
+ parse_options (p + sizeof("CYGWIN=") - 1);
if (*eq)
posify (already_posix, envp + i, *++eq ? eq : --eq);
debug_printf ("%s", envp[i]);
}
if (!sawTERM)
- envp[i++] = strdup ("TERM=cygwin");
+ envp[i++] = cygterm;
envp[i] = NULL;
__cygwin_environ = envp;
update_envptrs ();
- FreeEnvironmentStringsA ((char *) rawenv);
parse_options (NULL);
MALLOC_CHECK;
}
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 1bc3a7f8d..d593b7f68 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -494,8 +494,8 @@ int
_link (const char *a, const char *b)
{
int res = -1;
- path_conv real_a (a, PC_SYM_NOFOLLOW);
- path_conv real_b (b, PC_SYM_NOFOLLOW);
+ path_conv real_a (a, PC_SYM_NOFOLLOW | PC_FULL);
+ path_conv real_b (b, PC_SYM_NOFOLLOW | PC_FULL);
if (real_a.error)
{
@@ -525,7 +525,6 @@ _link (const char *a, const char *b)
DWORD cbPathLen;
DWORD StreamSize;
WCHAR wbuf[MAX_PATH];
- char buf[MAX_PATH];
BOOL bSuccess;
@@ -546,8 +545,7 @@ _link (const char *a, const char *b)
}
lpContext = NULL;
- cygwin_conv_to_full_win32_path (real_b.get_win32 (), buf);
- cbPathLen = sys_mbstowcs (wbuf, buf, MAX_PATH) * sizeof (WCHAR);
+ cbPathLen = sys_mbstowcs (wbuf, real_b.get_win32 (), MAX_PATH) * sizeof (WCHAR);
StreamId.dwStreamId = BACKUP_LINK;
StreamId.dwStreamAttributes = 0;