scandir()

Matt Landau mlandau at bbn.com
Fri Jul 1 09:43:18 AEST 1988


In comp.unix.wizards, warner at scubed.UUCP (Ken Warner) writes:
>In article <1445 at uokmax.UUCP> sam at uokmax.UUCP (Sam L Falkner) writes:
>>
>>   Has anyone out there ever used the scandir() function?  
>
>Here is a routine that uses scandir().  This is Sun 3-OS 3.4,5
>specific.  The trick to using scandir() is to know how many entries are
>in the directory before you make the call to scandir().  scandir()
>just stuffs the array full of the entries into the the location pointed
>to by the automatic and will blow away the stack if there isn't any
>room.  Sort of a catch 22.  

This is completely wrong -- scandir allocates its own storage.  Both the 
4.3 BSD and SunOS 3.4 manual pages say this quite explicitly.  

Here's a code fragment that uses scandir() and seems to work correctly.
Note the declaration of "struct direct **entries" and the use of &entries
as the second argument to scandir().  There's also a lot of ad hoc use
of pointers as arrays (and vice versa) in this code, but in this case 
it seems the clearest way to communicate what's going on.

clean_dir(dirname)
char   *dirname;
{
    extern char *getenv();
    extern int   needs_cleaning();
    extern int   is_directory();
    static char  old_name[MAXNAMLEN], new_name[MAXNAMLEN];

    register int    e;
    char	   *backup;
    int             n_entries;
    struct direct **entries;


    /* Figure out where to put things */
    if ((backup = getenv("TRASH")) == NULL)
	backup = "/tmp";
    if (!is_directory(backup))
    {
	fprintf(stderr, "clean: trash directory %s not found\n", backup);
	exit(-1);
    }

    /* Scan directory for files that are candidates for cleanup. */
    n_entries = scandir(dirname, &entries, needs_cleaning, (int (*)())NULL);

    /* If no valid entries were found, figure out why not. */
    if (n_entries < 0)
	perror("scandir");
    else
    {
	for (e = 0; e < n_entries; e++)
	{
	    sprintf(old_name, "%s/%s", dirname, entries[e]->d_name);
	    sprintf(new_name, "%s/%s", backup, entries[e]->d_name);
	    rename(old_name, new_name);
	}
    }
}



More information about the Comp.unix.wizards mailing list