Exemple #1
0
/* XXX: sometimes this function is called (internally) 
 *      just to push a NULL onto the and of the arg list.
 *      We should probably do that with a separate function
 *      for greater clarity.
 */
void
bc_push_arg (const struct buildcmd_control *ctl,
             struct buildcmd_state *state,
             const char *arg, size_t len,
             const char *prefix, size_t pfxlen,
             int initial_args)
{
  if (!initial_args)
    {
      state->todo = 1;
    }
  
  if (arg)
    {
      /* XXX_SOC: if do_exec() is only guaranteeed to free up one
       * argument, this if statement may need to become a while loop.
       * If it becomes a while loop, it needs not to be an infinite
       * loop...
       */
      if (state->cmd_argv_chars + len > ctl->arg_max)
        {
          if (initial_args || state->cmd_argc == ctl->initial_argc)
            error (1, 0, _("can not fit single argument within argument list size limit"));
          /* xargs option -i (replace_pat) implies -x (exit_if_size_exceeded) */
          if (ctl->replace_pat
              || (ctl->exit_if_size_exceeded &&
                  (ctl->lines_per_exec || ctl->args_per_exec)))
            error (1, 0, _("argument list too long"));
          do_exec (ctl, state);
        }
      /* XXX_SOC: this if may also need to become a while loop.  In
	 fact perhaps it is best to factor this out into a separate
	 function which ceeps calling the exec handler until there is
	 space for our next argument.  Each exec will free one argc
	 "slot" so the main thing to worry about repeated exec calls
	 for would be total argument length.
       */
      if (bc_argc_limit_reached(initial_args, ctl, state))
	do_exec (ctl, state);
    }

  if (state->cmd_argc >= state->cmd_argv_alloc)
    {
      /* XXX: we could use extendbuf() here. */
      if (!state->cmd_argv)
        {
          state->cmd_argv_alloc = 64;
          state->cmd_argv = xmalloc (sizeof (char *) * state->cmd_argv_alloc);
        }
      else
        {
          state->cmd_argv_alloc *= 2;
          state->cmd_argv = xrealloc (state->cmd_argv,
				      sizeof (char *) * state->cmd_argv_alloc);
        }
    }

  if (!arg)
    state->cmd_argv[state->cmd_argc++] = NULL;
  else
    {
      state->cmd_argv[state->cmd_argc++] = state->argbuf + state->cmd_argv_chars;
      if (prefix)
        {
          strcpy (state->argbuf + state->cmd_argv_chars, prefix);
          state->cmd_argv_chars += pfxlen;
        }
      
      strcpy (state->argbuf + state->cmd_argv_chars, arg);
      state->cmd_argv_chars += len;
      
      /* If we have now collected enough arguments,
       * do the exec immediately.  This must be 
       * conditional on arg!=NULL, since do_exec() 
       * actually calls bc_push_arg(ctl, state, NULL, 0, false).
       */
      if (bc_argc_limit_reached(initial_args, ctl, state))
	do_exec (ctl, state);
    }

  /* If this is an initial argument, set the high-water mark. */
  if (initial_args)
    {
      state->cmd_initial_argv_chars = state->cmd_argv_chars;
    }
}
Exemple #2
0
void
bc_push_arg (const struct buildcmd_control *ctl,
             struct buildcmd_state *state,
             const char *arg, size_t len,
             const char *prefix, size_t pfxlen,
             int initial_args)
{
  if (!initial_args)
    state->todo = 1;
  
  if (arg)
    {
      if (state->cmd_argv_chars + len > ctl->arg_max)
        {
          if (initial_args || state->cmd_argc == ctl->initial_argc)
            error (1, 0, _("can not fit single argument within argument list size limit"));
          /* option -i (replace_pat) implies -x (exit_if_size_exceeded) */
          if (ctl->replace_pat
              || (ctl->exit_if_size_exceeded &&
                  (ctl->lines_per_exec || ctl->args_per_exec)))
            error (1, 0, _("argument list too long"));
          do_exec (ctl, state);
        }
      
      if (bc_argc_limit_reached(initial_args, ctl, state))
	do_exec (ctl, state);
    }

  if (state->cmd_argc >= state->cmd_argv_alloc)
    {
      if (!state->cmd_argv)
        {
          state->cmd_argv_alloc = 64;
          state->cmd_argv = (char **) xmalloc (sizeof (char *) * state->cmd_argv_alloc);
        }
      else
        {
          state->cmd_argv_alloc *= 2;
          state->cmd_argv = (char **) xrealloc (state->cmd_argv,
                                         sizeof (char *) * state->cmd_argv_alloc);
        }
    }

  if (!arg)
    state->cmd_argv[state->cmd_argc++] = NULL;
  else
    {
      state->cmd_argv[state->cmd_argc++] = state->argbuf + state->cmd_argv_chars;
      if (prefix)
        {
          strcpy (state->argbuf + state->cmd_argv_chars, prefix);
          state->cmd_argv_chars += pfxlen;
        }
      
      strcpy (state->argbuf + state->cmd_argv_chars, arg);
      state->cmd_argv_chars += len;
      
      /* If we have now collected enough arguments,
       * do the exec immediately.  This must be 
       * conditional on arg!=NULL, since do_exec() 
       * actually calls bc_push_arg(ctl, state, NULL, 0, false).
       */
      if (bc_argc_limit_reached(initial_args, ctl, state))
	do_exec (ctl, state);
    }

  /* If this is an initial argument, set the high-water mark. */
  if (initial_args)
    {
      state->cmd_initial_argv_chars = state->cmd_argv_chars;
    }
}