Strange syntax

Discussion in 'C Programming' started by seenutn@gmail.com, Dec 5, 2007.

  1. Guest

    Hi All,
    I found a piece of code in linux/kernel/signal.c:

    int
    send_sig(int sig, struct task_struct *p, int priv)
    {
    return send_sig_info(sig, (void*)(long)(priv != 0), p);
    }


    What is the meaning of "(void*)(long)(priv != 0)" ?

    TIA

    Regards,
    Seenu.

    Note: Even though this code is not existing in the current kernel, it
    was avlbl in 2.4.xx.
     
    , Dec 5, 2007
    #1
    1. Advertising

  2. said:

    > Hi All,
    > I found a piece of code in linux/kernel/signal.c:
    >
    > int
    > send_sig(int sig, struct task_struct *p, int priv)
    > {
    > return send_sig_info(sig, (void*)(long)(priv != 0), p);
    > }
    >
    >
    > What is the meaning of "(void*)(long)(priv != 0)" ?


    It means "warning! dodgy code! fix me!"

    (priv != 0) yields a result that is either 0 or 1.
    Casting this to (long) yields a value that is either 0L or 1L.
    Casting to to (void *) yields a value that is very unlikely to be a valid
    pointer to any object or function.

    Stupid stupid stupid.

    > Note: Even though this code is not existing in the current kernel, it
    > was avlbl in 2.4.xx.


    So what you're saying, then, is that someone came to their senses and
    ripped it out. Good!

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
     
    Richard Heathfield, Dec 5, 2007
    #2
    1. Advertising

  3. Gene Guest

    On Dec 5, 12:33 am, wrote:
    > Hi All,
    > I found a piece of code in linux/kernel/signal.c:
    >
    > int
    > send_sig(int sig, struct task_struct *p, int priv)
    > {
    > return send_sig_info(sig, (void*)(long)(priv != 0), p);
    >
    > }
    >
    > What is the meaning of "(void*)(long)(priv != 0)" ?
    >
    > TIA
    >


    The second parameter has the type struct siginfo*. A NULL (0) pointer
    here means a user kill sig. The special reserved pointer (struct
    siginfo*)1 is for kernel sigs. (priv != 0) has value 0 if priv is 0
    and 1 otherwise. The casts coerce this int value to a compatible
    pointer. The effect is that privilege level 0 causes a user sig and
    all others a kernel sig. It's not clear to me why (void*)(long) is
    used instead of (struct siginfo*), but the effect ought to be the
    same.
     
    Gene, Dec 5, 2007
    #3
  4. Chris Dollin Guest

    Richard Heathfield wrote:

    > said:
    >
    >> Hi All,
    >> I found a piece of code in linux/kernel/signal.c:
    >>
    >> int
    >> send_sig(int sig, struct task_struct *p, int priv)
    >> {
    >> return send_sig_info(sig, (void*)(long)(priv != 0), p);
    >> }
    >>
    >>
    >> What is the meaning of "(void*)(long)(priv != 0)" ?

    >
    > It means "warning! dodgy code! fix me!"
    >
    > (priv != 0) yields a result that is either 0 or 1.
    > Casting this to (long) yields a value that is either 0L or 1L.
    > Casting to to (void *) yields a value that is very unlikely to be a valid
    > pointer to any object or function.
    >
    > Stupid stupid stupid.


    To be fair, code found in linux/kernel/anything is unlikely to be written
    in portable standard C and may be permitted to exploit implementation-
    specific details. (The casting looks bizarre, but for all we know, it
    could be avoiding an implementation-specific bug.)

    As you know, Bob, the standard doesn't stop you from relying on
    implementation details; it just doesn't define what happens if you
    do. Sometimes this is a Good Thing.

    --
    Chris "it only /looks/ like C" Dollin

    Hewlett-Packard Limited registered no:
    registered office: Cain Road, Bracknell, Berks RG12 1HN 690597 England
     
    Chris Dollin, Dec 5, 2007
    #4
  5. Chris Dollin said:

    <snip>

    > To be fair, code found in linux/kernel/anything is unlikely to be written
    > in portable standard C and may be permitted to exploit implementation-
    > specific details.


    Understood - but disguising a flag as a pointer is Just Plain Daft. I've
    seen the same trick used a few times in application code. It was daft
    then, and it's daft now. Obfuscation, sheer obfuscation.

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
     
    Richard Heathfield, Dec 5, 2007
    #5
  6. Mark Bluemel Guest

    Richard Heathfield wrote:
    > Chris Dollin said:
    >
    > <snip>
    >
    >> To be fair, code found in linux/kernel/anything is unlikely to be written
    >> in portable standard C and may be permitted to exploit implementation-
    >> specific details.

    >
    > Understood - but disguising a flag as a pointer is Just Plain Daft.


    Hmmm... It's just a special value, and I'm not convinced it's
    significantly different to the special value returned by getc() to
    indicate end of file, or (more to the point) the SIG_* macros in
    <signal.h>.
     
    Mark Bluemel, Dec 5, 2007
    #6
  7. In article <>,
    Richard Heathfield <> wrote:
    >Chris Dollin said:
    >
    ><snip>
    >
    >> To be fair, code found in linux/kernel/anything is unlikely to be written
    >> in portable standard C and may be permitted to exploit implementation-
    >> specific details.

    >
    >Understood - but disguising a flag as a pointer is Just Plain Daft. I've
    >seen the same trick used a few times in application code. It was daft
    >then, and it's daft now. Obfuscation, sheer obfuscation.


    Which means that you should be right at home with it.
     
    Kenny McCormack, Dec 5, 2007
    #7
  8. In article <>,
    Richard Heathfield <> wrote:

    >Understood - but disguising a flag as a pointer is Just Plain Daft. I've
    >seen the same trick used a few times in application code. It was daft
    >then, and it's daft now. Obfuscation, sheer obfuscation.


    It might be wise to use a #define for it, but if we allow NULL pointers,
    why not several varieties of not-a-pointer value?

    -- Richard
    --
    "Consideration shall be given to the need for as many as 32 characters
    in some alphabets" - X3.4, 1963.
     
    Richard Tobin, Dec 5, 2007
    #8
  9. Richard Tobin said:

    > In article <>,
    > Richard Heathfield <> wrote:
    >
    >>Understood - but disguising a flag as a pointer is Just Plain Daft. I've
    >>seen the same trick used a few times in application code. It was daft
    >>then, and it's daft now. Obfuscation, sheer obfuscation.

    >
    > It might be wise to use a #define for it, but if we allow NULL pointers,
    > why not several varieties of not-a-pointer value?


    Why not a method that is guaranteed by ISO to work?

    For example, have a couple of file scope objects, defined in Some
    Appropriate Place and declared in a header:

    void * const G_flag_off = &G_flag_off;
    void * const G_flag_on = &G_flag_on;

    Then you can do, say, something like this:

    return send_sig_info(sig, priv != 0 ? G_flag_on : G_flag_off, p);

    Of course, you could wrap it up a bit prettier than that, and equally
    of-coursely, the callee would need to know about the changed convention.
    But this is hardly difficult, surely?

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
     
    Richard Heathfield, Dec 5, 2007
    #9
  10. In article <>,
    Richard Heathfield <> wrote:

    >Why not a method that is guaranteed by ISO to work?
    >
    >For example, have a couple of file scope objects, defined in Some
    >Appropriate Place and declared in a header:
    >
    >void * const G_flag_off = &G_flag_off;
    >void * const G_flag_on = &G_flag_on;


    This has two minor disadvantages: it requires space for the objects,
    which might be large, and the values are not constants.

    And in the case cited - an operating system kernel - the code has no
    need to be guaranteed-by-ISO-to-work.

    There are also cases where your solution won't work because the
    interface is across an operating system boundary. For example
    the unix function mmap() returns (void *)-1 on error, and it
    couldn't use the address of an object instead unless the kernel
    and user programs shared some address space.

    But in typical cases, your solution is preferable.

    -- Richard
    --
    :wq
     
    Richard Tobin, Dec 5, 2007
    #10
  11. Richard Guest

    Chris Dollin <> writes:

    > Richard Heathfield wrote:
    >
    >> said:
    >>
    >>> Hi All,
    >>> I found a piece of code in linux/kernel/signal.c:
    >>>
    >>> int
    >>> send_sig(int sig, struct task_struct *p, int priv)
    >>> {
    >>> return send_sig_info(sig, (void*)(long)(priv != 0), p);
    >>> }
    >>>
    >>>
    >>> What is the meaning of "(void*)(long)(priv != 0)" ?

    >>
    >> It means "warning! dodgy code! fix me!"
    >>
    >> (priv != 0) yields a result that is either 0 or 1.
    >> Casting this to (long) yields a value that is either 0L or 1L.
    >> Casting to to (void *) yields a value that is very unlikely to be a valid
    >> pointer to any object or function.
    >>
    >> Stupid stupid stupid.

    >
    > To be fair, code found in linux/kernel/anything is unlikely to be written
    > in portable standard C and may be permitted to exploit implementation-
    > specific details. (The casting looks bizarre, but for all we know, it
    > could be avoiding an implementation-specific bug.)
    >
    > As you know, Bob, the standard doesn't stop you from relying on
    > implementation details; it just doesn't define what happens if you
    > do. Sometimes this is a Good Thing.


    Is there anything wrong with comparing that void * with (void *)(1L) in
    the calling hierarchy elsewhere?

    Its almost certainly an optimization to pass back control flags or
    pointers depending on usage.
     
    Richard, Dec 5, 2007
    #11
  12. santosh Guest

    Richard wrote:

    > Chris Dollin <> writes:
    >
    >> Richard Heathfield wrote:
    >>
    >>> said:
    >>>
    >>>> Hi All,
    >>>> I found a piece of code in linux/kernel/signal.c:
    >>>>
    >>>> int
    >>>> send_sig(int sig, struct task_struct *p, int priv)
    >>>> {
    >>>> return send_sig_info(sig, (void*)(long)(priv != 0), p);
    >>>> }
    >>>>
    >>>>
    >>>> What is the meaning of "(void*)(long)(priv != 0)" ?
    >>>
    >>> It means "warning! dodgy code! fix me!"
    >>>
    >>> (priv != 0) yields a result that is either 0 or 1.
    >>> Casting this to (long) yields a value that is either 0L or 1L.
    >>> Casting to to (void *) yields a value that is very unlikely to be a
    >>> valid pointer to any object or function.
    >>>
    >>> Stupid stupid stupid.

    >>
    >> To be fair, code found in linux/kernel/anything is unlikely to be
    >> written in portable standard C and may be permitted to exploit
    >> implementation- specific details. (The casting looks bizarre, but for
    >> all we know, it could be avoiding an implementation-specific bug.)
    >>
    >> As you know, Bob, the standard doesn't stop you from relying on
    >> implementation details; it just doesn't define what happens if you
    >> do. Sometimes this is a Good Thing.

    >
    > Is there anything wrong with comparing that void * with (void *)(1L)
    > in the calling hierarchy elsewhere?
    >
    > Its almost certainly an optimization to pass back control flags or
    > pointers depending on usage.


    In x86 under flat memory model a general purpose register can contain a
    pointer and they are compatible with ordinary integer values, which is
    the reason why the Linux kernel source can do these sort of tricks.
    Presumably code such as these would be rewritten for another
    incompatible architecture, for a port.
     
    santosh, Dec 5, 2007
    #12
  13. Richard Tobin said:

    > In article <>,
    > Richard Heathfield <> wrote:
    >
    >>Why not a method that is guaranteed by ISO to work?
    >>
    >>For example, have a couple of file scope objects, defined in Some
    >>Appropriate Place and declared in a header:
    >>
    >>void * const G_flag_off = &G_flag_off;
    >>void * const G_flag_on = &G_flag_on;

    >
    > This has two minor disadvantages: it requires space for the objects,
    > which might be large, and the values are not constants.


    Yes, I agree, although it is at least *unlikely* that they will be large.
    Typically they'll be 16, 32 or possibly even 64 bits each, but probably
    not larger than that (for now, anyway). As for the values not being
    constants, well, that's also true, but the constness should at least warn
    people off, if nothing else.

    > And in the case cited - an operating system kernel - the code has no
    > need to be guaranteed-by-ISO-to-work.


    Again, true - but I'm very much in the "make it portable unless you have a
    darn good reason not to" camp, and this case doesn't strike me as having a
    darn good reason not to.

    > There are also cases where your solution won't work because the
    > interface is across an operating system boundary. For example
    > the unix function mmap() returns (void *)-1 on error, and it
    > couldn't use the address of an object instead unless the kernel
    > and user programs shared some address space.


    Okay, and I realise that nobody is about to rewrite the entire kernel to my
    spec, but whoever designed mmap needs a good kicking. It should return
    NULL on error.

    > But in typical cases, your solution is preferable.


    Aye.

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
     
    Richard Heathfield, Dec 5, 2007
    #13
  14. Chris Torek Guest

    >Richard Tobin said:
    >> And in the case cited - an operating system kernel - the code has no
    >> need to be guaranteed-by-ISO-to-work.


    In article <>
    Richard Heathfield <> wrote:
    >Again, true - but I'm very much in the "make it portable unless
    >you have a darn good reason not to" camp, and this case doesn't
    >strike me as having a darn good reason not to.


    Indeed, and apparently this was cleaned up at some point anyway,
    so the linux kernel development folks appear to agree with you
    (Richard Heathfield I mean). :)

    >> There are also cases where your solution won't work because the
    >> interface is across an operating system boundary. For example
    >> the unix function mmap() returns (void *)-1 on error ...


    >Okay, and I realise that nobody is about to rewrite the entire
    >kernel to my spec, but whoever designed mmap needs a good kicking.
    >It should return NULL on error.


    Indeed -- although in this case, the "broken" interface is now
    enshrined in a standard (not Standard C, but POSIX). It might help
    to illustrate a bit how the situation came about, and how it could
    have been avoided, though.

    In Ye Aulde Daze, er, Days, "Unix" was "whatever Ken wrote for the
    PDP-11". If it ran on the 11, that was good enough -- and if you
    had more than 32K or so of RAM on your machine, you had a really
    big machine, so conserving memory space, including code space, was
    quite important.

    At that time, which was also before C had <stdio.h> and "FILE"s --
    maybe even before the syntax for "struct" used "{", and back when
    "i += 2" was spelled "i =+ 2" -- there was one kind of "system
    call", and it was not the system() function: it consisted of putting
    a syscall number into one of the eight registers and trapping to
    the Unix kernel, which would then pick out which "system operation"
    you wanted, read your (user) space to obtain any necessary arguments,
    and do whatever system-level privileged operation was requested,
    or fail the request. To "fail" a request, the kernel would set
    the carry flag in the PSW -- remember, the only machine that *exists*
    (as far as we are concerned) is the PDP-11, and its carry flag is
    in the PSW -- and return; to indicate success, the kernel would
    clear the carry flag and return. The return value went into register
    r0; on failure, this value was the error number to store in "errno".

    So, now we take a short trip back in time, to the mid-1970s...

    In C code, there is no way to test "the carry flag" directly. As
    a result, the C-to-kernel interface is written in assembly. Because
    code space is at a premium, and there is no need for portability
    (your code only runs on the PDP-11), one short assembly stub could
    handle pretty much every kernel call. It starts with a system-call
    trap instruction, then a test of the carry flag. If the carry flag
    is set, it stores r0 in the global variable "_errno" ("the" C
    compiler -- there is only one of those, remember, as it the mid
    1970s right now -- prepends an underscore) and sets r0 to -1. Then
    in any case it returns to the caller.

    (I glossed over a few details here. The actual syscall stubs were
    four instructions long: constant into r0; sys; branch on carry;
    return. The branch-on-carry went to the shared "store errno and
    set r0 to -1" code. The principal still applies, though.)

    Now, this is all well and good for the system calls that return an
    "int", because successful return values are normally 0 or small
    positive numbers. No successful int-valued system call returns
    -1. The one call that does not quite fit is the "brk" ("set break")
    system call, which returns a pointer -- but, luckily for us, we
    are only using the PDP-11, and "-1" is the address of the very last
    byte of memory, which is never a valid address for the "break".
    So we need not come up with a special system-call handler for brk();
    we can just use (char *)-1. (We are still in the 1970s and "void"
    does not exist, much less "void *".)

    Now we begin to return back to the present. Time accelerates: the
    PDP-11 Unix kernel acquires new versions, being ported to other
    models of PDP-11 (the various 40s and the split-I&D 11/70), then
    to newer machines like the VAX. C, too, begins to be ported, to
    machines like the Interdata 8/32, Honeywell mainframes, IBM
    mainframes, and even "weird" 9-bit-byte, 36-bit-word machines.
    Many things change, with C compilers growing new features like a
    "long" datatype, multiple flavors of "unsigned" integers, and
    standardized file I/O via <stdio.h> and company. But the "brk"
    system call remains unchanged throughout. This is not a big deal,
    as "normal user code" uses malloc() anyway, which hides the funny
    return value from "normal users". (The malloc() implementations
    on "non-Unixy" machines use various other system-specific mechanisms
    to obtain memory, so portable code *never* calls brk(), which often
    does not even exist.)

    As we zip through the 1980s, UC Berkeley (and others) work with
    DARPA on a grant for an "improved" Unix-like system that will
    function well on the "ARPAnet". They decide that there should be
    a file-to-memory-mapping interface similar to what was in Multics.
    This is called "mmap", and an initial interface is hammered out.
    For some reason, no one on the steering committee notices that
    mmap() probably should return NULL on failure; instead, they let
    the old code-space-constrained model, i.e., the one that had "brk"
    return (char *)-1, persist. And when 4.2BSD is released, even
    though mmap() is not actually supported, the documentation for it
    claims that it returns (char *)-1 on failure.

    Meanwhile, ANSI committee X3J11 works on a standard for C. They
    add "void *" and change malloc()'s return type. The Unix brk()
    call is not part of the proposed standard, nor is mmap(), which is
    just as well since no one actually has an mmap() that works yet.
    Sun Microsystems releases SunOS, and at some point, SunOS implements
    mmap(), sticking with the "wrong" failure-return-value. 4.3-net-n-BSD
    adopts (and adapts) the CMU Mach VM system, and also implements
    mmap(), in a way that differs from SunOS, but also still has the
    "wrong" failure-return-value.

    As we fly through the 1990s, POSIX picks up the effort, and
    standardizes mmap(), with some attempt to resolve the various
    differences between implementations. Since they all return
    (char *)-1 on failure, however, POSIX -- which picks up ANSI C as
    a base item -- has mmap() return (void *)-1 on failure.

    If, at any point along this path, someone had said: "hang on a
    moment, returning -1 is silly, mmap() should return NULL on failure",
    we would have had to do one extra thing: modify the mmap() system
    call stub, to stop sharing its error-path with that for "int"-valued
    system-call stubs. Since code space was no longer at such a great
    premium -- systems with 32K of RAM were no longer the norm; indeed,
    many machines came with as much as 16 entire *mega*bytes of RAM by
    1990 or so -- throwing a dozen bytes at this "special" syscall
    error path would not have been a big deal. (We could even have
    fixed the brk() return value at the same time, although that would
    have entailed changing existing code that tests the return value.
    Since mmap() had not yet been implemented, fixing it then would
    have been cheaper. Fixing it in POSIX would have been a bit more
    expensive, but we already had the problem of resolving incompatible
    mmap() implementations anyway.)

    But it never happened, probably because it never rose above the
    noise level. Instead, a trick for saving space on machines with
    32K of RAM is now firmly embedded in the POSIX standard, used on
    machines that routinely come with a minimum of over 100 thousand
    times as much memory.
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
     
    Chris Torek, Dec 5, 2007
    #14
  15. In article <>,
    Richard Heathfield <> wrote:

    >Okay, and I realise that nobody is about to rewrite the entire kernel to my
    >spec, but whoever designed mmap needs a good kicking. It should return
    >NULL on error.


    I assume it's possible (or was considered to be, when the interface
    was specified) for it to return a region mapped at address zero, which
    has the same representation as a NULL pointer on the systems in
    question.

    -- Richard
    --
    :wq
     
    Richard Tobin, Dec 5, 2007
    #15
  16. santosh Guest

    Chris Torek wrote:

    <snip history of mmap()' interface in relation to the evolution of UNIX>

    That was a very interesting post. Thanks.
     
    santosh, Dec 5, 2007
    #16
  17. In article <> lid writes:
    > Richard Tobin said:

    ....
    > > There are also cases where your solution won't work because the
    > > interface is across an operating system boundary. For example
    > > the unix function mmap() returns (void *)-1 on error, and it
    > > couldn't use the address of an object instead unless the kernel
    > > and user programs shared some address space.

    >
    > Okay, and I realise that nobody is about to rewrite the entire kernel to my
    > spec, but whoever designed mmap needs a good kicking. It should return
    > NULL on error.


    But also NULL is not necessarily the same across OS boundaries. I have used
    at least one system where a kernel NULL was different from a user NULL (the
    pointer contains ring information that is inherently not equal for kernel
    and user space).
    --
    dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
    home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
     
    Dik T. Winter, Dec 5, 2007
    #17
  18. In article <fj6sm0$5p3$>,
    Richard Tobin <> wrote:

    >I assume it's possible (or was considered to be, when the interface
    >was specified) for it to return a region mapped at address zero, which
    >has the same representation as a NULL pointer on the systems in
    >question.


    Though Chris has explained that it's just a historical consequence of
    the way unix system calls returned errors, it is in fact possible on
    the system I'm using to mmap() a file at address zero, and have mmap()
    succeed and return a [pointer identical to the] null pointer.

    The program below, running on an Apple Powerbook under MacOS X 10.4
    with /etc/motd as standard input, prints

    mmap()ed at 0x0
    Welcome to Darwin!

    Given a much larger file, it gets an illegal instruction, presumably because
    it has mapped the file over the executable code.

    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <sys/mman.h>

    int main(void)
    {
    int i;
    void *memory;
    struct stat sb;

    if(fstat(0, &sb) == -1)
    {
    perror("fstat");
    return 1;
    }

    if((memory = mmap(0, sb.st_size, PROT_READ, MAP_FIXED|MAP_PRIVATE, 0, 0)) == (void *)-1)
    {
    perror("mmap");
    return 0;
    }

    printf("mmap()ed at %p\n", memory);

    for(i=0; i<sb.st_size; i++)
    putchar(*(char *)i);

    return 0;
    }

    -- Richard
    --
    :wq
     
    Richard Tobin, Dec 6, 2007
    #18
  19. Chris Dollin Guest

    Chris Torek wrote:

    > Indeed -- although in this case, the "broken" interface is now
    > enshrined in a standard (not Standard C, but POSIX). It might help
    > to illustrate a bit how the situation came about, and how it could
    > have been avoided, though.


    Thanks for, and for taking the trouble to write, that historical view.

    --
    Chris "no, not that one" Dollin

    Hewlett-Packard Limited registered office: Cain Road, Bracknell,
    registered no: 690597 England Berks RG12 1HN
     
    Chris Dollin, Dec 6, 2007
    #19
  20. Tor Rustad Guest

    Richard Heathfield wrote:
    > said:
    >
    >> Hi All,
    >> I found a piece of code in linux/kernel/signal.c:
    >>
    >> int
    >> send_sig(int sig, struct task_struct *p, int priv)
    >> {
    >> return send_sig_info(sig, (void*)(long)(priv != 0), p);
    >> }
    >>
    >>
    >> What is the meaning of "(void*)(long)(priv != 0)" ?

    >
    > It means "warning! dodgy code! fix me!"
    >
    > (priv != 0) yields a result that is either 0 or 1.
    > Casting this to (long) yields a value that is either 0L or 1L.
    > Casting to to (void *) yields a value that is very unlikely to be a valid
    > pointer to any object or function.


    In <sched.h>, one can now find

    #define SEND_SIG_NOINFO ((struct siginfo *) 0)
    #define SEND_SIG_PRIV ((struct siginfo *) 1)

    which I guess give a clue to what the programmer intended.

    > Stupid stupid stupid.


    Agreed, very obfuscated code.


    >> Note: Even though this code is not existing in the current kernel, it
    >> was avlbl in 2.4.xx.

    >
    > So what you're saying, then, is that someone came to their senses and
    > ripped it out. Good!


    Yes, the current send_sig() function, doesn't look anything like OP's
    version.

    --
    Tor < | tr i-za-h a-z>
     
    Tor Rustad, Dec 9, 2007
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Harvey Twyman
    Replies:
    8
    Views:
    569
    August Derleth
    Oct 25, 2003
  2. gabriele renzi
    Replies:
    2
    Views:
    206
    gabriele renzi
    Dec 31, 2005
  3. Ken Bloom
    Replies:
    3
    Views:
    213
  4. Good Night Moon
    Replies:
    9
    Views:
    284
    Rick DeNatale
    Jul 25, 2007
  5. Jacob Grover
    Replies:
    5
    Views:
    318
    Jacob Grover
    Jul 18, 2008
Loading...

Share This Page