diff options
| author | Linus Torvalds <torvalds@home.osdl.org> | 2003-08-13 21:11:39 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.osdl.org> | 2003-08-13 21:11:39 -0700 |
| commit | 856c781e96c564bf22c3a9c49eabb09563e3bf23 (patch) | |
| tree | f6746a00f365a839cdc09722c61031061c6d142c | |
| parent | 7ea448d5256a3a0c058ece8e3eddf28c16a72d34 (diff) | |
Mark CLONE_DETACHED as being irrelevant: it must match CLONE_THREAD.
CLONE_THREAD without CLONE_DETACHED will now return -EINVAL, and
for a while we will warn about anything that uses it (there are no
known users, but this will help pinpoint any problems if somebody
used to care about the invalid combination).
| -rw-r--r-- | include/linux/sched.h | 2 | ||||
| -rw-r--r-- | kernel/fork.c | 21 |
2 files changed, 17 insertions, 6 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h index 70eb61ecf4a3..4c96f1df2e5c 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -49,7 +49,7 @@ struct exec_domain; #define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */ #define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */ #define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */ -#define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */ +#define CLONE_DETACHED 0x00400000 /* Not used - CLONE_THREAD implies detached uniquely */ #define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */ #define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */ #define CLONE_STOPPED 0x02000000 /* Start in stopped state */ diff --git a/kernel/fork.c b/kernel/fork.c index 7c4c94b1a968..1164d51d897f 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -746,8 +746,22 @@ struct task_struct *copy_process(unsigned long clone_flags, */ if ((clone_flags & CLONE_THREAD) && !(clone_flags & CLONE_SIGHAND)) return ERR_PTR(-EINVAL); - if ((clone_flags & CLONE_DETACHED) && !(clone_flags & CLONE_THREAD)) + + /* + * CLONE_DETACHED must match CLONE_THREAD: it's a historical + * thing. + */ + if (!(clone_flags & CLONE_DETACHED) != !(clone_flags & CLONE_THREAD)) { + /* Warn about the old no longer supported case so that we see it */ + if (clone_flags & CLONE_THREAD) { + static int count; + if (count < 5) { + count++; + printk(KERN_WARNING "%s trying to use CLONE_THREAD without CLONE_DETACH\n", current->comm); + } + } return ERR_PTR(-EINVAL); + } retval = security_task_create(clone_flags); if (retval) @@ -877,10 +891,7 @@ struct task_struct *copy_process(unsigned long clone_flags, p->parent_exec_id = p->self_exec_id; /* ok, now we should be set up.. */ - if (clone_flags & CLONE_DETACHED) - p->exit_signal = -1; - else - p->exit_signal = clone_flags & CSIGNAL; + p->exit_signal = (clone_flags & CLONE_THREAD) ? -1 : (clone_flags & CSIGNAL); p->pdeath_signal = 0; /* |
