Index: kern/kern_sig.c
===================================================================
--- kern/kern_sig.c	(revision 179880)
+++ kern/kern_sig.c	(working copy)
@@ -48,6 +48,7 @@
 #include <sys/acct.h>
 #include <sys/condvar.h>
 #include <sys/event.h>
+#include <sys/eventhandler.h>
 #include <sys/fcntl.h>
 #include <sys/kernel.h>
 #include <sys/ktr.h>
@@ -1951,6 +1952,24 @@
 int
 tdsignal(struct proc *p, struct thread *td, int sig, ksiginfo_t *ksi)
 {
+
+	/* 
+	 * XXX: the eventhandler does not return any value
+	 * so there is no way to determine the code path
+	 * that should be taken after the handler. hence
+	 * I check the sv_name[0] == 'L' because I need
+	 * to return from the function in that case. */
+	if (p->p_sysent->sv_name[0] == 'L') {
+		EVENTHANDLER_INVOKE(process_signal, p, sig);
+	   	return (0);
+	}
+
+	return (tdsignal1(p, td, sig, ksi));
+}
+
+int
+tdsignal1(struct proc *p, struct thread *td, int sig, ksiginfo_t *ksi)
+{
 	sig_t action;
 	sigqueue_t *sigqueue;
 	int prop;
Index: compat/linux/linux_signal.h
===================================================================
--- compat/linux/linux_signal.h	(revision 179880)
+++ compat/linux/linux_signal.h	(working copy)
@@ -34,6 +34,7 @@
 void linux_to_bsd_sigset(l_sigset_t *, sigset_t *);
 void bsd_to_linux_sigset(sigset_t *, l_sigset_t *);
 int linux_do_sigaction(struct thread *, int, l_sigaction_t *, l_sigaction_t *);
+void linux_proc_signal(void *arg __unused, struct proc *p, int);
 
 #define LINUX_SIG_VALID(sig)	((sig) <= LINUX_NSIG && (sig) > 0)
 
Index: compat/linux/linux_signal.c
===================================================================
--- compat/linux/linux_signal.c	(revision 179880)
+++ compat/linux/linux_signal.c	(working copy)
@@ -535,6 +535,33 @@
 	return (kill(td, &tmp));
 }
 
+static int
+linux_kill1(struct thread *td, struct linux_kill_args *args)
+{
+	struct proc *pk;
+	int signum;
+	int error = ESRCH;
+
+	/*
+	 * Allow signal 0 as a means to check for privileges
+	 */
+	if (!LINUX_SIG_VALID(args->signum) && args->signum != 0)
+		return EINVAL;
+
+	if (args->signum > 0 && args->signum <= LINUX_SIGTBLSZ)
+		signum = linux_to_bsd_signal[_SIG_IDX(args->signum)];
+	else
+		signum = args->signum;
+
+	pk = pfind(args->pid);
+	if (pk || (pk = zpfind(args->pid))) {
+		if ((error = p_cansignal(FIRST_THREAD_IN_PROC(td->td_proc), pk, signum)))
+			error = tdsignal1(pk, NULL, signum, NULL);
+		PROC_UNLOCK(pk);
+	}
+
+	return (error);
+}
 int
 linux_tgkill(struct thread *td, struct linux_tgkill_args *args)
 {
@@ -573,7 +600,7 @@
 	if (em->shared->group_pid != args->tgid)
 	   	return ESRCH;
 
-	return linux_kill(td, &ka);
+	return linux_kill1(td, &ka);
 }
 
 int
@@ -584,5 +611,43 @@
 		printf(ARGS(tkill, "%i, %i"), args->tid, args->sig);
 #endif
 
-	return (linux_kill(td, (struct linux_kill_args *) args));
+	return (linux_kill1(td, (struct linux_kill_args *) args));
 }
+
+/*
+ * XXX: locking - what if some thread/process disappears in the middle of this? 
+ * should I hold proctree_lock or something? or is holding the proc lock sufficient
+ * in this case? please review
+ */
+void
+linux_proc_signal(void *arg __unused, struct proc *p, int signal)
+{
+	int *tmp = NULL;
+	struct linux_emuldata *em, *tem;
+	struct proc *pk;
+	int error = 0, i = 0;
+
+	em = em_find(p, EMUL_DONTLOCK);
+
+	EMUL_SHARED_RLOCK(&emul_shared_lock);	
+	LIST_FOREACH(tem, &em->shared->threads, threads) {
+		tmp = realloc(tmp, (i+1) * sizeof(int), M_TEMP, M_WAITOK);
+		tmp[i] = tem->pid;
+		i++;
+	}
+	EMUL_SHARED_RUNLOCK(&emul_shared_lock);	
+
+	for (; i >= 0; i--) {
+		pk = pfind(tmp[i]);
+		if (pk || (pk = zpfind(tmp[i]))) {
+	   		/* try to accumulate the error */
+			if (p_cansignal(FIRST_THREAD_IN_PROC(p), pk, signal))
+   				error |= tdsignal1(pk, NULL, signal, NULL);
+			PROC_UNLOCK(pk);
+		}
+	}
+
+	free(tmp, M_TEMP);
+
+	return;
+}
Index: sys/signalvar.h
===================================================================
--- sys/signalvar.h	(revision 179880)
+++ sys/signalvar.h	(working copy)
@@ -334,6 +334,8 @@
 void	signotify(struct thread *td);
 int	tdsignal(struct proc *p, struct thread *td, int sig,
 	    ksiginfo_t *ksi);
+int	tdsignal1(struct proc *p, struct thread *td, int sig,
+	    ksiginfo_t *ksi);
 void	trapsignal(struct thread *td, ksiginfo_t *);
 int	ptracestop(struct thread *td, int sig);
 ksiginfo_t * ksiginfo_alloc(int);
Index: sys/eventhandler.h
===================================================================
--- sys/eventhandler.h	(revision 179880)
+++ sys/eventhandler.h	(working copy)
@@ -186,6 +186,7 @@
 typedef void (*exitlist_fn)(void *, struct proc *);
 typedef void (*forklist_fn)(void *, struct proc *, struct proc *, int);
 typedef void (*execlist_fn)(void *, struct proc *, struct image_params *);
+typedef void (*signallist_fn)(void *, struct proc *, int);
 typedef void (*proc_ctor_fn)(void *, struct proc *);
 typedef void (*proc_dtor_fn)(void *, struct proc *);
 typedef void (*proc_init_fn)(void *, struct proc *);
@@ -197,6 +198,7 @@
 EVENTHANDLER_DECLARE(process_exit, exitlist_fn);
 EVENTHANDLER_DECLARE(process_fork, forklist_fn);
 EVENTHANDLER_DECLARE(process_exec, execlist_fn);
+EVENTHANDLER_DECLARE(process_signal, signallist_fn);
 
 struct thread;
 typedef void (*thread_ctor_fn)(void *, struct thread *);
