[PATCH] Improve LinuxThreads compatibility in rfork()
Kostik Belousov
kostikbel at gmail.com
Tue Jul 12 10:35:35 UTC 2011
On Tue, Jul 12, 2011 at 11:16:28AM +0200, Petr Salinger wrote:
> >>Seems this interface be acceptable ?
> >
> >Looks good to me.
>
> The proposed code changes are in the attached patch.
>
> Proposed wording of addition into RFORK(2):
Below is the patch I intend to commit after you retest it.
I added the checks for validity of the flags, and some rewording to the
manual page.
diff --git a/lib/libc/sys/rfork.2 b/lib/libc/sys/rfork.2
index f1ae14b..993fd1b 100644
--- a/lib/libc/sys/rfork.2
+++ b/lib/libc/sys/rfork.2
@@ -5,7 +5,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd March 15, 2011
+.Dd July 12, 2011
.Dt RFORK 2
.Os
.Sh NAME
@@ -84,6 +84,16 @@ Note that a lot of code will not run correctly in such an environment.
.It Dv RFSIGSHARE
If set, the kernel will force sharing the sigacts structure between the
child and the parent.
+.It Dv RFTSIGZMB
+If set, the kernel will deliver a specified signal to the parent
+upon the child exit, instead of default SIGCHILD.
+The signal number
+.Dv signum
+is specified by oring the
+.Dv RFTSIGFLAGS(signum)
+expression into
+.Fa flags .
+Specifying signal number 0 disables signal delivery upon the child exit.
.It Dv RFLINUXTHPN
If set, the kernel will return SIGUSR1 instead of SIGCHILD upon thread
exit for the child.
@@ -164,6 +174,8 @@ would be exceeded (see
Both the RFFDG and the RFCFDG flags were specified.
.It Bq Er EINVAL
Any flags not listed above were specified.
+.It Bq Er EINVAL
+An invalid signal number was specified.
.It Bq Er ENOMEM
There is insufficient swap space for the new process.
.El
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 */
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-current/attachments/20110712/3209404b/attachment.pgp
More information about the freebsd-current
mailing list