Another doubleunderscore thingy

M

Mark Hobley

In comp.os.linux.development.apps Mark Hobley said:
Right. That is just as messy as __dead. I think I will just delete the tag.

Right I have found another doubleunderscore thingybob. This time __progname:

void
usage(void)
{
extern char *__progname;
(void)fprintf(stderr, "usage: %s [-itw] file ...\n", __progname);
exit(1);
}

This was easier to find in google than the last one. I stumbled across:

http://stackoverflow.com/questions/273691/using-progname-instead-of-argv0

This tells me that __progname is a bsdism and getopt() modifies argv[],
which is not available outside of main(). I guess that I need to somehow
capture argv[0] on entry to main. I guess that the following is a fixup for
this:

extern char *progname;

int
main(int argc, char *argv[])
{
extern char *progname;
progname=argv[0];
blah blah blah
}

void
usage(void)
{
extern char *progname;
(void)fprintf(stderr, "usage: %s [-itw] file ...\n", progname);
exit(1);
}

Does that look right?

Mark.
 
M

Mark Hobley

In comp.os.linux.development.apps Mark Hobley said:
extern char *progname;

Hmmm. It's not external now though. I changed this to:

char *progname;

When I compile, I get an error:

getname.c: In function 'main':
getname.c:96: error: 'optind' undeclared (first use in this function)
getname.c:96: error: (Each undeclared identifier is reported only once
getname.c:96: error: for each function it appears in.)

That error looks right to me: 'optind' is undeclared. I wonder if this is an
error in the original bsd code, or whether optind becomes defined in the
bsd versions of the header files, or the optind becomes defined when the bsd
compiler is used.

The headers are:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libgen.h>

The specification says:

SYNOPSIS

#include <unistd.h>

