mmap'd file ends with '!', copy doesn't

mmap'd file ends with '!', copy doesn't

Post by Mitch Vincen » Tue, 04 Jul 2000 04:00:00



I'm sorry, I don't have an answer to your problem but wanted to comment (and
ask) about something..

 #define DIE(X) do { fprintf(stderr, "%s: %s '%s' failed: %s\n", progname,
X, \
file, strerror(errno)); exit(EXIT_FAILURE); } while (0)

Why do people do this? Is there some advantage ?

It looks odd but maybe just because I've never used it (nor have I seen it
used that much) :-)

I've seen it a lot lately in some code I've been looking over and have
wondered what the advantage of defining small functions like that is (if
any)..

Thanks!

-Mitch

 
 
 

mmap'd file ends with '!', copy doesn't

Post by Mitch Vincen » Tue, 04 Jul 2000 04:00:00


Quote:> Defining small functions in macro form is a crude form of inlining,
> and is sometimes done to avoid function-call overhead, or to share
> variables, or to allow the macro to do a return on behalf of the
> function proper. The method can be confusing if misused.

Well, that makes sense.. Thanks!!

-Mitch

 
 
 

mmap'd file ends with '!', copy doesn't

Post by Andrew Giert » Tue, 04 Jul 2000 04:00:00


 Mitch> I'm sorry, I don't have an answer to your problem but wanted
 Mitch> to comment (and ask) about something..

 Mitch>  #define DIE(X) do { fprintf(stderr, "%s: %s '%s' failed:
 Mitch> %s\n", progname, X, \ file, strerror(errno));
 Mitch> exit(EXIT_FAILURE); } while (0)

 Mitch> Why do people do this?

do what? the do ... while(0) thing?

If one has a compound-statement that one wishes to use in macro form,
then the do {} while(0) idiom is used to keep the syntax correct when
the statement is followed by a semicolon.

If you do

#define foo(x) { bar(x); baz(x); }

then try and do

    if (x)
        foo(x);
    else
        bar(x);

then you get a syntax error, because the null statement that results
from the }; construct interferes with the syntax of if () ... else ...

In general one should always wrap multi-statement macro bodies in a
do...while(0) unless you have a good reason not to, but also one
should not use such macros in the first place without a very good
reason (use a function instead).

 Mitch> I've seen it a lot lately in some code I've been looking over
 Mitch> and have wondered what the advantage of defining small
 Mitch> functions like that is (if any)..

Defining small functions in macro form is a crude form of inlining,
and is sometimes done to avoid function-call overhead, or to share
variables, or to allow the macro to do a return on behalf of the
function proper. The method can be confusing if misused.

--
Andrew.

comp.unix.programmer FAQ: see <URL: http://www.erlenstar.demon.co.uk/unix/>
                           or <URL: http://www.whitefang.com/unix/>

 
 
 

mmap'd file ends with '!', copy doesn't

Post by Andrew Giert » Tue, 04 Jul 2000 04:00:00


 Tim> System: Linux 2.2.15, glibc 2.0.7, gcc 2.7.2.3, Debian 2.1,
 Tim> i586.

what type of filesystem is the file on?

 Tim> The program listed at the end of this posting demonstrates a
 Tim> problem I just discovered. One file that is mmap'ed mysteriously
 Tim> has a "!" (exclamation mark) at the end, although no such
 Tim> character exists in the file.

this is probably a kernel bug, but there are problems with your code
too.

to cut straight to the point:

 Tim>        mapped = (char *)mmap(0, length, PROT_READ, MAP_PRIVATE, fd, 0);
 Tim>        close(fd);
 Tim>        if (mapped==(char *)-1)
 Tim>                DIE("mapping");
 Tim>        puts(mapped);

There is a bug here, BTW; if the length of the file is an exact
multiple of the system page size, the puts() call will get SIGSEGV.
(If you replace "length" with "length+1" in the mmap call, then it
should get SIGBUS instead, but I think some implementations give
SIGSEGV instead.)

Otherwise you're depending on the behaviour of mmap() when applied to
partial pages; the length of the mapped area is rounded up to whole
pages. Then you're depending on the fact that the partial page
containing the end of file is supposed to be padded with zeros by the
system (at least one Linux filesystem is known to ignore this
requirement). It looks like your OS is not handling this case
correctly.

OS bugs aside, this technique (treating an mmaped file as a
null-terminated string) is bad practice, because it breaks on files
that happen to fit in whole pages, and also because it doesn't cope
well with null characters appearing in the file.

--
Andrew.

comp.unix.programmer FAQ: see <URL: http://www.erlenstar.demon.co.uk/unix/>
                           or <URL: http://www.whitefang.com/unix/>

 
 
 

mmap'd file ends with '!', copy doesn't

Post by Russ Allber » Tue, 04 Jul 2000 04:00:00



> Defining small functions in macro form is a crude form of inlining, and
> is sometimes done to avoid function-call overhead, or to share
> variables, or to allow the macro to do a return on behalf of the
> function proper. The method can be confusing if misused.

It actually has an additional useful purpose under C99, since variadic
macros are now supported and part of the standard.  While one can still do
screen output without using macros by passing va_list arguments to
functions that use vfprintf or the like, there aren't any standard syslog
functions that will take a va_list.  So if you want to do something like
either syslog or print to stderr an error message depending on some flag,
the only good portable way to do it that doesn't involve ugly syntax hacks
like double parentheses is to use a variadic macro.

--

 
 
 

1. ping -g 'gateway-IP' 'host-IP' DOESN'T work!

Hello guys,

I have a machine with two interfaces, each connected to
a gateway. This two gateways are then connected to a common
network and I want to ping another router in that network over
the two interfaces.

Looks like this:
                        Gateway 1
                           ----
               ------------|  |------------
              | Subnet A   ----            |
            ----
Machine    |  |                Subnet C   Router
            ----
              | Subnet B   ----            |
               ------------|  |------------
                           ----
                        Gateway 2

Now if I type following on my machine it doesn't work:

ping -g 'IP in Subnet A of Gateway 1' 'Router-IP-address'

But if I do a ping (Defaultgateway is 'IP in Subnet A of Gateway 1'
(without -g) it works fine:

ping 'Router-IP-address'

Can someone give me a hint? Thanks in advance!

Cheers, Walter

2. Logging into CDE as an ordinary user

3. 'ping' sees route but 'telnet' doesn't??

4. reply email address

5. cvsup doesn't like tags 'ports-all' & 'doc-all'

6. Netscape Problem

7. Bash 'umask' builtin doesn't set 'x' permissions?

8. Help - Linux to Win 95 connexion

9. pppd 2.2.0f 'make kernel' won't copy files

10. 'ppp-on' Works, 'ifup ppp0' Doesn't

11. Xialog --title 'one two' works Xialog `cat file` doesn't

12. Even 'cat file >/dev/lp0' doesn't work

13. dmesg doesn't show 'file system full' msgs