print_usage() & QNX6

I noticed that QNX6 provides the “use” and “usemsg” utilities, which is great.
However the function print_usage() which I used extensively in QNX4 seems to
not have made it across quite yet. Any chance of me getting a pre-release copy
of it or enough info on how you do the use messages to code it myself? (perhaps
a snippet from “use.c”?) I hate having to maintain multiple sets of usage
descriptions. Thanks in advance.

-Warren

→ Ping!

“Warren Peece” <warren@nospam.com> wrote in message
news:8vbrji$re7$1@inn.qnx.com
| I noticed that QNX6 provides the “use” and “usemsg” utilities, which is
great.
| However the function print_usage() which I used extensively in QNX4 seems to
| not have made it across quite yet. Any chance of me getting a pre-release
copy
| of it or enough info on how you do the use messages to code it myself?
(perhaps
| a snippet from “use.c”?) I hate having to maintain multiple sets of usage
| descriptions. Thanks in advance.
|
| -Warren

I doubt that print_usage will ever appear in out libc. However, here
is a hacked up version…

#ifdef __USAGE
%C - test print_usage
#endif /* __USAGE */

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/debug.h>
#include <sys/elf.h>
#include <sys/procfs.h>
#include <unistd.h>

void print_usage(void)
{
Elf32_Ehdr ehdr;
Elf32_Shdr *shdr = NULL;
char *usage = NULL, *shstrtab = NULL;
int fd, i;

/* get a file descriptor to our executable */
if ( -1 == (fd = _cmdfd()) )
return;

/* read Elf Header */
if ( sizeof(ehdr) != read(fd, &ehdr, sizeof(ehdr)) ) {
return;
}

/* Check ELF magic */
if ( ehdr.e_ident[0] != 0x7f
|| ehdr.e_ident[1] != ‘E’
|| ehdr.e_ident[2] != ‘L’
|| ehdr.e_ident[3] != ‘F’ ) {
return;
}

/* read section table */
if ( (shdr = malloc( ehdr.e_shentsize * ehdr.e_shnum )) == NULL ) {
goto end;
}
if ( -1 == lseek( fd, ehdr.e_shoff, SEEK_SET ) )
goto end;
if ( ehdr.e_shentsize * ehdr.e_shnum != read( fd, shdr, ehdr.e_shentsize * ehdr.e_shnum ) )
goto end;

/* read string index */
if ( (shstrtab = malloc( shdr[ehdr.e_shstrndx].sh_size )) == NULL ) {
goto end;
}
if ( -1 == lseek( fd, shdr[ehdr.e_shstrndx].sh_offset, SEEK_SET ) )
goto end;
if ( shdr[ehdr.e_shstrndx].sh_size != read( fd, shstrtab, shdr[ehdr.e_shstrndx].sh_size ) ) {
goto end;
}

/* look through each section until we find the “QNX_usage” section */
for ( i = 1; i < ehdr.e_shnum; i++ ) {
if ( !strcmp( &shstrtab[shdr_.sh_name],“QNX_usage”))
break;
}
if ( i == ehdr.e_shnum )
goto end;

if ( (usage = malloc( shdr.sh_size )) == NULL )
goto end;

if ( -1 == lseek( fd, shdr.sh_offset, SEEK_SET ) )
goto end;

if ( shdr.sh_size != read( fd, usage, shdr.sh_size ) )
goto end;

write( STDERR_FILENO, usage, shdr.sh_size );

end:
if ( shdr )
free( shdr );
if ( shstrtab )
free( shstrtab );
if ( usage )
free( usage );
}

int main(void)
{
print_usage();

return 0;
}

Warren Peece <warren@nospam.com> wrote:_

→ Ping!

“Warren Peece” <> warren@nospam.com> > wrote in message
news:8vbrji$re7$> 1@inn.qnx.com> …
| I noticed that QNX6 provides the “use” and “usemsg” utilities, which is
great.
| However the function print_usage() which I used extensively in QNX4 seems to
| not have made it across quite yet. Any chance of me getting a pre-release
copy
| of it or enough info on how you do the use messages to code it myself?
(perhaps
| a snippet from “use.c”?) I hate having to maintain multiple sets of usage
| descriptions. Thanks in advance.
|
| -Warren


cburgess@qnx.com

