summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2011-07-12 20:37:18 +0000
committerkib <kib@FreeBSD.org>2011-07-12 20:37:18 +0000
commit09ee3c95a50245039079062566f7368fc034ba87 (patch)
tree8add58a7d0d1796d3df9902e1188f5aa16bd89fe
parent751d3abdea3b16734bff1812e7e8e18b69c9fdd9 (diff)
downloadFreeBSD-src-09ee3c95a50245039079062566f7368fc034ba87.zip
FreeBSD-src-09ee3c95a50245039079062566f7368fc034ba87.tar.gz
Implement an RFTSIGZMB flag to rfork(2) to specify a signal that is
delivered to parent when the child exists. Submitted by: Petr Salinger <Petr.Salinger seznam cz> (Debian/kFreeBSD) MFC after: 1 week X-MFC-note: bump __FreeBSD_version
-rw-r--r--sys/kern/kern_fork.c17
-rw-r--r--sys/sys/unistd.h8
2 files changed, 24 insertions, 1 deletions
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index a8abd8e..9d3e22d 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -476,7 +476,10 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2,
sigacts_copy(newsigacts, p1->p_sigacts);
p2->p_sigacts = newsigacts;
}
- if (flags & RFLINUXTHPN)
+
+ if (flags & RFTSIGZMB)
+ p2->p_sigparent = RFTSIGNUM(flags);
+ else if (flags & RFLINUXTHPN)
p2->p_sigparent = SIGUSR1;
else
p2->p_sigparent = SIGCHLD;
@@ -719,10 +722,22 @@ fork1(struct thread *td, int flags, int pages, struct proc **procp)
static int curfail;
static struct timeval lastfail;
+ /* Check for the undefined or unimplemented flags. */
+ if ((flags & ~(RFFLAGS | RFTSIGFLAGS(RFTSIGMASK))) != 0)
+ return (EINVAL);
+
+ /* Signal value requires RFTSIGZMB. */
+ if ((flags & RFTSIGFLAGS(RFTSIGMASK)) != 0 && (flags & RFTSIGZMB) == 0)
+ return (EINVAL);
+
/* Can't copy and clear. */
if ((flags & (RFFDG|RFCFDG)) == (RFFDG|RFCFDG))
return (EINVAL);
+ /* Check the validity of the signal number. */
+ if ((flags & RFTSIGZMB) != 0 && (u_int)RFTSIGNUM(flags) > _SIG_MAXSIG)
+ return (EINVAL);
+
p1 = td->td_proc;
/*
diff --git a/sys/sys/unistd.h b/sys/sys/unistd.h
index 378308d..9d56a3a 100644
--- a/sys/sys/unistd.h
+++ b/sys/sys/unistd.h
@@ -180,8 +180,16 @@
#define RFLINUXTHPN (1<<16) /* do linux clone exit parent notification */
#define RFSTOPPED (1<<17) /* leave child in a stopped state */
#define RFHIGHPID (1<<18) /* use a pid higher than 10 (idleproc) */
+#define RFTSIGZMB (1<<19) /* select signal for exit parent notification */
+#define RFTSIGSHIFT 20 /* selected signal number is in bits 20-27 */
+#define RFTSIGMASK 0xFF
+#define RFTSIGNUM(flags) (((flags) >> RFTSIGSHIFT) & RFTSIGMASK)
+#define RFTSIGFLAGS(signum) ((signum) << RFTSIGSHIFT)
#define RFPPWAIT (1<<31) /* parent sleeps until child exits (vfork) */
#define RFKERNELONLY (RFSTOPPED | RFHIGHPID | RFPPWAIT)
+#define RFFLAGS (RFFDG | RFPROC | RFMEM | RFNOWAIT | RFCFDG | \
+ RFTHREAD | RFSIGSHARE | RFLINUXTHPN | RFSTOPPED | RFHIGHPID | RFTSIGZMB | \
+ RFPPWAIT)
#endif /* __BSD_VISIBLE */
OpenPOWER on IntegriCloud