[PATCH] ash: clear the NONBLOCK flag from stdin when in foreground

Alexey Fomenko ext-alexey.fomenko at nokia.com
Wed Aug 17 13:00:42 UTC 2011


Signed-off-by: ext-adam.endrodi at nokia.com
---
 shell/ash.c |   36 +++++++++++++++++++++++++++++++++++-
 1 files changed, 35 insertions(+), 1 deletions(-)

diff --git a/shell/ash.c b/shell/ash.c
index d48cd01..be9f138 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -3343,11 +3343,18 @@ struct procstat {
 	char    *ps_cmd;        /* text of command being run */
 };
 
+/* F_GETFL flags of the standard file descriptors */
+struct fdflags {
+	int stdinflags, stdoutflags, stderrflags;
+};
+
 struct job {
 	struct procstat ps0;    /* status of process */
 	struct procstat *ps;    /* status or processes when more than one */
 #if JOBS
 	int stopstatus;         /* status of a stopped job */
+	struct fdflags jobsfdflags; /* the job's standard file descriptor flags
+	                             * at the last time the job was stopped */
 #endif
 	uint32_t
 		nprocs: 16,     /* number of processes */
@@ -3847,6 +3854,24 @@ showpipe(struct job *jp /*, FILE *out*/)
 	flush_stdout_stderr();
 }
 
+static void
+restore_fdflags(const struct fdflags *f)
+{
+	if (f->stdinflags >= 0)
+		fcntl(0, F_SETFL, f->stdinflags);
+	if (f->stdoutflags >= 0)
+		fcntl(1, F_SETFL, f->stdoutflags);
+	if (f->stderrflags >= 0)
+		fcntl(2, F_SETFL, f->stderrflags);
+}
+
+static void
+save_fdflags(struct fdflags *f)
+{
+	f->stdinflags  = fcntl(0, F_GETFL);
+	f->stdoutflags = fcntl(1, F_GETFL);
+	f->stderrflags = fcntl(2, F_GETFL);
+}
 
 static int
 restartjob(struct job *jp, int mode)
@@ -3861,8 +3886,10 @@ restartjob(struct job *jp, int mode)
 		goto out;
 	jp->state = JOBRUNNING;
 	pgid = jp->ps[0].ps_pid;
-	if (mode == FORK_FG)
+	if (mode == FORK_FG) {
+		restore_fdflags(&jp->jobsfdflags);
 		xtcsetpgrp(ttyfd, pgid);
+	}
 	killpg(pgid, SIGCONT);
 	ps = jp->ps;
 	i = jp->nprocs;
@@ -4351,6 +4378,9 @@ makejob(/*union node *node,*/ int nprocs)
 	if (doing_jobctl)
 		jp->jobctl = 1;
 #endif
+	jp->jobsfdflags.stdinflags
+		= jp->jobsfdflags.stdoutflags
+		= jp->jobsfdflags.stderrflags = -1;
 	jp->prev_job = curjob;
 	curjob = jp;
 	jp->used = 1;
@@ -4945,6 +4975,7 @@ waitforjob(struct job *jp)
 	st = getstatus(jp);
 #if JOBS
 	if (jp->jobctl) {
+		save_fdflags(&jp->jobsfdflags);
 		xtcsetpgrp(ttyfd, rootpid);
 		/*
 		 * This is truly gross.
@@ -12138,12 +12169,15 @@ cmdloop(int top)
 	struct stackmark smark;
 	int inter;
 	int numeof = 0;
+	struct fdflags myfdflags;
 
 	TRACE(("cmdloop(%d) called\n", top));
+	save_fdflags(&myfdflags);
 	for (;;) {
 		int skip;
 
 		setstackmark(&smark);
+		restore_fdflags(&myfdflags);
 #if JOBS
 		if (doing_jobctl)
 			showjobs(stderr, SHOW_CHANGED);
-- 
1.7.2.5



More information about the busybox mailing list