problem with timer_create(2) for SIGEV_NONE ??

problem with timer_create(2) for SIGEV_NONE ??

Post by Aniruddha M Marath » Tue, 06 May 2003 15:20:16



George,

 timer_create(2) fails in the case where sigev_notify parameter of
sigevent structure is SIGEV_NONE. I believe this should not happen.

Consider following code which was run on x86:

#include <stdio.h>
#include <syscall.h>
#include <errno.h>
#include <time.h>
#include <signal.h>

#define ANYSIG SIGALRM  /* Any signal value works*/

#ifndef __NR_timer_create
#if defined(__i386__)
#define __NR_timer_create 259
#elif defined(__ppc__)
#define __NR_timer_create 240
#elif defined(__powerpc64__)
#define __NR_timer_create 240
#elif defined(__x86_64__)
#define __NR_timer_create 222
#endif
#endif

_syscall3(int, timer_create, clockid_t, which_clock, struct sigevent *,
        timer_event_spec, timer_t *, created_timer_id);

 int main(int ac, char **av)
{
        timer_t created_timer_id;     /* holds the returned timer_id*/
        struct sigevent evp;
        int retval;

        evp.sigev_value =  (sigval_t) 0;
        evp.sigev_signo = ANYSIG;
        evp.sigev_notify = SIGEV_NONE;

        retval =        timer_create(CLOCK_REALTIME, &evp,
                                                &created_timer_id);

        if (retval < 0) {
                perror("timer_crete");
                printf("timer_create returned %d\n", retval);
        } else {
                printf("timer_create success");
        }
        return 0;

Quote:}  /* End of main */

My analysis of this problem:

Kernel/include/asm-generic/siginfo.h contains following defintions

#define SIGEV_SIGNAL    0       /* notify via signal */
#define SIGEV_NONE      1       /* other notification: meaningless */
#define SIGEV_THREAD    2       /* deliver via thread creation */
#define SIGEV_THREAD_ID 4       /* deliver to thread */

In 2.5.68/kernel/posix-timers.c

Line 86:
MIPS_SEGV = ~(SIGEV_NONE & \
                      SIGEV_SIGNAL & \
                      SIGEV_THREAD &  \
                      SIGEV_THREAD_ID)
= (001 & 000 & 010 & 100) = ~(000) = 111

Line 364: in good_sigevent()
Lets assume that event->sigev_notify = SIGEV_NONE = 001

Line 368:
SIGEV_NONE & SIGEV_THREAD_ID = 001 & 100 = 000. Therefore the if
statement becomes false

Line 373:
SIGEV_NONE & SIGEV_SIGNAL = 001 & 000 = 000. Therefore the if statement
is false

Line 377:
SIGEV_NONE & ~(SIGEV_SIGNAL | SIGEV_THREAD_ID)
= 001 & ~(000 | 100)
= 001 & ~(100)
= 001 & 011
= 001
therefore the if condition is true
therefore the function returns NULL from line 378.

Now in sys_timer_create() at line number 462
Process = NULL

Now at line 489
if (!process) becomes TRUE
and function returns with EINVAL

Is my analysis right? If so can you comment on this behaviour?

-Aniruddha
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

 
 
 

problem with timer_create(2) for SIGEV_NONE ??

Post by george anzinge » Wed, 07 May 2003 01:50:14



> George,

>  timer_create(2) fails in the case where sigev_notify parameter of
> sigevent structure is SIGEV_NONE. I believe this should not happen.

  ~snip~

Quote:

> Line 377:
> SIGEV_NONE & ~(SIGEV_SIGNAL | SIGEV_THREAD_ID)
> = 001 & ~(000 | 100)
> = 001 & ~(100)
> = 001 & 011
> = 001
> therefore the if condition is true
> therefore the function returns NULL from line 378.

> Now in sys_timer_create() at line number 462
> Process = NULL

> Now at line 489
> if (!process) becomes TRUE
> and function returns with EINVAL

> Is my analysis right? If so can you comment on this behaviour?

