PROC_WAITING if we have one
- unset_waitlist: unset PROC_WAITING in all procsubs
+ 7/18
+ ----
+jobs.c
+ - procsub_prune: set last_procsub_child to NULL if we are cleaning up
+ that process because it's terminated, since that will invalidate the
+ pointer
+
+ 7/22
+ ----
+lib/malloc/malloc.c
+ - RIGHT_BUCKET: don't check binsizes[nu-1] unless nu >= 1; clamp at 0
+ otherwise
+ - internal_realloc: don't check bucket at nunits-1 unless nunits >= 1
+ Report and fix from Collin Funk <collin.funk1@gmail.com>
GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
# endif
- array_push (bash_source_a, (char *)filename);
+ push_source (bash_source_a, (char *)filename);
t = itos (executing_line_number ());
array_push (bash_lineno_a, t);
free (t);
int check_window_size = CHECKWINSIZE_DEFAULT;
PROCESS *last_procsub_child = (PROCESS *)NULL;
+pid_t last_procsub_pid = NO_PID;
/* Set to non-zero if you want to force job notifications even in contexts
where the shell would defer them. */
return p;
}
+/* Take the PROCESS * corresponding to PID out of the procsubs list and
+ return it. */
PROCESS *
procsub_delete (pid_t pid, int block)
{
procsub_free (p);
}
procsubs.head = procsubs.end = 0;
- procsubs.nproc = 0;
+ procsubs.nproc = 0;
+
+ last_procsub_child = NULL;
UNBLOCK_CHILD (oset);
}
if (p->running == PS_DONE)
{
bgp_add (p->pid, process_exit_status (p->status));
+ if (p == last_procsub_child)
+ last_procsub_child = NULL;
procsub_free (p);
}
else
QUEUE_SIGCHLD(os);
procsub_prune ();
- last_procsub_child = (PROCESS *)NULL;
UNQUEUE_SIGCHLD (os);
}
#if defined (PROCESS_SUBSTITUTION)
/* Don't need to call procsub_reap() since SIGCHLD is already blocked. */
procsub_prune ();
- last_procsub_child = (PROCESS *)NULL;
#endif
#if defined (COPROCESS_SUPPORT)
/* If we're waiting for specific pids, skip over ones we're not interested in. */
if ((flags & JWAIT_WAITING) && (p->flags & PROC_WAITING) == 0)
continue;
+#if 0
+ /* If we want to restrict wait -n without pid arguments to only wait
+ for last_procsub_child->pid, uncomment this. */
+ if ((flags & JWAIT_WAITING) == 0 && p != last_procsub_child)
+ continue;
+#endif
if (p->running == PS_DONE)
{
return_procsub:
+ if (p == last_procsub_child)
+ last_procsub_child = (PROCESS *)NULL;
r = process_exit_status (p->status);
pid = p->pid;
if (ps)
ps->pid = pid;
ps->status = r;
}
- procsub_delete (pid, 0); /* XXX - procsub_reap? */
+ child = procsub_delete (pid, 0); /* XXX - procsub_reap? */
+ if (child == last_procsub_child)
+ last_procsub_child = NULL;
+ procsub_free (child);
if (posixly_correct)
bgp_delete (pid);
UNBLOCK_CHILD (oset);
{
if ((flags & JWAIT_WAITING) && (p->flags & PROC_WAITING) == 0)
continue;
+#if 0
+ /* If we want to restrict wait -n without pid arguments to only wait
+ for last_procsub_child->pid, uncomment this. */
+ if ((flags & JWAIT_WAITING) == 0 && p != last_procsub_child && p->running == PS_DONE)
+ continue;
+#endif
else if (p->running == PS_DONE)
goto return_procsub;
else if (p->running == PS_RUNNING) /* still got one */
extern int running_in_background;
extern PROCESS *last_procsub_child;
+extern pid_t last_procsub_pid;
extern JOB **jobs;
/* Use this when we want to be sure that NB is in bucket NU. */
#define RIGHT_BUCKET(nb, nu) \
- (((nb) > binsizes[(nu)-1]) && ((nb) <= binsizes[(nu)]))
+ (((nb) > (((nu) >= 1) ? binsizes[(nu)-1] : 0UL)) && ((nb) <= binsizes[(nu)]))
/* nextf[i] is free list of blocks of size 2**(i + 5) */
nbytes = ALLOCATED_BYTES(n);
/* If ok, use the same block, just marking its size as changed. */
- if (RIGHT_BUCKET(nbytes, nunits) || RIGHT_BUCKET(nbytes, nunits-1))
+ if (RIGHT_BUCKET(nbytes, nunits) || (nunits >= 1 && RIGHT_BUCKET(nbytes, nunits-1)))
{
/* Compensate for increment above. */
m -= 4;
GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a);
- array_push (bash_source_a, filename);
+ push_source (bash_source_a, filename);
if (bash_lineno_a)
{
t = itos (executing_line_number ());
pop_args ();
}
+#if defined (ARRAY_VARS)
+/* Push the current input filename onto BASH_SOURCE. This is where we can
+ apply any policy. */
+void
+push_source (ARRAY *a, char *filename)
+{
+ array_push (a, filename);
+}
+#endif
+
/*************************************************
* *
* Functions to manage special variables *
extern void pop_args (void);
extern void uw_pop_args (void *);
+#if defined (ARRAY_VARS)
+extern void push_source (ARRAY *, char *);
+#endif
+
extern void adjust_shell_level (int);
extern void non_unsettable (char *);
extern void dispose_variable (SHELL_VAR *);