Submitted By: Armin K. Date: 2012-09-19 Initial Package Version: 3.82 Upstream Status: Fixed Upstream Origin: Upstream Description: Several bug fixes from upstream cvs. --- make.orig/expand.c 2010-07-13 03:20:39.000000000 +0200 +++ make/expand.c 2012-09-19 17:25:52.496989738 +0200 @@ -197,7 +197,7 @@ { struct variable *v; const char *p, *p1; - char *abuf = NULL; + char *save; char *o; unsigned int line_offset; @@ -212,16 +212,11 @@ return (variable_buffer); } - /* If we want a subset of the string, allocate a temporary buffer for it. - Most of the functions we use here don't work with length limits. */ - if (length > 0 && string[length] != '\0') - { - abuf = xmalloc(length+1); - memcpy(abuf, string, length); - abuf[length] = '\0'; - string = abuf; - } - p = string; + /* We need a copy of STRING: due to eval, it's possible that it will get + freed as we process it (it might be the value of a variable that's reset + for example). Also having a nil-terminated string is handy. */ + save = length < 0 ? xstrdup (string) : xstrndup (string, length); + p = save; while (1) { @@ -411,8 +406,7 @@ ++p; } - if (abuf) - free (abuf); + free (save); variable_buffer_output (o, "", 1); return (variable_buffer + line_offset); --- make.orig/function.c 2010-07-13 03:20:39.000000000 +0200 +++ make/function.c 2012-09-19 17:25:52.509989959 +0200 @@ -706,7 +706,7 @@ const char *word_iterator = argv[0]; char buf[20]; - while (find_next_token (&word_iterator, (unsigned int *) 0) != 0) + while (find_next_token (&word_iterator, NULL) != 0) ++i; sprintf (buf, "%d", i); @@ -1133,21 +1133,14 @@ /* Find the maximum number of words we'll have. */ t = argv[0]; - wordi = 1; - while (*t != '\0') + wordi = 0; + while ((p = find_next_token (&t, NULL)) != 0) { - char c = *(t++); - - if (! isspace ((unsigned char)c)) - continue; - + ++t; ++wordi; - - while (isspace ((unsigned char)*t)) - ++t; } - words = xmalloc (wordi * sizeof (char *)); + words = xmalloc ((wordi == 0 ? 1 : wordi) * sizeof (char *)); /* Now assign pointers to each string in the array. */ t = argv[0]; --- make.orig/job.c 2010-07-24 10:27:50.000000000 +0200 +++ make/job.c 2012-09-19 17:25:52.509989959 +0200 @@ -29,6 +29,15 @@ #include +#if defined(__linux__) /* defined (HAVE_LINUX_BINFMTS_H) && defined (HAVE_SYS_USER_H) */ +#include +#include +#ifndef PAGE_SIZE +#define PAGE_SIZE sysconf(_SC_PAGE_SIZE) +#endif +#include +#endif + /* Default shell to use. */ #ifdef WINDOWS32 #include @@ -2791,6 +2800,15 @@ argument list. */ unsigned int shell_len = strlen (shell); +#ifdef MAX_ARG_STRLEN + static char eval_line[] = "eval\\ \\\"set\\ x\\;\\ shift\\;\\ "; +#define ARG_NUMBER_DIGITS 5 +#define EVAL_LEN (sizeof(eval_line)-1 + shell_len + 4 \ + + (7 + ARG_NUMBER_DIGITS) * 2 * line_len / (MAX_ARG_STRLEN - 2)) +#else +#define EVAL_LEN 0 +#endif + char *args_ptr; unsigned int line_len = strlen (line); unsigned int sflags_len = strlen (shellflags); char *command_ptr = NULL; /* used for batch_mode_shell mode */ @@ -2866,7 +2884,7 @@ } new_line = alloca (shell_len + 1 + sflags_len + 1 - + (line_len*2) + 1); + + (line_len*2) + 1 + EVAL_LEN); ap = new_line; memcpy (ap, shell, shell_len); ap += shell_len; @@ -2875,6 +2893,30 @@ ap += sflags_len; *(ap++) = ' '; command_ptr = ap; + +#if !defined (WINDOWS32) && defined (MAX_ARG_STRLEN) + if (unixy_shell && line_len > MAX_ARG_STRLEN) + { + unsigned j; + memcpy (ap, eval_line, sizeof (eval_line) - 1); + ap += sizeof (eval_line) - 1; + for (j = 1; j <= 2 * line_len / (MAX_ARG_STRLEN - 2); j++) + ap += sprintf (ap, "\\$\\{%u\\}", j); + *ap++ = '\\'; + *ap++ = '"'; + *ap++ = ' '; + /* Copy only the first word of SHELL to $0. */ + for (p = shell; *p != '\0'; ++p) + { + if (isspace ((unsigned char)*p)) + break; + *ap++ = *p; + } + *ap++ = ' '; + } +#endif + args_ptr = ap; + for (p = line; *p != '\0'; ++p) { if (restp != NULL && *p == '\n') @@ -2922,6 +2964,14 @@ } #endif *ap++ = *p; + +#if !defined (WINDOWS32) && defined (MAX_ARG_STRLEN) + if (unixy_shell && line_len > MAX_ARG_STRLEN && (ap - args_ptr > MAX_ARG_STRLEN - 2)) + { + *ap++ = ' '; + args_ptr = ap; + } +#endif } if (ap == new_line + shell_len + sflags_len + 2) /* Line was empty. */ --- make.orig/main.c 2010-07-19 09:10:53.000000000 +0200 +++ make/main.c 2012-09-19 17:25:52.510989976 +0200 @@ -1138,7 +1138,7 @@ a macro and some compilers (MSVC) don't like conditionals in macros. */ { const char *features = "target-specific order-only second-expansion" - " else-if shortest-stem undefine" + " else-if shortest-stem undefine oneshell" #ifndef NO_ARCHIVES " archives" #endif @@ -2088,12 +2088,17 @@ ++restarts; + /* If we're re-exec'ing the first make, put back the number of + job slots so define_makefiles() will get it right. */ + if (master_job_slots) + job_slots = master_job_slots; + /* Reset makeflags in case they were changed. */ { const char *pv = define_makeflags (1, 1); char *p = alloca (sizeof ("MAKEFLAGS=") + strlen (pv) + 1); sprintf (p, "MAKEFLAGS=%s", pv); - putenv (p); + putenv (allocated_variable_expand (p)); } if (ISDB (DB_BASIC)) @@ -2824,9 +2829,6 @@ && (*(unsigned int *) cs->value_ptr == *(unsigned int *) cs->noarg_value)) ADD_FLAG ("", 0); /* Optional value omitted; see below. */ - else if (cs->c == 'j') - /* Special case for `-j'. */ - ADD_FLAG ("1", 1); else { char *buf = alloca (30); --- make.orig/read.c 2010-07-13 03:20:42.000000000 +0200 +++ make/read.c 2012-09-19 17:25:52.511989993 +0200 @@ -2904,6 +2904,7 @@ const char *name; const char **nlist = 0; char *tildep = 0; + int globme = 1; #ifndef NO_ARCHIVES char *arname = 0; char *memname = 0; @@ -3028,7 +3029,7 @@ { /* This looks like the first element in an open archive group. A valid group MUST have ')' as the last character. */ - const char *e = p + nlen; + const char *e = p; do { e = next_token (e); @@ -3084,19 +3085,19 @@ Go to the next item in the string. */ if (flags & PARSEFS_NOGLOB) { - NEWELT (concat (2, prefix, tp)); + NEWELT (concat (2, prefix, tmpbuf)); continue; } /* If we get here we know we're doing glob expansion. TP is a string in tmpbuf. NLEN is no longer used. We may need to do more work: after this NAME will be set. */ - name = tp; + name = tmpbuf; /* Expand tilde if applicable. */ - if (tp[0] == '~') + if (tmpbuf[0] == '~') { - tildep = tilde_expand (tp); + tildep = tilde_expand (tmpbuf); if (tildep != 0) name = tildep; } @@ -3112,32 +3113,40 @@ } #endif /* !NO_ARCHIVES */ - switch (glob (name, GLOB_NOSORT|GLOB_ALTDIRFUNC, NULL, &gl)) - { - case GLOB_NOSPACE: - fatal (NILF, _("virtual memory exhausted")); - - case 0: - /* Success. */ - i = gl.gl_pathc; - nlist = (const char **)gl.gl_pathv; - break; - - case GLOB_NOMATCH: - /* If we want only existing items, skip this one. */ - if (flags & PARSEFS_EXISTS) - { - i = 0; - break; - } - /* FALLTHROUGH */ - - default: - /* By default keep this name. */ + /* glob() is expensive: don't call it unless we need to. */ + if (!(flags & PARSEFS_EXISTS) && strpbrk (name, "?*[") == NULL) + { + globme = 0; i = 1; nlist = &name; - break; - } + } + else + switch (glob (name, GLOB_NOSORT|GLOB_ALTDIRFUNC, NULL, &gl)) + { + case GLOB_NOSPACE: + fatal (NILF, _("virtual memory exhausted")); + + case 0: + /* Success. */ + i = gl.gl_pathc; + nlist = (const char **)gl.gl_pathv; + break; + + case GLOB_NOMATCH: + /* If we want only existing items, skip this one. */ + if (flags & PARSEFS_EXISTS) + { + i = 0; + break; + } + /* FALLTHROUGH */ + + default: + /* By default keep this name. */ + i = 1; + nlist = &name; + break; + } /* For each matched element, add it to the list. */ while (i-- > 0) @@ -3152,7 +3161,10 @@ else { /* We got a chain of items. Attach them. */ - (*newp)->next = found; + if (*newp) + (*newp)->next = found; + else + *newp = found; /* Find and set the new end. Massage names if necessary. */ while (1) @@ -3174,7 +3186,8 @@ #endif /* !NO_ARCHIVES */ NEWELT (concat (2, prefix, nlist[i])); - globfree (&gl); + if (globme) + globfree (&gl); #ifndef NO_ARCHIVES if (arname) --- make.orig/remake.c 2010-07-13 03:20:42.000000000 +0200 +++ make/remake.c 2012-09-19 17:26:09.116270849 +0200 @@ -614,6 +614,10 @@ d->file->dontcare = file->dontcare; } + /* We may have already considered this file, when we didn't know + we'd need to update it. Force update_file() to consider it and + not prune it. */ + d->file->considered = !considered; dep_status |= update_file (d->file, depth);