Looks like a bug :(  I feel a patch coming on...

--

High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

 
 
 

problem with timer_create(2) for SIGEV_NONE ??

Post by george anzinge » Thu, 08 May 2003 17:30:18


Attached is a fix.

Change log:

Fix the sig_notify filtering code for the timer_create system call to
properly check for the signal number being small enought, but only if
SIG_NONE is not specified.

Eliminate useless test of sig_notify.

george


> George,

>  timer_create(2) fails in the case where sigev_notify parameter of
> sigevent structure is SIGEV_NONE. I believe this should not happen.

    ~snip~

Quote:

> Line 377:
> SIGEV_NONE & ~(SIGEV_SIGNAL | SIGEV_THREAD_ID)
> = 001 & ~(000 | 100)
> = 001 & ~(100)
> = 001 & 011
> = 001
> therefore the if condition is true
> therefore the function returns NULL from line 378.

> Now in sys_timer_create() at line number 462
> Process = NULL

> Now at line 489
> if (!process) becomes TRUE
> and function returns with EINVAL

> Is my analysis right? If so can you comment on this behaviour?

Looks like a bug :(  I feel a patch coming on...

--

High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml

[ hrtimers-fix-signone-2.5.69-1.0.patch < 1K ]
--- linux-2.5.69-org/kernel/posix-timers.c      2003-05-05 15:34:09.000000000 -0700

                        rtn->tgid != current->tgid))
                return NULL;

-       if ((event->sigev_notify & SIGEV_SIGNAL & MIPS_SIGEV) &&
+       if ((event->sigev_notify & ~SIGEV_NONE & MIPS_SIGEV) &&
                        ((unsigned) (event->sigev_signo > SIGRTMAX)))
                return NULL;

-       if (event->sigev_notify & ~(SIGEV_SIGNAL | SIGEV_THREAD_ID))
-               return NULL;
-
        return rtn;
 }

 
 
 

1. timer_create refers to struct sigevent; struct sigevent not availabe unders same conditions as timer_create

Him

time.h in included in c source file. The file does not use the
timer_create function but compiling the file throws a warning:

/opt/WS6U2/SUNWspro/bin/cc semaph.c -D_XPG4_2
"/usr/include/time.h", line 99: warning: dubious tag declaration:
struct sigevent

This is because the declaration of timer_create function gets included
which refers to the structure sigevent. But the structure sigevent
present in sys/siginfo.h included in time.h does not get included as
it is enclosed in a
!defined(_XPG4_2).

Basically the condition under which the declaration of timer_create
gets included and sigevent gets included vary.

time.h
--------------------------------------------------------------------------
#if defined(__EXTENSIONS__) || ((__STDC__ - 0 == 0) && \
                !defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE))
|| \
                (_POSIX_C_SOURCE > 2)
extern int timer_create(clockid_t, struct sigevent *, timer_t *);
#endif
--------------------------------------------------------------------------

sys/siginfo.h
--------------------------------------------------------------------------
#if (!defined(_POSIX_C_SOURCE) && !defined(_XPG4_2)) || \
        (_POSIX_C_SOURCE > 2) || defined(__EXTENSIONS__)

struct sigevent {
        int             sigev_notify;   /* notification mode */
        union {
                int     _sigev_signo;   /* signal number */
                void    (*_sigev_notify_function)(union sigval);
        } _sigev_un;
        union sigval    sigev_value;    /* signal value */
        int             _sigev_pad1;
        void            *_sigev_notify_attributes;
        int             _sigev_pad2;
#endif
--------------------------------------------------------------------------

Is there a way to resolve this warning? Should it be resolved since I
am not using timer_create. Should _XOPEN_SOURCE be defined when
_XPG4_2 is defined?. If I define _XOPEN_SOURCE as well this warning
goes off but I am not sure if I am doing the right thing?

Kindly help.

Thanks and Regards,
Mranalini

PS: I am working on Solaris 2.6 and using the Forte 6 Update 2 cc
compiler.

2. Configuring X11R6

3. timer_create

4. carrier errors

5. UNIX to Linux port: timer_create and timer_settime

6. ?tcsh 2.04 on solaris: just prints exit

7. Solaris 7 and timer_create() - Is there a work around or fix

8. C++ and libraries?

9. SIGEV_THREAD doesn't work w/ timer_create

10. using timer_create

11. timer_create System call!

12. how can I create more timer_create() timers??

13. how 2 use timer_create/timer_settimer POSIX functions?