Skip to contentSkip to conversation

kill(2), killpg(2) wrongly fail with EPERM

PATCH Linus Torvalds 2 participants 2 messages Jun 16, 2004 1 message not in the archive

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): 40D07A1A.6828.1C33C7E@localhost

#1 lore raw
Quoted 2 lines · Michael Kerrisk

The following patch for 2.6.7 fixes the problem. Please apply.

How about this imho nicer version instead? It results in the main loop being just:

        success = 0;
        retval = -ESRCH;
        for_each_task_pid(pgrp, PIDTYPE_PGID, p, l, pid) {
                int err = group_send_sig_info(sig, info, p);
                success |= !err;
                retval = err;  
        }
        return success ? 0 : retval;

which seems sensible. If _any_ group-send succeeded, we want to return success (ie this is not a EPERM vs everything else issue).

Does this work for you?

Linus

-----
===== kernel/signal.c 1.120 vs edited =====

kernel/signal.c +7 -11
@@ -1071,23 +1071,19 @@
 	struct task_struct *p;
 	struct list_head *l;
 	struct pid *pid;
-	int retval;
-	int found;
+	int retval, success;
 
 	if (pgrp <= 0)
 		return -EINVAL;
 
-	found = 0;
-	retval = 0;
+	success = 0;
+	retval = -ESRCH;
 	for_each_task_pid(pgrp, PIDTYPE_PGID, p, l, pid) {
-		int err;
-
-		found = 1;
-		err = group_send_sig_info(sig, info, p);
-		if (!retval)
-			retval = err;
+		int err = group_send_sig_info(sig, info, p);
+		success |= !err;
+		retval = err;
 	}
-	return found ? retval : -ESRCH;
+	return success ? 0 : retval;
 }
 
 int
#2 lore raw

Gidday Linus,

Quoted 7 lines · Michael Kerrisk
Quoted 2 lines

The following patch for 2.6.7 fixes the problem. Please apply.

How about this imho nicer version instead? It results in the main loop being just:

Quoted 8 lines
        success = 0;
        retval = -ESRCH;
        for_each_task_pid(pgrp, PIDTYPE_PGID, p, l, pid) {
                int err = group_send_sig_info(sig, info, p);
                success |= !err;
                retval = err;  
        }
        return success ? 0 : retval;

Yes, it is nicer.

Quoted 4 lines

which seems sensible. If _any_ group-send succeeded, we want to return success (ie this is not a EPERM vs everything else issue).

Does this work for you?

Well, in terms of SUSv3/POSIX, I don't think there's a problem, since the only errors trhat are specified for kill()/killpg() are EPERM, ESRCH, and EINVAL (invalid signal number). Aside from the fact that I didn't spot the nice way, I wrote my patch as I did since I was worried about the possibility of some other Linux-specific errno values creeping around in the woodwork. But a little further investigation seems to show that there aren't other cases to worry about (EAGAIN in send_sig() doesn't apply for kill()/killpg(). So, your patch is better, since simpler. I've tested it, and it works as I would expect for EPERM.

Thanks,

Michael

Quoted 36 lines

-----
===== kernel/signal.c 1.120 vs edited =====

kernel/signal.c +7 -11
@@ -1071,23 +1071,19 @@
 	struct task_struct *p;
 	struct list_head *l;
 	struct pid *pid;
-	int retval;
-	int found;
+	int retval, success;
 
 	if (pgrp <= 0)
 		return -EINVAL;
 
-	found = 0;
-	retval = 0;
+	success = 0;
+	retval = -ESRCH;
 	for_each_task_pid(pgrp, PIDTYPE_PGID, p, l, pid) {
-		int err;
-
-		found = 1;
-		err = group_send_sig_info(sig, info, p);
-		if (!retval)
-			retval = err;
+		int err = group_send_sig_info(sig, info, p);
+		success |= !err;
+		retval = err;
 	}
-	return found ? retval : -ESRCH;
+	return success ? 0 : retval;
 }
 
 int
Signature · 2 lines
+++ Jetzt WLAN-Router für alle DSL-Einsteiger und Wechsler +++
GMX DSL-Powertarife zudem 3 Monate gratis* http://www.gmx.net/dsl