int getopt(int argc, char * const argv[], const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;

Maybe optind is defined in unistd.h

I added the declaration to the top of the file, and now I get an error:

getname.c:(.text+0x304): undefined reference to `strlcat'

There is a string.h file, so I don't know what is going on there.

Mark.
 
I

Ian Collins

Mark said:
Hmmm. It's not external now though. I changed this to:

char *progname;

When I compile, I get an error:

getname.c: In function 'main':
getname.c:96: error: 'optind' undeclared (first use in this function)

Then you haven't included the header where it is declared.
getname.c:96: error: (Each undeclared identifier is reported only once
getname.c:96: error: for each function it appears in.)

That error looks right to me: 'optind' is undeclared. I wonder if this is an
error in the original bsd code, or whether optind becomes defined in the
bsd versions of the header files, or the optind becomes defined when the bsd
compiler is used.

The headers are:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libgen.h>

Well given the synopsis below said:
The specification says:

SYNOPSIS

#include <unistd.h>

int getopt(int argc, char * const argv[], const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;

Maybe optind is defined in unistd.h

No, it may be declared there, but it will be defined in a library source
file.
I added the declaration to the top of the file, and now I get an error:

getname.c:(.text+0x304): undefined reference to `strlcat'

There is a string.h file, so I don't know what is going on there.

It will probably be declared in <strings.h>, see the man page.
 
S

Seebs

(someone else)
It will probably be declared in <strings.h>, see the man page.

More likely, it was in <string.h> on the system the OP was porting from,
but isn't in it on most other systems, since it's a BSD extension.
(strlcat/strlcpy are what strncat/strncpy probably should have been).

-s
 
M

Mark Hobley

In comp.unix.programmer Seebs said:
More likely, it was in <string.h> on the system the OP was porting from,
but isn't in it on most other systems, since it's a BSD extension.
(strlcat/strlcpy are what strncat/strncpy probably should have been).

Right that is interesting. I am reading the manual pages online, and I have
found something very odd:

The man page for string(3)

http://linux.die.net/man/3/string

(This does not mention strlcat)

From the same website, a man page for strlcat:

http://linux.die.net/man/3/strlcat

Strangely, there is a string.h and a strings.h

I tried included both:

#include <string.h>
#include <strings.h>

That didn't fix it. Maybe it is in unistd.h:

#include <unistd.h>

Nope. That didn't fix it either.

I think you are right. Maybe this is a BSD extension and I am reading the wrong
documents.

Mark.
 
S

santosh

Mark Hobley said:
Right that is interesting. I am reading the manual pages online,
and I have found something very odd:

The man page for string(3)

http://linux.die.net/man/3/string

(This does not mention strlcat)

From the same website, a man page for strlcat:

http://linux.die.net/man/3/strlcat

Strangely, there is a string.h and a strings.h

I tried included both:

#include <string.h>
#include <strings.h>

That didn't fix it. Maybe it is in unistd.h:

#include <unistd.h>

Nope. That didn't fix it either.

I think you are right. Maybe this is a BSD extension and I am
reading the wrong documents.

It does seem to be a BSD specific function, along with strlcpy().

<http://en.wikipedia.org/wiki/Strlcpy>
<http://www.openbsd.org/cgi-
bin/cvsweb/~checkout~/src/lib/libc/string/strlcat.c?rev=1.13>
<http://www.openbsd.org/cgi-bin/man.cgi?query=strlcpy&sektion=3>

Since the source is available, and it's easy to implement your own as
well, with the same semantics, it's not a big portability problem,
AFAICS.
 
M

Mark Hobley

In comp.unix.programmer Ian Collins said:
Then you haven't included the header where it is declared.

Yeah. That is weird, because there were no additional #include statements in
the original bsd code. This must be an implementation difference.

Mark.
 
M

Mark Hobley

In comp.unix.programmer santosh said:
Since the source is available, and it's easy to implement your own as
well, with the same semantics, it's not a big portability problem,
AFAICS.

Yeah. I am just deciding how to do that now. I have stumbled across a library
called libnostd that contains an implementation of this. I could use that
library. I am a bit concerned about the transparency issue of that though,
because it still uses string.h and this means that code using string.h
but using strlcat will work directly on some systems, but not on other
systems where strlcat is not implement (so much for standard C libraries huh!).

I am thinking it might be better to create a new header bsdlib.h containing
the additional functionality, and using that. However, this may then create
another problem in that I need to provide fixups so that code including
bsdlib.h and string.h on a host that includes strlcat in the string.h header
does not create a conflicting definition. Also, what do I do about alternative
implementations of strlcat, which zero the last byte of the buffer? Do I just
drop support for those platforms, or do I create a new function name with
equal functionality to avoid ambiguity? What a mess!

The other thing is, I have some fixups to make to glibc anyway to make it
portable across IA32 compatible machines (Currently it contains embedded
invalid instructions which do not work on traditional Pentiums, the Cyrix 686,
and the AMD K5 and AMD K6, and can cause a crash when the libraries are
transferred between machines containing these processors.) I could just fork
the library, apply the strlcat to the forked library and be done.

Mark.
 
M

Moi

Yeah. I am just deciding how to do that now. I have stumbled across a
library called libnostd that contains an implementation of this. I could
use that library. I am a bit concerned about the transparency issue of
that though, because it still uses string.h and this means that code
using string.h but using strlcat will work directly on some systems, but
not on other systems where strlcat is not implement (so much for
standard C libraries huh!).

The strlxxx() and strpxxx() families of functions are extensions to
the stdlibrary. If you can live with polluting the library, it is
easiest to just add them to libc. Otherwise, you'll have to put them
in a separate library, obviously.

(IMHO: the and str[lp]xxx() are a very useful extention; I never
use the return values (the first argument, which the caller already has)
from strcpy() and memcpy().
I am thinking it might be better to create a new header bsdlib.h
containing the additional functionality, and using that. However, this
may then create another problem in that I need to provide fixups so that
code including bsdlib.h and string.h on a host that includes strlcat in
the string.h header does not create a conflicting definition. Also, what
do I do about alternative implementations of strlcat, which zero the
last byte of the buffer? Do I just drop support for those platforms, or
do I create a new function name with equal functionality to avoid
ambiguity? What a mess!

The clean way is to provide your own versions, and possibly
#define strlcpy mystrlcpy
, etc.
The other thing is, I have some fixups to make to glibc anyway to make
it portable across IA32 compatible machines (Currently it contains
embedded invalid instructions which do not work on traditional Pentiums,
the Cyrix 686, and the AMD K5 and AMD K6, and can cause a crash when the
libraries are transferred between machines containing these processors.)

Well, this is what open source is all about. Why distribute binaries
if you can compile on (for) the target platform ?

Why would you distribute glibc anyway ? You expect target platforms without
a usable glibc ? Why not have the users install it themselves ?
(or let the package manager handle it)

HTH,
AvK
 
M

Mark Hobley

In comp.unix.programmer Moi said:
Well, this is what open source is all about. Why distribute binaries
if you can compile on (for) the target platform ?

The core system will be installable from a cdrom, and the rest of the binary
files will be shared via the network. All machines are IA32 compatible, so as
long as I can build to this the binaries will be portable.

Mark.
Why would you distribute glibc anyway ? You expect target platforms without
a usable glibc ?

I was hoping that my source packages would be usable within other
distributions irrespective of which C library was being used. This enables me
to bootstrap. I need to have the code working on an existing system, before I
can deploy a revised system.

This would also mean that third parties can use my packages without having to
install my version of the C library.

Mark.
 
M

Martin Neitzel

Mark said:
Strangely, there is a string.h and a strings.h

Historically (in the eighties), BSD systems had the declarations
for string functions such as strcpy() in <strings.h> whereas SystemV
systems had them in <string.h>. There were some differences in
return types (int vs. char*) and naming (index() vs. strchr()).

These differences were always a portability nuisance. Later,
ANSI C (1989) came and also defined the standard library.
This made <string.h> the norm. In today's systems, you'll
often find a <strings.h> which just #includes <string.h>.

If you're porting some code to a new system: first look which
routine is requiring a prototype declaration; then look up its man
page which will indicate the required header file. Use that one.
If you get type warnings when you compile the code, fix the code.

Martin Neitzel
 
E

Ersek, Laszlo

Historically (in the eighties), BSD systems had the declarations
for string functions such as strcpy() in <strings.h> whereas SystemV
systems had them in <string.h>. There were some differences in
return types (int vs. char*) and naming (index() vs. strchr()).

These differences were always a portability nuisance. Later,
ANSI C (1989) came and also defined the standard library.
This made <string.h> the norm. In today's systems, you'll
often find a <strings.h> which just #includes <string.h>.

SUSv3 (POSIX:2004) and SUSv4 (POSIX:2008) have a <strings.h> which is
not an empty shell:

http://www.opengroup.org/onlinepubs/000095399/basedefs/strings.h.html
http://www.opengroup.org/onlinepubs/9699919799/basedefs/strings.h.html

Cheers,
lacos
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top