зеркало из https://github.com/github/ruby.git
* dir.c (glob_helper): get rid of possible memory leak.
* win32/win32.c (cmdglob, rb_w32_cmdvector, rb_w32_opendir, rb_w32_get_environ): not to use GC before initialization. [ruby-core:09024] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11245 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
3679754a95
Коммит
66d43b5fd6
|
@ -1,3 +1,10 @@
|
||||||
|
Mon Oct 30 23:22:43 2006 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* dir.c (glob_helper): get rid of possible memory leak.
|
||||||
|
|
||||||
|
* win32/win32.c (cmdglob, rb_w32_cmdvector, rb_w32_opendir,
|
||||||
|
rb_w32_get_environ): not to use GC before initialization.
|
||||||
|
|
||||||
Mon Oct 30 19:28:02 2006 NAKAMURA Usaku <usa@ruby-lang.org>
|
Mon Oct 30 19:28:02 2006 NAKAMURA Usaku <usa@ruby-lang.org>
|
||||||
|
|
||||||
* bignum.c (rb_big2str0): use better approximation.
|
* bignum.c (rb_big2str0): use better approximation.
|
||||||
|
|
78
dir.c
78
dir.c
|
@ -922,7 +922,11 @@ sys_warning_1(const char* mesg)
|
||||||
|
|
||||||
#define GLOB_VERBOSE (1UL << (sizeof(int) * CHAR_BIT - 1))
|
#define GLOB_VERBOSE (1UL << (sizeof(int) * CHAR_BIT - 1))
|
||||||
#define sys_warning(val) \
|
#define sys_warning(val) \
|
||||||
((flags & GLOB_VERBOSE) && rb_protect((VALUE (*)_((VALUE)))sys_warning_1, (VALUE)(val), 0))
|
(void)((flags & GLOB_VERBOSE) && rb_protect((VALUE (*)_((VALUE)))sys_warning_1, (VALUE)(val), 0))
|
||||||
|
|
||||||
|
#define GLOB_ALLOC(type) (type *)malloc(sizeof(type))
|
||||||
|
#define GLOB_ALLOC_N(type, n) (type *)malloc(sizeof(type) * (n))
|
||||||
|
#define GLOB_JUMP_TAG(status) ((status == -1) ? rb_memerror() : rb_jump_tag(status))
|
||||||
|
|
||||||
/* System call with warning */
|
/* System call with warning */
|
||||||
static int
|
static int
|
||||||
|
@ -1058,6 +1062,8 @@ struct glob_pattern {
|
||||||
struct glob_pattern *next;
|
struct glob_pattern *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void glob_free_pattern(struct glob_pattern *list);
|
||||||
|
|
||||||
static struct glob_pattern *
|
static struct glob_pattern *
|
||||||
glob_make_pattern(const char *p, int flags)
|
glob_make_pattern(const char *p, int flags)
|
||||||
{
|
{
|
||||||
|
@ -1065,7 +1071,8 @@ glob_make_pattern(const char *p, int flags)
|
||||||
int dirsep = 0; /* pattern is terminated with '/' */
|
int dirsep = 0; /* pattern is terminated with '/' */
|
||||||
|
|
||||||
while (*p) {
|
while (*p) {
|
||||||
tmp = ALLOC(struct glob_pattern);
|
tmp = GLOB_ALLOC(struct glob_pattern);
|
||||||
|
if (!tmp) goto error;
|
||||||
if (p[0] == '*' && p[1] == '*' && p[2] == '/') {
|
if (p[0] == '*' && p[1] == '*' && p[2] == '/') {
|
||||||
/* fold continuous RECURSIVEs (needed in glob_helper) */
|
/* fold continuous RECURSIVEs (needed in glob_helper) */
|
||||||
do { p += 3; } while (p[0] == '*' && p[1] == '*' && p[2] == '/');
|
do { p += 3; } while (p[0] == '*' && p[1] == '*' && p[2] == '/');
|
||||||
|
@ -1075,7 +1082,11 @@ glob_make_pattern(const char *p, int flags)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const char *m = find_dirsep(p, flags);
|
const char *m = find_dirsep(p, flags);
|
||||||
char *buf = ALLOC_N(char, m-p+1);
|
char *buf = GLOB_ALLOC_N(char, m-p+1);
|
||||||
|
if (!buf) {
|
||||||
|
free(tmp);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
memcpy(buf, p, m-p);
|
memcpy(buf, p, m-p);
|
||||||
buf[m-p] = '\0';
|
buf[m-p] = '\0';
|
||||||
tmp->type = has_magic(buf, flags) ? MAGICAL : PLAIN;
|
tmp->type = has_magic(buf, flags) ? MAGICAL : PLAIN;
|
||||||
|
@ -1093,7 +1104,13 @@ glob_make_pattern(const char *p, int flags)
|
||||||
tail = &tmp->next;
|
tail = &tmp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = ALLOC(struct glob_pattern);
|
tmp = GLOB_ALLOC(struct glob_pattern);
|
||||||
|
if (!tmp) {
|
||||||
|
error:
|
||||||
|
*tail = 0;
|
||||||
|
glob_free_pattern(list);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
tmp->type = dirsep ? MATCH_DIR : MATCH_ALL;
|
tmp->type = dirsep ? MATCH_DIR : MATCH_ALL;
|
||||||
tmp->str = 0;
|
tmp->str = 0;
|
||||||
*tail = tmp;
|
*tail = tmp;
|
||||||
|
@ -1118,8 +1135,9 @@ static char *
|
||||||
join_path(const char *path, int dirsep, const char *name)
|
join_path(const char *path, int dirsep, const char *name)
|
||||||
{
|
{
|
||||||
long len = strlen(path);
|
long len = strlen(path);
|
||||||
char *buf = ALLOC_N(char, len+strlen(name)+(dirsep?1:0)+1);
|
char *buf = GLOB_ALLOC_N(char, len+strlen(name)+(dirsep?1:0)+1);
|
||||||
|
|
||||||
|
if (!buf) return 0;
|
||||||
memcpy(buf, path, len);
|
memcpy(buf, path, len);
|
||||||
if (dirsep) {
|
if (dirsep) {
|
||||||
strcpy(buf+len, "/");
|
strcpy(buf+len, "/");
|
||||||
|
@ -1229,6 +1247,7 @@ glob_helper(
|
||||||
}
|
}
|
||||||
if (match_dir && isdir == YES) {
|
if (match_dir && isdir == YES) {
|
||||||
char *tmp = join_path(path, dirsep, "");
|
char *tmp = join_path(path, dirsep, "");
|
||||||
|
if (!tmp) return -1;
|
||||||
status = glob_call_func(func, tmp, arg);
|
status = glob_call_func(func, tmp, arg);
|
||||||
free(tmp);
|
free(tmp);
|
||||||
if (status) return status;
|
if (status) return status;
|
||||||
|
@ -1244,8 +1263,12 @@ glob_helper(
|
||||||
|
|
||||||
for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
|
for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
|
||||||
char *buf = join_path(path, dirsep, dp->d_name);
|
char *buf = join_path(path, dirsep, dp->d_name);
|
||||||
|
|
||||||
enum answer new_isdir = UNKNOWN;
|
enum answer new_isdir = UNKNOWN;
|
||||||
|
|
||||||
|
if (!buf) {
|
||||||
|
status = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (recursive && strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0
|
if (recursive && strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0
|
||||||
&& fnmatch("*", dp->d_name, flags) == 0) {
|
&& fnmatch("*", dp->d_name, flags) == 0) {
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
@ -1258,7 +1281,11 @@ glob_helper(
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
new_beg = new_end = ALLOC_N(struct glob_pattern *, (end - beg) * 2);
|
new_beg = new_end = GLOB_ALLOC_N(struct glob_pattern *, (end - beg) * 2);
|
||||||
|
if (!new_beg) {
|
||||||
|
status = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
for (cur = beg; cur < end; ++cur) {
|
for (cur = beg; cur < end; ++cur) {
|
||||||
struct glob_pattern *p = *cur;
|
struct glob_pattern *p = *cur;
|
||||||
|
@ -1284,7 +1311,8 @@ glob_helper(
|
||||||
else if (plain) {
|
else if (plain) {
|
||||||
struct glob_pattern **copy_beg, **copy_end, **cur2;
|
struct glob_pattern **copy_beg, **copy_end, **cur2;
|
||||||
|
|
||||||
copy_beg = copy_end = ALLOC_N(struct glob_pattern *, end - beg);
|
copy_beg = copy_end = GLOB_ALLOC_N(struct glob_pattern *, end - beg);
|
||||||
|
if (!copy_beg) return -1;
|
||||||
for (cur = beg; cur < end; ++cur)
|
for (cur = beg; cur < end; ++cur)
|
||||||
*copy_end++ = (*cur)->type == PLAIN ? *cur : 0;
|
*copy_end++ = (*cur)->type == PLAIN ? *cur : 0;
|
||||||
|
|
||||||
|
@ -1292,11 +1320,20 @@ glob_helper(
|
||||||
if (*cur) {
|
if (*cur) {
|
||||||
char *buf;
|
char *buf;
|
||||||
char *name;
|
char *name;
|
||||||
name = ALLOC_N(char, strlen((*cur)->str) + 1);
|
name = GLOB_ALLOC_N(char, strlen((*cur)->str) + 1);
|
||||||
|
if (!name) {
|
||||||
|
status = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
strcpy(name, (*cur)->str);
|
strcpy(name, (*cur)->str);
|
||||||
if (escape) remove_backslashes(name);
|
if (escape) remove_backslashes(name);
|
||||||
|
|
||||||
new_beg = new_end = ALLOC_N(struct glob_pattern *, end - beg);
|
new_beg = new_end = GLOB_ALLOC_N(struct glob_pattern *, end - beg);
|
||||||
|
if (!new_beg) {
|
||||||
|
free(name);
|
||||||
|
status = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
*new_end++ = (*cur)->next;
|
*new_end++ = (*cur)->next;
|
||||||
for (cur2 = cur + 1; cur2 < copy_end; ++cur2) {
|
for (cur2 = cur + 1; cur2 < copy_end; ++cur2) {
|
||||||
if (*cur2 && fnmatch((*cur2)->str, name, flags) == 0) {
|
if (*cur2 && fnmatch((*cur2)->str, name, flags) == 0) {
|
||||||
|
@ -1307,6 +1344,11 @@ glob_helper(
|
||||||
|
|
||||||
buf = join_path(path, dirsep, name);
|
buf = join_path(path, dirsep, name);
|
||||||
free(name);
|
free(name);
|
||||||
|
if (!buf) {
|
||||||
|
free(new_beg);
|
||||||
|
status = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
status = glob_helper(buf, 1, UNKNOWN, UNKNOWN, new_beg, new_end, flags, func, arg);
|
status = glob_helper(buf, 1, UNKNOWN, UNKNOWN, new_beg, new_end, flags, func, arg);
|
||||||
free(buf);
|
free(buf);
|
||||||
free(new_beg);
|
free(new_beg);
|
||||||
|
@ -1338,11 +1380,16 @@ ruby_glob0(const char *path, int flags, ruby_glob_func *func, VALUE arg)
|
||||||
if (root && *root == '/') root++;
|
if (root && *root == '/') root++;
|
||||||
|
|
||||||
n = root - start;
|
n = root - start;
|
||||||
buf = ALLOC_N(char, n + 1);
|
buf = GLOB_ALLOC_N(char, n + 1);
|
||||||
|
if (!buf) return -1;
|
||||||
MEMCPY(buf, start, char, n);
|
MEMCPY(buf, start, char, n);
|
||||||
buf[n] = '\0';
|
buf[n] = '\0';
|
||||||
|
|
||||||
list = glob_make_pattern(root, flags);
|
list = glob_make_pattern(root, flags);
|
||||||
|
if (!list) {
|
||||||
|
free(buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
status = glob_helper(buf, 0, UNKNOWN, UNKNOWN, &list, &list + 1, flags, func, arg);
|
status = glob_helper(buf, 0, UNKNOWN, UNKNOWN, &list, &list + 1, flags, func, arg);
|
||||||
glob_free_pattern(list);
|
glob_free_pattern(list);
|
||||||
free(buf);
|
free(buf);
|
||||||
|
@ -1386,7 +1433,7 @@ void
|
||||||
rb_glob(const char *path, void (*func)(const char *, VALUE), VALUE arg)
|
rb_glob(const char *path, void (*func)(const char *, VALUE), VALUE arg)
|
||||||
{
|
{
|
||||||
int status = rb_glob2(path, 0, func, arg);
|
int status = rb_glob2(path, 0, func, arg);
|
||||||
if (status) rb_jump_tag(status);
|
if (status) GLOB_JUMP_TAG(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1419,9 +1466,10 @@ ruby_brace_expand(const char *str, int flags, ruby_glob_func *func, VALUE arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lbrace && rbrace) {
|
if (lbrace && rbrace) {
|
||||||
char *buf = ALLOC_N(char, strlen(s) + 1);
|
char *buf = GLOB_ALLOC_N(char, strlen(s) + 1);
|
||||||
long shift;
|
long shift;
|
||||||
|
|
||||||
|
if (!buf) return -1;
|
||||||
memcpy(buf, s, lbrace-s);
|
memcpy(buf, s, lbrace-s);
|
||||||
shift = (lbrace-s);
|
shift = (lbrace-s);
|
||||||
p = lbrace;
|
p = lbrace;
|
||||||
|
@ -1503,7 +1551,7 @@ rb_push_glob(VALUE str, int flags) /* '\0' is delimiter */
|
||||||
while (offset < RSTRING_LEN(str)) {
|
while (offset < RSTRING_LEN(str)) {
|
||||||
int status = push_glob(ary, RSTRING_PTR(str) + offset, flags);
|
int status = push_glob(ary, RSTRING_PTR(str) + offset, flags);
|
||||||
char *p, *pend;
|
char *p, *pend;
|
||||||
if (status) rb_jump_tag(status);
|
if (status) GLOB_JUMP_TAG(status);
|
||||||
if (offset >= RSTRING_LEN(str)) break;
|
if (offset >= RSTRING_LEN(str)) break;
|
||||||
p = RSTRING_PTR(str) + offset;
|
p = RSTRING_PTR(str) + offset;
|
||||||
p += strlen(p) + 1;
|
p += strlen(p) + 1;
|
||||||
|
@ -1527,7 +1575,7 @@ dir_globs(long argc, VALUE *argv, int flags)
|
||||||
VALUE str = argv[i];
|
VALUE str = argv[i];
|
||||||
StringValue(str);
|
StringValue(str);
|
||||||
status = push_glob(ary, RSTRING_PTR(str), flags);
|
status = push_glob(ary, RSTRING_PTR(str), flags);
|
||||||
if (status) rb_jump_tag(status);
|
if (status) GLOB_JUMP_TAG(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ary;
|
return ary;
|
||||||
|
|
|
@ -410,7 +410,8 @@ init_env(void)
|
||||||
NTLoginName = "<Unknown>";
|
NTLoginName = "<Unknown>";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
NTLoginName = ALLOC_N(char, len+1);
|
NTLoginName = (char *)malloc(len+1);
|
||||||
|
if (!NTLoginName) return;
|
||||||
strncpy(NTLoginName, env, len);
|
strncpy(NTLoginName, env, len);
|
||||||
NTLoginName[len] = '\0';
|
NTLoginName[len] = '\0';
|
||||||
}
|
}
|
||||||
|
@ -1059,10 +1060,12 @@ insert(const char *path, VALUE vinfo)
|
||||||
NtCmdLineElement *tmpcurr;
|
NtCmdLineElement *tmpcurr;
|
||||||
NtCmdLineElement ***tail = (NtCmdLineElement ***)vinfo;
|
NtCmdLineElement ***tail = (NtCmdLineElement ***)vinfo;
|
||||||
|
|
||||||
tmpcurr = ALLOC(NtCmdLineElement);
|
tmpcurr = (NtCmdLineElement *)malloc(sizeof(NtCmdLineElement));
|
||||||
|
if (!tmpcurr) return -1;
|
||||||
MEMZERO(tmpcurr, NtCmdLineElement, 1);
|
MEMZERO(tmpcurr, NtCmdLineElement, 1);
|
||||||
tmpcurr->len = strlen(path);
|
tmpcurr->len = strlen(path);
|
||||||
tmpcurr->str = ALLOC_N(char, tmpcurr->len + 1);
|
tmpcurr->str = (char *)malloc(tmpcurr->len + 1);
|
||||||
|
if (!tmpcurr->str) return -1;
|
||||||
tmpcurr->flags |= NTMALLOC;
|
tmpcurr->flags |= NTMALLOC;
|
||||||
strcpy(tmpcurr->str, path);
|
strcpy(tmpcurr->str, path);
|
||||||
**tail = tmpcurr;
|
**tail = tmpcurr;
|
||||||
|
@ -1084,20 +1087,21 @@ cmdglob(NtCmdLineElement *patt, NtCmdLineElement **tail)
|
||||||
char buffer[MAXPATHLEN], *buf = buffer;
|
char buffer[MAXPATHLEN], *buf = buffer;
|
||||||
char *p;
|
char *p;
|
||||||
NtCmdLineElement **last = tail;
|
NtCmdLineElement **last = tail;
|
||||||
|
int status;
|
||||||
|
|
||||||
if (patt->len >= MAXPATHLEN)
|
if (patt->len >= MAXPATHLEN)
|
||||||
buf = ruby_xmalloc(patt->len + 1);
|
if (!(buf = malloc(patt->len + 1))) return 0;
|
||||||
|
|
||||||
strncpy (buf, patt->str, patt->len);
|
strncpy (buf, patt->str, patt->len);
|
||||||
buf[patt->len] = '\0';
|
buf[patt->len] = '\0';
|
||||||
for (p = buf; *p; p = CharNext(p))
|
for (p = buf; *p; p = CharNext(p))
|
||||||
if (*p == '\\')
|
if (*p == '\\')
|
||||||
*p = '/';
|
*p = '/';
|
||||||
ruby_brace_glob(buf, 0, insert, (VALUE)&tail);
|
status = ruby_brace_glob(buf, 0, insert, (VALUE)&tail);
|
||||||
if (buf != buffer)
|
if (buf != buffer)
|
||||||
free(buf);
|
free(buf);
|
||||||
|
|
||||||
if (last == tail) return 0;
|
if (status || last == tail) return 0;
|
||||||
if (patt->flags & NTMALLOC)
|
if (patt->flags & NTMALLOC)
|
||||||
free(patt->str);
|
free(patt->str);
|
||||||
free(patt);
|
free(patt);
|
||||||
|
@ -1321,8 +1325,8 @@ rb_w32_cmdvector(const char *cmd, char ***vec)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
curr = ALLOC(NtCmdLineElement);
|
curr = (NtCmdLineElement *)calloc(sizeof(NtCmdLineElement), 1);
|
||||||
MEMZERO(curr, NtCmdLineElement, 1);
|
if (!curr) goto do_nothing;
|
||||||
curr->str = base;
|
curr->str = base;
|
||||||
curr->len = len;
|
curr->len = len;
|
||||||
|
|
||||||
|
@ -1347,7 +1351,18 @@ rb_w32_cmdvector(const char *cmd, char ***vec)
|
||||||
}
|
}
|
||||||
|
|
||||||
len = (elements+1)*sizeof(char *) + strsz;
|
len = (elements+1)*sizeof(char *) + strsz;
|
||||||
buffer = ALLOC_N(char, len);
|
buffer = (char *)malloc(len);
|
||||||
|
if (!buffer) {
|
||||||
|
do_nothing:
|
||||||
|
while (curr = cmdhead) {
|
||||||
|
cmdhead = curr->next;
|
||||||
|
if (curr->flags & NTMALLOC) free(curr->str);
|
||||||
|
free(curr);
|
||||||
|
}
|
||||||
|
free(cmdline);
|
||||||
|
for (vptr = *vec; *vptr; ++vptr);
|
||||||
|
return vptr - *vec;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// make vptr point to the start of the buffer
|
// make vptr point to the start of the buffer
|
||||||
|
@ -1447,6 +1462,7 @@ rb_w32_opendir(const char *filename)
|
||||||
fh = FindFirstFile(scanname, &fd);
|
fh = FindFirstFile(scanname, &fd);
|
||||||
if (fh == INVALID_HANDLE_VALUE) {
|
if (fh == INVALID_HANDLE_VALUE) {
|
||||||
errno = map_errno(GetLastError());
|
errno = map_errno(GetLastError());
|
||||||
|
free(p);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1456,9 +1472,14 @@ rb_w32_opendir(const char *filename)
|
||||||
//
|
//
|
||||||
|
|
||||||
idx = strlen(fd.cFileName)+1;
|
idx = strlen(fd.cFileName)+1;
|
||||||
p->start = ALLOC_N(char, idx);
|
if (!(p->start = (char *)malloc(idx)) || !(p->bits = (char *)malloc(1))) {
|
||||||
|
error:
|
||||||
|
rb_w32_closedir(p);
|
||||||
|
FindClose(fh);
|
||||||
|
errno = ENOMEM;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
strcpy(p->start, fd.cFileName);
|
strcpy(p->start, fd.cFileName);
|
||||||
p->bits = ALLOC_N(char, 1);
|
|
||||||
p->bits[0] = 0;
|
p->bits[0] = 0;
|
||||||
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
SetBit(p->bits, 0);
|
SetBit(p->bits, 0);
|
||||||
|
@ -1484,14 +1505,14 @@ rb_w32_opendir(const char *filename)
|
||||||
|
|
||||||
Renew (p->start, idx+len+1, char);
|
Renew (p->start, idx+len+1, char);
|
||||||
if (p->start == NULL) {
|
if (p->start == NULL) {
|
||||||
rb_fatal ("opendir: malloc failed!\n");
|
goto error;
|
||||||
}
|
}
|
||||||
strcpy(&p->start[idx], fd.cFileName);
|
strcpy(&p->start[idx], fd.cFileName);
|
||||||
|
|
||||||
if (p->nfiles % 4 == 0) {
|
if (p->nfiles % 4 == 0) {
|
||||||
Renew (p->bits, p->nfiles / 4 + 1, char);
|
Renew (p->bits, p->nfiles / 4 + 1, char);
|
||||||
if (p->bits == NULL) {
|
if (p->bits == NULL) {
|
||||||
rb_fatal ("opendir: malloc failed!\n");
|
goto error;
|
||||||
}
|
}
|
||||||
p->bits[p->nfiles / 4] = 0;
|
p->bits[p->nfiles / 4] = 0;
|
||||||
}
|
}
|
||||||
|
@ -3981,10 +4002,12 @@ rb_w32_get_environ(void)
|
||||||
for (env = envtop, num = 0; *env; env += strlen(env) + 1)
|
for (env = envtop, num = 0; *env; env += strlen(env) + 1)
|
||||||
if (*env != '=') num++;
|
if (*env != '=') num++;
|
||||||
|
|
||||||
myenvtop = ALLOC_N(char*, num + 1);
|
myenvtop = (char **)malloc(sizeof(char *) * (num + 1));
|
||||||
for (env = envtop, myenv = myenvtop; *env; env += strlen(env) + 1) {
|
for (env = envtop, myenv = myenvtop; *env; env += strlen(env) + 1) {
|
||||||
if (*env != '=') {
|
if (*env != '=') {
|
||||||
*myenv = ALLOC_N(char, strlen(env) + 1);
|
if (!(*myenv = (char *)malloc(strlen(env) + 1))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
strcpy(*myenv, env);
|
strcpy(*myenv, env);
|
||||||
myenv++;
|
myenv++;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче