- if DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS is defined, don't print an
error message from sh_wrerror if errno == EPIPE. Suggestion from
Petr Sumbera <petr.sumbera@sun.com>
+
+ 9/19
+ ----
+{jobs,nojobs}.c,jobs.h
+ - add code to retry fork() after EAGAIN, with a progressively longer
+ sleep between attempts, up to FORKSLEEP_MAX (16) seconds. Suggested
+ by Martin Koeppe <mkoeppe@gmx.de>
line was actually added (HISTIGNORE may have caused it to not be),
so we check hist_last_line_added. */
- /* "When not listing, he fc command that caused the editing shall not be
+ /* "When not listing, the fc command that caused the editing shall not be
entered into the history list." */
if (listing == 0 && hist_last_line_added)
delete_last_history ();
Provides control over the resources available to the shell and to
processes started by it, on systems that allow such control.
The \fB\-H\fP and \fB\-S\fP options specify that the hard or soft limit is
-set for the given resource. A hard limit cannot be increased once it
-is set; a soft limit may be increased up to the value of the hard limit.
+set for the given resource.
+A hard limit cannot be increased by a non-root user once it is set;
+a soft limit may be increased up to the value of the hard limit.
If neither \fB\-H\fP nor \fB\-S\fP is specified, both the soft and hard
limits are set.
The value of
the special @var{limit} values @code{hard}, @code{soft}, and
@code{unlimited} stand for the current hard limit, the current soft limit,
and no limit, respectively.
+A hard limit cannot be increased by a non-root user once it is set;
+a soft limit may be increased up to the value of the hard limit.
Otherwise, the current value of the soft limit for the specified resource
is printed, unless the @option{-H} option is supplied.
When setting new limits, if neither @option{-H} nor @option{-S} is supplied,
char *command;
int async_p;
{
+ int forksleep;
sigset_t set, oset;
pid_t pid;
sync_buffered_stream (default_buffered_input);
#endif /* BUFFERED_INPUT */
- /* Create the child, handle severe errors. */
- if ((pid = fork ()) < 0)
+ /* Create the child, handle severe errors. Retry on EAGAIN. */
+ while ((pid = fork ()) < 0 && errno == EAGAIN && forksleep < FORKSLEEP_MAX)
+ {
+ sys_error ("fork: retry");
+ if (sleep (forksleep) != 0)
+ break;
+ forksleep <<= 1;
+ }
+
+ if (pid < 0)
{
sys_error ("fork");
/* I looked it up. For pretty_print_job (). The real answer is 24. */
#define LONGEST_SIGNAL_DESC 24
+/* The max time to sleep while retrying fork() on EAGAIN failure */
+#define FORKSLEEP_MAX 16
+
/* We keep an array of jobs. Each entry in the array is a linked list
of processes that are piped together. The first process encountered is
the group leader. */
int async_p;
{
pid_t pid;
-#if defined (HAVE_WAITPID)
- int retry = 1;
-#endif /* HAVE_WAITPID */
+ int forksleep;
/* Discard saved memory. */
if (command)
sync_buffered_stream (default_buffered_input);
#endif /* BUFFERED_INPUT */
- /* Create the child, handle severe errors. */
-#if defined (HAVE_WAITPID)
- retry_fork:
-#endif /* HAVE_WAITPID */
-
- if ((pid = fork ()) < 0)
+ /* Create the child, handle severe errors. Retry on EAGAIN. */
+ forksleep = 1;
+ while ((pid = fork ()) < 0 && errno == EAGAIN && forksleep < FORKSLEEP_MAX)
{
+ sys_error ("fork: retry");
#if defined (HAVE_WAITPID)
/* Posix systems with a non-blocking waitpid () system call available
get another chance after zombies are reaped. */
- if (errno == EAGAIN && retry)
- {
- reap_zombie_children ();
- retry = 0;
- goto retry_fork;
- }
+ reap_zombie_children ();
+ if (forksleep > 1 && sleep (forksleep) != 0)
+ break;
+#else
+ if (sleep (forksleep) != 0)
+ break;
#endif /* HAVE_WAITPID */
+ forksleep <<= 1;
+ }
+ if (pid < 0)
+ {
sys_error ("fork");
-
throw_to_top_level ();
}