~ubuntu-branches/ubuntu/feisty/findutils/feisty

« back to all changes in this revision

Viewing changes to lib/buildcmd.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Metzler
  • Date: 2006-08-06 09:53:05 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20060806095305-265uqmwsguy8vfjq
Tags: 4.2.28-1
* New upstream version.
 - includes 01_updatedb-withnew-su.dpatch, drop it.

Show diffs side-by-side

added added

removed removed

Lines of Context:
92
92
 
93
93
#include "buildcmd.h"
94
94
 
 
95
 
 
96
extern char **environ;
 
97
 
 
98
 
95
99
static char *mbstrstr PARAMS ((const char *haystack, const char *needle));
96
100
 
97
101
/* Replace all instances of `replace_pat' in ARG with `linebuf',
118
122
     real arg.  */
119
123
  static char *insertbuf;
120
124
  char *p;
121
 
  int bytes_left = ctl->arg_max - 1;    /* Bytes left on the command line.  */
 
125
  size_t bytes_left = ctl->arg_max - 1;    /* Bytes left on the command line.  */
122
126
  int need_prefix;
123
127
 
124
128
  /* XXX: on systems lacking an upper limit for exec args, ctl->arg_max
145
149
          len = arglen;
146
150
        }
147
151
      
148
 
      bytes_left -= len;
149
 
      if (bytes_left <= 0)
 
152
      if (bytes_left <= len)
150
153
        break;
 
154
      else
 
155
        bytes_left -= len;
151
156
 
152
157
      strncpy (p, arg, len);
153
158
      p += len;
156
161
 
157
162
      if (s)
158
163
        {
159
 
          bytes_left -= lblen;
160
 
          if (bytes_left <= 0)
161
 
            break;
 
164
          if (bytes_left <= lblen)
 
165
            break;
 
166
          else
 
167
            bytes_left -= lblen;
 
168
 
162
169
          strcpy (p, linebuf);
163
170
          arg += ctl->rplen;
164
171
          arglen -= ctl->rplen;
325
332
  return strstr (haystack, needle);
326
333
}
327
334
 
328
 
 
329
 
long
 
335
static size_t
 
336
get_line_max(void)
 
337
{
 
338
  long val;
 
339
#ifdef _SC_LINE_MAX  
 
340
  val = sysconf(_SC_LINE_MAX);
 
341
#else
 
342
  val = -1;
 
343
#endif
 
344
  
 
345
  if (val > 0)
 
346
    return val;
 
347
 
 
348
  /* either _SC_LINE_MAX was not available or 
 
349
   * there is no particular limit.
 
350
   */
 
351
#ifdef LINE_MAX
 
352
  val = LINE_MAX;
 
353
#endif
 
354
 
 
355
  if (val > 0)
 
356
    return val;
 
357
 
 
358
  return 2048L;                 /* a reasonable guess. */
 
359
}
 
360
 
 
361
 
 
362
size_t
330
363
bc_get_arg_max(void)
331
364
{
332
365
  long val;
 
366
 
 
367
  /* We may resort to using LONG_MAX, so check it fits. */
 
368
  /* XXX: better to do a compile-time check */
 
369
  assert( (~(size_t)0) >= LONG_MAX);
 
370
 
333
371
#ifdef _SC_ARG_MAX  
334
372
  val = sysconf(_SC_ARG_MAX);
335
373
#else
336
374
  val = -1;
337
375
#endif
338
 
  
 
376
 
339
377
  if (val > 0)
340
378
    return val;
341
379
 
369
407
  return 0;
370
408
}
371
409
 
372
 
void
 
410
 
 
411
/* Return how much of ARG_MAX is used by the environment.  */
 
412
size_t
 
413
bc_size_of_environment (void)
 
414
{
 
415
  size_t len = 0u;
 
416
  char **envp = environ;
 
417
 
 
418
  while (*envp)
 
419
    len += strlen (*envp++) + 1;
 
420
 
 
421
  return len;
 
422
}
 
