Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Strange syntax

Reply
Thread Tools

Strange syntax

 
 
seenutn@gmail.com
Guest
Posts: n/a
 
      12-05-2007
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.
 
Reply With Quote
 
 
 
 
Richard Heathfield
Guest
Posts: n/a
 
      12-05-2007
http://www.velocityreviews.com/forums/(E-Mail Removed) 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
 
Reply With Quote
 
 
 
 
Gene
Guest
Posts: n/a
 
      12-05-2007
On Dec 5, 12:33 am, (E-Mail Removed) 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.



 
Reply With Quote
 
Chris Dollin
Guest
Posts: n/a
 
      12-05-2007
Richard Heathfield wrote:

> (E-Mail Removed) 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

 
Reply With Quote
 
Richard Heathfield
Guest
Posts: n/a
 
      12-05-2007
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
 
Reply With Quote
 
Mark Bluemel
Guest
Posts: n/a
 
      12-05-2007
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>.



 
Reply With Quote
 
Kenny McCormack
Guest
Posts: n/a
 
      12-05-2007
In article <(E-Mail Removed)>,
Richard Heathfield <(E-Mail Removed)> 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.

 
Reply With Quote
 
Richard Tobin
Guest
Posts: n/a
 
      12-05-2007
In article <(E-Mail Removed)>,
Richard Heathfield <(E-Mail Removed)> 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.
 
Reply With Quote
 
Richard Heathfield
Guest
Posts: n/a
 
      12-05-2007
Richard Tobin said:

> In article <(E-Mail Removed)>,
> Richard Heathfield <(E-Mail Removed)> 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
 
Reply With Quote
 
Richard Tobin
Guest
Posts: n/a
 
      12-05-2007
In article <(E-Mail Removed)>,
Richard Heathfield <(E-Mail Removed)> 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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Syntax Checker that's better than the normal syntax checker Jacob Grover Ruby 5 07-18-2008 05:07 AM
Syntax bug, in 1.8.5? return not (some expr) <-- syntax error vsreturn (not (some expr)) <-- fine Good Night Moon Ruby 9 07-25-2007 04:51 PM
[ANN] SqlStatement 1.0.0 - hide the syntax of SQL behind familiarruby syntax Ken Bloom Ruby 3 10-09-2006 06:46 PM
Syntax highligth with textile: Syntax+RedCloth ? gabriele renzi Ruby 2 12-31-2005 02:44 AM
Question About Strange 'C' Code Syntax ( Well strange to me anyway ) Harvey Twyman C Programming 8 10-25-2003 05:54 AM



Advertisments