Help a perl dev learn c, my first cli

L

los harcre

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]$
 
S

Spiros Bousbouras

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]$
 

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

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top