Help a perl dev learn c, my first cli

Discussion in 'C Programming' started by los harcre, May 11, 2009.

  1. los harcre

    los harcre Guest

    My first c program.
    Platform is linux 2.6.* ext3, 32bit arch.
    My bkg: perl.

    This is a cli program. It's given directory paths, and prints to screen
    how many regular files are there.

    My problem is that it seems to count properly for the cwd, but then.. It
    says 0 for everywhere else. Maybe the entry_counter var is global .. ???






    /*
    * print to screen how many entries are in a directory
    */

    #include <stdio.h>
    #include <sys/types.h>
    #include <dirent.h>
    #include <errno.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/stat.h>

    int lscount ( char dir_path[], int typeflag )
    {
    DIR *dp;
    int entry_count;
    struct dirent *ep;

    /*
    switch ( typeflag )
    {
    case 0:
    break;

    case 1:
    break;

    case 2:
    break;

    default:
    printf("no such type %d\n", typeflag );
    exit(1);
    }
    */
    entry_count = 0;

    dp = opendir( dir_path );


    if ( dp == NULL )
    {
    (void) closedir(dp);

    perror("didnt work");

    exit(EXIT_FAILURE);
    }


    while ((ep = readdir(dp)) != NULL)
    {

    struct stat es;
    stat( ep->d_name , &es ); /* man stat.h */

    switch ( typeflag )
    {
    case 0:
    /* all files */
    entry_count++;
    break;

    case 1:
    /* files */
    if ( S_ISREG( es.st_mode ) )
    entry_count++;

    break;

    case 2:
    /* subdirs only */
    if ( S_ISDIR( es.st_mode ) )
    entry_count++;

    break;
    }



    }

    (void) closedir(dp);

    return entry_count;
    }


    int main ( int argc, char *argv[] )
    {
    int i;
    for ( i = 1; i < argc ; i++ )
    {
    printf("%6d %s\n", lscount(argv, 1) , argv );
    }
    exit(0);
    }



    My results:

    [leo@nicotine lsutils]$ gcc -Wall lscount.c
    [leo@nicotine lsutils]$ ./a.out ./
    7 ./
    [leo@nicotine lsutils]$ ./a.out ~/
    0 /home/leo/
    [leo@nicotine lsutils]$ touch ./test
    [leo@nicotine lsutils]$ touch ~/testanother
    [leo@nicotine lsutils]$ ./a.out ./ ~/
    8 ./
    0 /home/leo/
    [leo@nicotine lsutils]$
     
    los harcre, May 11, 2009
    #1
    1. Advertising

  2. On 11 May, 15:21, los harcre <> wrote:
    > My first c program.
    > Platform is linux 2.6.* ext3, 32bit arch.
    > My bkg: perl.
    >
    > This is a cli program. It's given directory paths, and prints to screen
    > how many regular files are there.
    >
    > My problem is that it seems to count properly for the cwd, but then.. It
    > says 0 for everywhere else. Maybe the entry_counter var is global .. ???
    >
    > /*
    > * print to screen how many entries are in a directory
    > */
    >
    > #include <stdio.h>
    > #include <sys/types.h>
    > #include <dirent.h>
    > #include <errno.h>
    > #include <stdlib.h>
    > #include <string.h>
    > #include <sys/stat.h>


    We only deal with standard C here. So I will give you a push in
    the right direction but I'm also crossposting and setting
    follow-ups for comp.unix.programmer

    > int lscount ( char dir_path[], int typeflag )
    > {
    > DIR *dp;
    > int entry_count;
    > struct dirent *ep;
    >
    > /*
    > switch ( typeflag )
    > {
    > case 0:
    > break;
    >
    > case 1:
    > break;
    >
    > case 2:
    > break;
    >
    > default:
    > printf("no such type %d\n", typeflag );
    > exit(1);
    > }
    > */
    > entry_count = 0;
    >
    > dp = opendir( dir_path );
    >
    > if ( dp == NULL )
    > {
    > (void) closedir(dp);


    You should not call closedir() with a NULL pointer.

    > perror("didnt work");


    The call to closedir() may modify the value of errno. So you
    need to store errno right after the call to opendir() fails and
    restore the value of errno right before you call perror().

    > exit(EXIT_FAILURE);
    > }
    >
    > while ((ep = readdir(dp)) != NULL)
    > {
    >
    > struct stat es;
    > stat( ep->d_name , &es ); /* man stat.h */


    Here is the crux of your problem. If you were checking the
    return value of stat() as you should then it would give you a
    clue as to what goes wrong. Say you have a file named "myfile"
    under your current directory. You call
    stat("myfile",&es) and it works ok. But say you have "myfile2"
    in the parent directory. Doing stat("myfile2" , &es) isn't
    going to work because it searches for the file under the current
    directory. You need to do instead stat("../myfile2" , &es)
    So basically for any directory other than the current one you
    need to concatenate the name of the directory with ep->d_name
    and use that string as the first argument to stat()

    > switch ( typeflag )
    > {
    > case 0:
    > /* all files */
    > entry_count++;
    > break;
    >
    > case 1:
    > /* files */
    > if ( S_ISREG( es.st_mode ) )
    > entry_count++;
    >
    > break;
    >
    > case 2:
    > /* subdirs only */
    > if ( S_ISDIR( es.st_mode ) )
    > entry_count++;
    >
    > break;
    > }
    >
    > }
    >
    > (void) closedir(dp);
    >
    > return entry_count;
    >
    > }
    >
    > int main ( int argc, char *argv[] )
    > {
    > int i;
    > for ( i = 1; i < argc ; i++ )
    > {
    > printf("%6d %s\n", lscount(argv, 1) , argv );
    > }
    > exit(0);
    >
    > }
    >
    > My results:
    >
    > [leo@nicotine lsutils]$ gcc -Wall lscount.c
    > [leo@nicotine lsutils]$ ./a.out ./
    > 7 ./
    > [leo@nicotine lsutils]$ ./a.out ~/
    > 0 /home/leo/
    > [leo@nicotine lsutils]$ touch ./test
    > [leo@nicotine lsutils]$ touch ~/testanother
    > [leo@nicotine lsutils]$ ./a.out ./ ~/
    > 8 ./
    > 0 /home/leo/
    > [leo@nicotine lsutils]$


    --
    The big print giveth, and the fine print taketh away.
    Cardinal Cook
     
    Spiros Bousbouras, May 11, 2009
    #2
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Porky Pig Jr
    Replies:
    3
    Views:
    1,114
    Fuzzyman
    May 12, 2004
  2. Ron Peterson

    /dev/urandom vs. /dev/random

    Ron Peterson, Jan 7, 2005, in forum: C Programming
    Replies:
    21
    Views:
    1,612
    Keith Thompson
    Jan 13, 2005
  3. CoreyWhite
    Replies:
    1
    Views:
    692
    JohnQ
    Mar 31, 2007
  4. Alexander
    Replies:
    20
    Views:
    1,086
    BGB / cr88192
    Sep 11, 2010
  5. AC
    Replies:
    0
    Views:
    192
Loading...

Share This Page