Wow. Thank you, kind sir. Never look gift code in the mouth (it might bite
your nose off :slight_smile:

-Warren


<cburgess@qnx.com> wrote in message news:90gri7$p2i$1@nntp.qnx.com
| I doubt that print_usage will ever appear in out libc. However, here
| is a hacked up version…
|
| #ifdef __USAGE
| %C - test print_usage
| #endif /* _USAGE */
|
| #include <errno.h>
| #include <fcntl.h>
| #include <stdio.h>
| #include <stdlib.h>
| #include <sys/debug.h>
| #include <sys/elf.h>
| #include <sys/procfs.h>
| #include <unistd.h>
|
| void print_usage(void)
| {
| Elf32_Ehdr ehdr;
| Elf32_Shdr *shdr = NULL;
| char *usage = NULL, shstrtab = NULL;
| int fd, i;
|
| /
get a file descriptor to our executable /
| if ( -1 == (fd = _cmdfd()) )
| return;
|
| /
read Elf Header /
| if ( sizeof(ehdr) != read(fd, &ehdr, sizeof(ehdr)) ) {
| return;
| }
|
| /
Check ELF magic /
| if ( ehdr.e_ident[0] != 0x7f
| || ehdr.e_ident[1] != ‘E’
| || ehdr.e_ident[2] != ‘L’
| || ehdr.e_ident[3] != ‘F’ ) {
| return;
| }
|
| /
read section table /
| if ( (shdr = malloc( ehdr.e_shentsize * ehdr.e_shnum )) == NULL ) {
| goto end;
| }
| if ( -1 == lseek( fd, ehdr.e_shoff, SEEK_SET ) )
| goto end;
| if ( ehdr.e_shentsize * ehdr.e_shnum != read( fd, shdr, ehdr.e_shentsize *
ehdr.e_shnum ) )
| goto end;
|
| /
read string index /
| if ( (shstrtab = malloc( shdr[ehdr.e_shstrndx].sh_size )) == NULL ) {
| goto end;
| }
| if ( -1 == lseek( fd, shdr[ehdr.e_shstrndx].sh_offset, SEEK_SET ) )
| goto end;
| if ( shdr[ehdr.e_shstrndx].sh_size != read( fd, shstrtab,
shdr[ehdr.e_shstrndx].sh_size ) ) {
| goto end;
| }
|
| /
look through each section until we find the “QNX_usage” section */
| for ( i = 1; i < ehdr.e_shnum; i++ ) {
| if ( !strcmp( &shstrtab[shdr
.sh_name],“QNX_usage”))
| break;
| }
| if ( i == ehdr.e_shnum )
| goto end;
|
| if ( (usage = malloc( shdr.sh_size )) == NULL )
| goto end;
|
| if ( -1 == lseek( fd, shdr.sh_offset, SEEK_SET ) )
| goto end;
|
| if ( shdr.sh_size != read( fd, usage, shdr.sh_size ) )
| goto end;
|
| write( STDERR_FILENO, usage, shdr.sh_size );
|
| end:
| if ( shdr )
| free( shdr );
| if ( shstrtab )
| free( shstrtab );
| if ( usage )
| free( usage );
| }
|
| int main(void)
| {
| print_usage();
|
| return 0;
| }
|
| Warren Peece <warren@nospam.com> wrote:
| > → Ping!
|
| > “Warren Peece” <warren@nospam.com> wrote in message
| > news:8vbrji$re7$1@inn.qnx.com
| > | I noticed that QNX6 provides the “use” and “usemsg” utilities, which is
| > great.
| > | However the function print_usage() which I used extensively in QNX4 seems
to
| > | not have made it across quite yet. Any chance of me getting a
pre-release
| > copy
| > | of it or enough info on how you do the use messages to code it myself?
| > (perhaps
| > | a snippet from “use.c”?) I hate having to maintain multiple sets of
usage
| > | descriptions. Thanks in advance.
| > |
| > | -Warren
|
|
|

Warren Peece <warren@nospam.com> wrote:

Wow. Thank you, kind sir. Never look gift code in the mouth (it might bite
your nose off > :slight_smile:

While colin’s is nice in that it digs right into the elf information,
the QNX4 version has a big disclaimer that it uses exec to invoke
use. Using the same information you could do:

#ifdef __USAGE
Print the usage of the file here!
#endif

#include <stdio.h>
#include <process.h>

int print_usage(char **argv) {
static char *usestr = “use”;
char **nargv;
int count;

for(count=0; argv[count]; count++) { ; }
count += 2;

nargv = (char **)alloca(count * sizeof(*nargv));

nargv[0] = usestr;
for(count=0; argv[count]; count++) {
nargv[count+1] = argv[count];
}
nargv[count+1] = NULL;

return execvp(nargv[0], nargv);
}

int main(int argc, char **argv) {

printf(“Now printing usage information …\n”);
print_usage(argv);

return 0;
}

Now you have two options …

Thomas


cburgess@qnx.com> > wrote in message news:90gri7$p2i$> 1@nntp.qnx.com> …
| I doubt that print_usage will ever appear in out libc. However, here
| is a hacked up version…
|
| #ifdef __USAGE
| %C - test print_usage
| #endif /* __USAGE */
|
| #include <errno.h
| #include <fcntl.h
| #include <stdio.h
| #include <stdlib.h
| #include <sys/debug.h
| #include <sys/elf.h
| #include <sys/procfs.h
| #include <unistd.h
|
| void print_usage(void)
| {
| Elf32_Ehdr ehdr;
| Elf32_Shdr *shdr = NULL;
| char *usage = NULL, shstrtab = NULL;
| int fd, i;
|
| /
get a file descriptor to our executable /
| if ( -1 == (fd = _cmdfd()) )
| return;
|
| /
read Elf Header /
| if ( sizeof(ehdr) != read(fd, &ehdr, sizeof(ehdr)) ) {
| return;
| }
|
| /
Check ELF magic /
| if ( ehdr.e_ident[0] != 0x7f
| || ehdr.e_ident[1] != ‘E’
| || ehdr.e_ident[2] != ‘L’
| || ehdr.e_ident[3] != ‘F’ ) {
| return;
| }
|
| /
read section table /
| if ( (shdr = malloc( ehdr.e_shentsize * ehdr.e_shnum )) == NULL ) {
| goto end;
| }
| if ( -1 == lseek( fd, ehdr.e_shoff, SEEK_SET ) )
| goto end;
| if ( ehdr.e_shentsize * ehdr.e_shnum != read( fd, shdr, ehdr.e_shentsize *
ehdr.e_shnum ) )
| goto end;
|
| /
read string index /
| if ( (shstrtab = malloc( shdr[ehdr.e_shstrndx].sh_size )) == NULL ) {
| goto end;
| }
| if ( -1 == lseek( fd, shdr[ehdr.e_shstrndx].sh_offset, SEEK_SET ) )
| goto end;
| if ( shdr[ehdr.e_shstrndx].sh_size != read( fd, shstrtab,
shdr[ehdr.e_shstrndx].sh_size ) ) {
| goto end;
| }
|
| /
look through each section until we find the “QNX_usage” section */
| for ( i = 1; i < ehdr.e_shnum; i++ ) {
| if ( !strcmp( &shstrtab[shdr> _.sh_name],“QNX_usage”))
| break;
| }
| if ( i == ehdr.e_shnum )
| goto end;
|
| if ( (usage = malloc( shdr> .sh_size )) == NULL )
| goto end;
|
| if ( -1 == lseek( fd, shdr> .sh_offset, SEEK_SET ) )
| goto end;
|
| if ( shdr> .sh_size != read( fd, usage, shdr> .sh_size ) )
| goto end;
|
| write( STDERR_FILENO, usage, shdr> .sh_size );
|
| end:
| if ( shdr )
| free( shdr );
| if ( shstrtab )
| free( shstrtab );
| if ( usage )
| free( usage );
| }
|
| int main(void)
| {
| print_usage();
|
| return 0;
| }
|
| Warren Peece <> warren@nospam.com> > wrote:
| > → Ping!
|
| > “Warren Peece” <> warren@nospam.com> > wrote in message
| > news:8vbrji$re7$> 1@inn.qnx.com> …
| > | I noticed that QNX6 provides the “use” and “usemsg” utilities, which is
| > great.
| > | However the function print_usage() which I used extensively in QNX4 seems
to
| > | not have made it across quite yet. Any chance of me getting a
pre-release
| > copy
| > | of it or enough info on how you do the use messages to code it myself?
| > (perhaps
| > | a snippet from “use.c”?) I hate having to maintain multiple sets of
usage
| > | descriptions. Thanks in advance.
| > |
| > | -Warren
|
|
|

Indeed I do now have two options, thank you for the insight. My initial
reaction would be that the self-contained option is slightly better in that it
doesn’t require an external application (namely “use”) to work. However I must
say I never ran into a situation on QNX4 where it failed to work for me, so
it’s probably 6’s. I guess I’ll start by cleaning up the elf one, and I can
always switch back and forth as I see necessary.

Thanks again for the info.

-Warren


“Thomas Fletcher” <thomasf@qnx.com> wrote in message
news:90h5gc$1d8$1@nntp.qnx.com
| Warren Peece <warren@nospam.com> wrote:
| > Wow. Thank you, kind sir. Never look gift code in the mouth (it might
bite
| > your nose off :slight_smile:
|
| While colin’s is nice in that it digs right into the elf information,
| the QNX4 version has a big disclaimer that it uses exec to invoke
| use. Using the same information you could do:
|
| #ifdef __USAGE
| Print the usage of the file here!
| #endif
|
| #include <stdio.h>
| #include <process.h>
|
| int print_usage(char **argv) {
| static char *usestr = “use”;
| char **nargv;
| int count;
|
| for(count=0; argv[count]; count++) { ; }
| count += 2;
|
| nargv = (char **)alloca(count * sizeof(*nargv));
|
| nargv[0] = usestr;
| for(count=0; argv[count]; count++) {
| nargv[count+1] = argv[count];
| }
| nargv[count+1] = NULL;
|
| return execvp(nargv[0], nargv);
| }
|
| int main(int argc, char *argv) {
|
| printf(“Now printing usage information …\n”);
| print_usage(argv);
|
| return 0;
| }
|
| Now you have two options …
|
| Thomas
|
|
| > <cburgess@qnx.com> wrote in message news:90gri7$p2i$1@nntp.qnx.com
| > | I doubt that print_usage will ever appear in out libc. However, here
| > | is a hacked up version…
| > |
| > | #ifdef __USAGE
| > | %C - test print_usage
| > | #endif /
USAGE */
| > |
| > | #include <errno.h>
| > | #include <fcntl.h>
| > | #include <stdio.h>
| > | #include <stdlib.h>
| > | #include <sys/debug.h>
| > | #include <sys/elf.h>
| > | #include <sys/procfs.h>
| > | #include <unistd.h>
| > |
| > | void print_usage(void)
| > | {
| > | Elf32_Ehdr ehdr;
| > | Elf32_Shdr *shdr = NULL;
| > | char *usage = NULL, shstrtab = NULL;
| > | int fd, i;
| > |
| > | /
get a file descriptor to our executable /
| > | if ( -1 == (fd = _cmdfd()) )
| > | return;
| > |
| > | /
read Elf Header /
| > | if ( sizeof(ehdr) != read(fd, &ehdr, sizeof(ehdr)) ) {
| > | return;
| > | }
| > |
| > | /
Check ELF magic /
| > | if ( ehdr.e_ident[0] != 0x7f
| > | || ehdr.e_ident[1] != ‘E’
| > | || ehdr.e_ident[2] != ‘L’
| > | || ehdr.e_ident[3] != ‘F’ ) {
| > | return;
| > | }
| > |
| > | /
read section table /
| > | if ( (shdr = malloc( ehdr.e_shentsize * ehdr.e_shnum )) == NULL ) {
| > | goto end;
| > | }
| > | if ( -1 == lseek( fd, ehdr.e_shoff, SEEK_SET ) )
| > | goto end;
| > | if ( ehdr.e_shentsize * ehdr.e_shnum != read( fd, shdr, ehdr.e_shentsize
*
| > ehdr.e_shnum ) )
| > | goto end;
| > |
| > | /
read string index /
| > | if ( (shstrtab = malloc( shdr[ehdr.e_shstrndx].sh_size )) == NULL ) {
| > | goto end;
| > | }
| > | if ( -1 == lseek( fd, shdr[ehdr.e_shstrndx].sh_offset, SEEK_SET ) )
| > | goto end;
| > | if ( shdr[ehdr.e_shstrndx].sh_size != read( fd, shstrtab,
| > shdr[ehdr.e_shstrndx].sh_size ) ) {
| > | goto end;
| > | }
| > |
| > | /
look through each section until we find the “QNX_usage” section */
| > | for ( i = 1; i < ehdr.e_shnum; i++ ) {
| > | if ( !strcmp( &shstrtab[shdr
.sh_name],“QNX_usage”))
| > | break;
| > | }
| > | if ( i == ehdr.e_shnum )
| > | goto end;
| > |
| > | if ( (usage = malloc( shdr.sh_size )) == NULL )
| > | goto end;
| > |
| > | if ( -1 == lseek( fd, shdr.sh_offset, SEEK_SET ) )
| > | goto end;
| > |
| > | if ( shdr.sh_size != read( fd, usage, shdr.sh_size ) )
| > | goto end;
| > |
| > | write( STDERR_FILENO, usage, shdr.sh_size );
| > |
| > | end:
| > | if ( shdr )
| > | free( shdr );
| > | if ( shstrtab )
| > | free( shstrtab );
| > | if ( usage )
| > | free( usage );
| > | }
| > |
| > | int main(void)
| > | {
| > | print_usage();
| > |
| > | return 0;
| > | }
| > |
| > | Warren Peece <warren@nospam.com> wrote:
| > | > → Ping!
| > |
| > | > “Warren Peece” <warren@nospam.com> wrote in message
| > | > news:8vbrji$re7$1@inn.qnx.com
| > | > | I noticed that QNX6 provides the “use” and “usemsg” utilities, which
is
| > | > great.
| > | > | However the function print_usage() which I used extensively in QNX4
seems
| > to
| > | > | not have made it across quite yet. Any chance of me getting a
| > pre-release
| > | > copy
| > | > | of it or enough info on how you do the use messages to code it
myself?
| > | > (perhaps
| > | > | a snippet from “use.c”?) I hate having to maintain multiple sets of
| > usage
| > | > | descriptions. Thanks in advance.
| > | > |
| > | > | -Warren
| > |
| > |
| > |
| > |
| > | –
| > | cburgess@qnx.com
|
|