423
 
 
424
 
 
425
enum BC_INIT_STATUS
373
426
bc_init_controlinfo(struct buildcmd_control *ctl)
374
427
{
375
 
  long arg_max = bc_get_arg_max();
376
 
  assert(arg_max > 0);
 
428
  size_t size_of_environment = bc_size_of_environment();
 
429
  size_t arg_max;
 
430
  
 
431
  ctl->posix_arg_size_min = get_line_max();
 
432
  arg_max = bc_get_arg_max();
 
433
  
 
434
  /* POSIX.2 requires subtracting 2048.  */
 
435
  assert(arg_max > 2048u);      /* XXX: this is an external condition, should not check it with assert. */
 
436
  ctl->posix_arg_size_max = (arg_max - 2048);
377
437
  
378
438
  ctl->exit_if_size_exceeded = 0;
379
 
  ctl->arg_max = arg_max - 2048; /* a la xargs */
 
439
 
 
440
  /* Take the size of the environment into account.  */
 
441
  if (size_of_environment > ctl->posix_arg_size_max)
 
442
    {
 
443
      return BC_INIT_ENV_TOO_BIG;
 
444
    }
 
445
  else
 
446
    {
 
447
      ctl->posix_arg_size_max - size_of_environment;
 
448
    }
 
449
 
380
450
  /* need to subtract 2 on the following line - for Linux/PPC */
381
 
  ctl->max_arg_count = (arg_max / sizeof(void*)) - 2;
 
451
  ctl->max_arg_count = (ctl->posix_arg_size_max / sizeof(char*)) - 2u;
382
452
  assert(ctl->max_arg_count > 0);
383
453
  ctl->rplen = 0u;
384
454
  ctl->replace_pat = NULL;
386
456
  ctl->exec_callback = cb_exec_noop;
387
457
  ctl->lines_per_exec = 0;
388
458
  ctl->args_per_exec = 0;
389
 
}
 
459
 
 
460
  /* Set the initial value of arg_max to the largest value we can
 
461
   * tolerate.
 
462
   */
 
463
  ctl->arg_max = ctl->posix_arg_size_max;
 
464
 
 
465
  return BC_INIT_OK;
 
466
}
 
467
 
 
468
void
 
469
bc_use_sensible_arg_max(struct buildcmd_control *ctl)
 
470
{
 
471
  size_t env_size = bc_size_of_environment();
 
472
  const size_t arg_size = (128u * 1024u) + env_size;
 
473
  
 
474
  /* Check against the upper and lower limits. */  
 
475
  if (arg_size > ctl->posix_arg_size_max)
 
476
    ctl->arg_max = ctl->posix_arg_size_max - env_size;
 
477
  else if (arg_size < ctl->posix_arg_size_min)
 
478
    ctl->arg_max = ctl->posix_arg_size_min;
 
479
  else 
 
480
    ctl->arg_max = arg_size;
 
481
}
 
482
 
 
483
 
 
484
 
390
485
 
391
486
void
392
487
bc_init_state(const struct buildcmd_control *ctl,
399
494
  state->cmd_argv_alloc = 0;
400
495
  
401
496
  /* XXX: the following memory allocation is inadvisable on systems
402
 
   * with no ARG_MAX, because ctl->arg_max may actually be LONG_MAX.
403
 
   * Also, adding one to that is a bad idea.
 
497
   * with no ARG_MAX, because ctl->arg_max may actually be close to 
 
498
   * LONG_MAX.   Adding one to it is safe though because earlier we
 
499
   * subtracted 2048.
404
500
   */
405
 
  state->argbuf = (char *) xmalloc (ctl->arg_max + 1);
 
501
  assert(ctl->arg_max <= (LONG_MAX - 2048L));
 
502
  state->argbuf = (char *) xmalloc (ctl->arg_max + 1u);
406
503
  
407
504
  state->cmd_argv_chars = state->cmd_initial_argv_chars = 0;
408
505
  state->todo = 0;