[RFC patch 0/3] signals: add rt_tgsigqueueinfo syscall

Previous thread: wrong usage of MAX_DMA_ADDRESS in bootmem.h by Nicolas Pitre on Tuesday, September 30, 2008 - 12:35 pm. (10 messages)

Next thread: [RFC patch 1/3] signals: split do_tkill by Thomas Gleixner on Tuesday, September 30, 2008 - 12:48 pm. (1 message)
From: Thomas Gleixner
Date: Tuesday, September 30, 2008 - 12:48 pm

sys_kill has a counterpart sys_tgkill which allows to send signals to
a particular thread. sys_rt_sigqueueinfo is lacking such a counterpart.

Aside of the asymetry it is a show stopper for migrating applications
from other unix-alike RTOSes.

The following patch series implements rt_tgsigqueueinfo and hooks it
up for x86.

Find below the raw documentation.

Thanks,

	tglx
----

NAME
       rt_tgsigqueueinfo - Send signal information to a signal to a thread

SYNOPSIS
       long sys_rt_tgsigqueueinfo (int tgid, int tid, int sig, siginfo_t *uinfo);

DESCRIPTION

       rt_tgsigqueueinfo sends signal sig information uinfo to the
       thread with the thread ID tid in the thread group tgid.  (By
       contrast, rt_sigqueueinfo(2) can only be used to send a signal
       info to a process (i.e., thread group) as a whole, and the
       signal will be delivered to an arbitrary thread within that
       process.)

RETURN VALUE

       rt_tgsigqueueinfo returns 0 on success; otherwise,
       rt_sigqueueinfo returns one of the errors listed in the
       "Errors" section.

ERRORS
       -EFAULT
              An invalid value for uinfo was specified.

       -EINVAL
	      An invalid TID, TGID or signal was specified.

       -EPERM 
              Permission denied.  For the required permissions,
              see rt_sigqueueinfo(2).

       -ESRCH 
       	      No process with the specified thread ID and thread group
              ID exists.

 


--

From: Roland McGrath
Date: Tuesday, September 30, 2008 - 11:39 pm

The core of this looks fine to me.  Presumably this would be expressed in
userland as pthread_sigqueue.

You are missing compat_sys_rt_tgsigqueueinfo for e.g. the
arch/x86/ia32/ia32entry.S table.

The clean way to do that would be a do_rt_tgsigqueueinfo taking
the siginfo_t * (not __user).  That is, just split out the copy_from_user,
so compat_sys_rt_tgsigqueueinfo does copy_siginfo_from_user32 instead.


Thanks,
Roland

--

From: Thomas Gleixner
Date: Wednesday, October 1, 2008 - 12:51 am

Will do.

Thanks,

	tglx
--

From: Michael Kerrisk
Date: Tuesday, October 7, 2008 - 6:49 am

Thomas,


I'm not sure if I've run across a bug or (maybe more likely) have a
bug in my test code.  Could you take a look at the test programs
below.

When I use t_rt_tgsigqueueinfo.c to send a signal to my receiving
program it crashes because the siginfo_t argument to the signal
handler has a bad value (0x33); it's not obvious to me how it should
get to have that value (have I misconstructed something in the
t_rt_tgsigqueuinfo.c program?).

Cheers,

Michael

==========

$ ./multithread_sig_receiver 44 x
Established handler for signal 44
Main: TGID = 6105; TID = 6105
Thread 1: PID = 6105; TID = 6106; arg = x
Thread 1: about to pause
                                                              $
./t_rt_tgsigqueuinfo 6105 6106 44 1
PID = 6105; TID = 6106; caught signal 44:
0x33
Segmentation fault (core dumped)

=========

/*#* t_rt_tgsigqueueinfo.c

   Copyright 2008, Linux Foundation;
   written by Michael Kerrisk <mtk.manpages@gmail.com>
*/
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>

#define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \
                        } while (0)

#if defined(__i386__)
#define SYS_rt_tgsigqueueinfo 333
#endif

static int
rt_tgsigqueueinfo(pid_t tgid, pid_t tid, int sig, siginfo_t *si)
{
    return syscall(SYS_rt_tgsigqueueinfo, tgid, tid, sig, si);
}


int
main(int argc, char *argv[])
{
    pid_t tgid, tid;
    siginfo_t si;
    int sig, val;

    if (argc < 5) {
        fprintf(stderr, "Usage: %s <tgid> <tid> <sig> <val>\n", argv[0]);
        exit(EXIT_SUCCESS);
    }

    printf("My PID is %ld\n", (long) getpid());

    tgid = atoi(argv[1]);
    tid = atoi(argv[2]);
    sig = atoi(argv[3]);
    val = atoi(argv[4]);

    si.si_signo = sig;
    si.si_code = SI_QUEUE;
    si.si_pid = getpid();
    si.si_uid = getuid();
    si.si_value.sival_int = val;

    if ...
From: Roland McGrath
Date: Tuesday, October 7, 2008 - 1:21 pm

You need .sa_flags = SA_SIGINFO.


Thanks,
Roland
--

From: Michael Kerrisk
Date: Tuesday, October 7, 2008 - 7:50 pm

D'oh!  Overlooking the obvious!  Thanks Roland.
--

Previous thread: wrong usage of MAX_DMA_ADDRESS in bootmem.h by Nicolas Pitre on Tuesday, September 30, 2008 - 12:35 pm. (10 messages)

Next thread: [RFC patch 1/3] signals: split do_tkill by Thomas Gleixner on Tuesday, September 30, 2008 - 12:48 pm. (1 message)