[comp.unix.questions] how to use scandir

wyuen@CAE.WISC.EDU (08/28/90)

Could someone give examples of how to use scandir?
Eg., how to list the filenames of a given directory?

It seems to me that

struct direct *(*namelist[]);       is a reasonable declaration,

n = scandir(".", namelist, NULL, NULL)        is a reasonable call,

for (i=0; i<n; i++)
     printf("filename = %s\n", (*namelist[i])->d_name);   is a reasonable use,

however, I'm getting Segmentation Faults all the time.
Someone kindly points out what I did wrong?

Thanks. Please send to newsgroup as my email is unstable.

katsu@sra.co.jp (WATANABE Katsuhiro) (08/28/90)

# Sorry for my poor English.

In article <9008271747.AA02292@ws-38.cae.wisc.edu> wyuen@CAE.WISC.EDU writes:

> Could someone give examples of how to use scandir?

> struct direct *(*namelist[]);       is a reasonable declaration,
> n = scandir(".", namelist, NULL, NULL)        is a reasonable call,

  It's a `illegal pointer probrem'. The 2nd argument of scandir() must
be the address in which you want scandir() to set the address of name list.
  Indeed TYPE of each identifiers are surely reasonable in your program.
But `namelist' is uninitialized and it holds nonsense address and its VALUE
is not reasonable.

  Anyway, my example:

#include <sys/types.h>
#include <sys/dir.h>

main(argc, argv)
int argc;
char **argv;
{
        int i, n;
        struct direct **namelist;

        if ((n = scandir(".", &namelist, NULL, NULL)) < 0) {
                perror(argv[0]);
                exit(1);
        }
        for (i = 0; i < n; i++)
                printf("filename = %s\n", namelist[i]->d_name);
        
/* example of free-ing */
        for (i = 0; i < n; i++) {
                free(namelist[i]->d_name);
        }
        free(namelist);

        exit(0);
}

----____----____
WATANABE Katsuhiro      Software Research Associates, Inc. Japan.
Not execute, but evaluate.

gwyn@smoke.BRL.MIL (Doug Gwyn) (08/29/90)

In article <KATSU.90Aug28105457@sran14.sra.co.jp> katsu@sra.co.jp (WATANABE Katsuhiro) writes:
>> n = scandir(".", namelist, NULL, NULL)        is a reasonable call,

No, it is not "reasonable".  The only time you should pass uncast NULL
arguments to a function is when there is a prototype for the function
in scope, which is not possible in pre-ANSI C.  In this particular case
the last two arguments should be either (int(*)())NULL or (int(*)())0.

jmaynard@thesis1.hsch.utexas.edu (Jay Maynard) (08/29/90)

In article <KATSU.90Aug28105457@sran14.sra.co.jp> katsu@sra.co.jp (WATANABE
Katsuhiro) thinks all the world's a VAX:
>>> n = scandir(".", namelist, NULL, NULL)        is a reasonable call,

In article <13677@smoke.BRL.MIL> gwyn@smoke.BRL.MIL (Doug Gwyn) corrects him:
>No, it is not "reasonable".  The only time you should pass uncast NULL
>arguments to a function is when there is a prototype for the function
>in scope, which is not possible in pre-ANSI C.  In this particular case
>the last two arguments should be either (int(*)())NULL or (int(*)())0.

This bears repeating. Sloppy programmers get away with cruft like this on
benevolent architectures like the VAX, where everything is 32 bits and may
be freely interchanged; when this is tried on other machines, though, it blows
up because suddenly the wrong amount of stuff is added to or removed from the
stack.

If you're trying to write portable programs, please don't assume anything is
interchangeable with anything else!

-- 
Jay Maynard, EMT-P, K5ZC, PP-ASEL | Never ascribe to malice that which can
jmaynard@thesis1.hsch.utexas.edu  | adequately be explained by stupidity.
"It's a hardware bug!" "It's a    +---------------------------------------
software bug!" "It's two...two...two bugs in one!" - _Engineer's Rap_

george@hls0.hls.oz (George Turczynski) (08/31/90)

In article <9008271747.AA02292@ws-38.cae.wisc.edu>, wyuen@CAE.WISC.EDU writes:
> 
> Could someone give examples of how to use scandir?
> Eg., how to list the filenames of a given directory?
> 
> It seems to me that
> 
> struct direct *(*namelist[]);       is a reasonable declaration,

try:	struct direct **namelist;

> n = scandir(".", namelist, NULL, NULL)        is a reasonable call,

try:	n= scandir(".",&namelist,NULL,NULL);

> for (i=0; i<n; i++)
>      printf("filename = %s\n", (*namelist[i])->d_name);   is a reasonable use,

try:	for( i= 0; i < n; i++ )
			printf("filename= %s\n",namelist[i]->d_name);

> however, I'm getting Segmentation Faults all the time.
> Someone kindly points out what I did wrong?
> 
> Thanks. Please send to newsgroup as my email is unstable.

Perhaps you couldn't make sense of the manual entry ?  I assume you
_did_ read it, no ?  You give it the address of a struct direct ** and
it malloc()s the space for the pointer table and the structures, then
"fills in" the struct direct ** ("namelist" here) with a pointer to
the pointer table.  You then use the pointer table to get to the
struct directs.

Here is the example you asked for:

/*-----------------Cut here--------------------*/
#include<stdio.h>
#include<sys/types.h>
#include<sys/dir.h>

struct direct **namelist;

main()
{
        int i, n;

        n= scandir(".",&namelist,NULL,NULL);

        for( i= 0; i < n; i++ )
                printf("filename= %s\n",namelist[i]->d_name);
}

/*-----------------Cut here--------------------*/

Hope this clears up any problems,

and have a nice day...

-- 
| George P. J. Turczynski.          |---------------------------------------------------- 
| Computer Systems Engineer.        | ACSnet: george@highland.oz | I can't speak for the |
| Highland Logic Pty. Ltd.          | Phone: +61 48 683490       | company, I can barely |
| Suite 1, 348-354 Argyle St        | Fax:   +61 48 683474       | speak for myself...   |
| Moss Vale. NSW. Australia. 2577   |----------------------------------------------------