Solved

Questions on codes

Posted on 2011-03-14
72
401 Views
Last Modified: 2012-05-11
There're several questions i would like to ask for the following codes:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <limits.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>


unsigned process_directory( char *theDir )
{
    	DIR *dir = NULL;
    	struct dirent entry;
    	struct dirent *entryPtr = NULL;
    	int retval = 0;
    	unsigned count = 0;
	char pathName[PATH_MAX + 1];

    	/* Open the given directory, if you can. */  
    	dir = opendir( theDir );
    	if( dir == NULL ) 
	{
        	printf( "Error opening %s: %s", theDir, strerror( errno ) );
        	return 0;
    	}
	
	retval = readdir_r( dir, &entry, &entryPtr );
    	while( entryPtr != NULL ) 
	{
        	struct stat entryInfo;
        
        	if( ( strncmp( entry.d_name, ".", PATH_MAX ) == 0 ) || ( strncmp( entry.d_name, "..", PATH_MAX ) == 0 ) ) 
		{
            		/* Short-circuit the . and .. entries. */
            		retval = readdir_r( dir, &entry, &entryPtr );
            		continue;
        	}
		(void)strncpy( pathName, theDir, PATH_MAX );
        	(void)strncat( pathName, "/", PATH_MAX );
        	(void)strncat( pathName, entry.d_name, PATH_MAX );
        
        	if( lstat( pathName, &entryInfo ) == 0 ) 
		{
            		count++;
                        // to check whether it is a directory
            		if( S_ISDIR( entryInfo.st_mode ) ) 
			{            
				/* directory */
                		printf( "processing %s/\n", pathName );
                		count += process_directory( pathName );
            		} 
                        // to check whether it is a file
			else if( S_ISREG( entryInfo.st_mode ) ) 
			{ 
				/* regular file */
                		printf( "\t%s has %lld bytes\n", pathName, (long long)entryInfo.st_size );
            		} 
                        // to check whether it is a symbolic link
			else if( S_ISLNK( entryInfo.st_mode ) ) 
			{ 
				/* symbolic link */
                		char targetName[PATH_MAX + 1];
                		if( readlink( pathName, targetName, PATH_MAX ) != -1 ) 
				{
                    			printf( "\t%s -> %s\n", pathName, targetName );
                		} 
				else 
				{
                    			printf( "\t%s -> (invalid symbolic link!)\n", pathName );
                		}
            		}
        	} 
		else 
		{
            		printf( "Error statting %s: %s\n", pathName, strerror( errno ) );
        	}
 		retval = readdir_r( dir, &entry, &entryPtr );
    	}
    
    	/* Close the directory and return the number of entries. */
    	(void)closedir( dir );
    	return count;
}

/* readdir_demo main()
 * 
 * Run through the specified directories, and pass them
 * to process_directory().
 */
int main( int argc, char **argv )
{
    int idx = 0;
    unsigned count = 0;
    
    for( idx = 1; idx < argc; idx++ ) {
        count += process_directory( argv[idx] );
    }
    
    return EXIT_SUCCESS;
}

Open in new window


1) I got some errors while compiling this code, not too sure what are these

as3.c: In function `process_directory':
as3.c:30: error: too many arguments to function `readdir_r'
as3.c:30: warning: assignment makes integer from pointer without a cast
as3.c:38: error: too many arguments to function `readdir_r'
as3.c:38: warning: assignment makes integer from pointer without a cast
as3.c:79: error: too many arguments to function `readdir_r'
as3.c:79: warning: assignment makes integer from pointer without a cast

2) Is that possible for me to use chdir in this prog? Let's say if i remove the following line and replace with the chdir func (like chdir (entry.d_name) and chdir (".."))?
             retval = readdir_r( dir, &entry, &entryPtr );

3) what does this return >> EXIT_SUCCESS at the end of the main func what is the difference than the usual?

4) Is there any difference of using void and without void in some of these lines, what do they meant to be here?
                (void)strncpy( pathName, theDir, PATH_MAX );
              (void)strncat( pathName, "/", PATH_MAX );
              (void)strncat( pathName, entry.d_name, PATH_MAX );

5) Is there any possibility for me getting a NULL when reading a directory?

Any help will be greatly appreciated:)
0
Comment
Question by:crazy4s
  • 37
  • 32
  • 3
72 Comments
 
LVL 8

Accepted Solution

by:
ssnkumar earned 300 total points
Comment Utility
1. I compiled your code on CentOS and didn't get any warnings or errors.
So, it should compile without problems, if you are using Linux and gcc.
Anyway, check the manpages on your computer for readdir_r and see if it has different arguments.
Or check the header file /usr/include/dirent.h and search for readdir_h. Check if it has same arguments that you are using.

2. I think, that should be possible.

3. In the header file stdlib.h, EXIT_STATUS is defined as:
#define   EXIT_SUCCESS    0
So, when your program ends, you can check the exit status.
You can have different exit values depending on the place where you are exiting.
For error 1, you can exit with -1.
For error 2, you can exit with -2.
For success, you can exit with 0.
Now, after your code terminates, how do you know, whether your code completed successfully or with error.
In Linux/Unix, you can do "echo $?" and this will give the exit value of your program (provided you execute "echo $?" immediately after you execute your program).

4. From programming point of view, there is no difference.
But, there are some compilers, which might give lint errors/warning if you are not using the return values (if the function is returning some value). To overcome this, you can prefix the function with (void).
But, if a function is returning value, it is better to use that value.

5. Yes. If the directory is not there or in case of errors you might get NULL.
But, before reading the values in dirent structure, you have to check the return value of readdir().
If it is successful, then only you should attempt to check the dirent structure.
Even then, it is better to check for NULL and then dereference it.
0
 
LVL 53

Assisted Solution

by:Infinity08
Infinity08 earned 200 total points
Comment Utility
>> 1) I got some errors while compiling this code, not too sure what are these

Check the dirent.h header file on your platform to see if it includes a declaration for the readdir_r function, and whether it matches the standard signature :

        int readdir_r(DIR *restrict dirp, struct dirent *restrict entry, struct dirent **restrict result);

Your platform might not have this function.


>> 2) Is that possible for me to use chdir in this prog? Let's say if i remove the following line and replace with the chdir func (like chdir (entry.d_name) and chdir (".."))?
>>              retval = readdir_r( dir, &entry, &entryPtr );

chdir doesn't do the same thing as readdir, so I'm not sure what you mean.


>> 3) what does this return >> EXIT_SUCCESS at the end of the main func what is the difference than the usual?

EXIT_SUCCESS is an integer value that indicates success. Commonly that will be the value 0, but it depends on the platform.


>> 4) Is there any difference of using void and without void in some of these lines, what do they meant to be here?
>>                 (void)strncpy( pathName, theDir, PATH_MAX );

It doesn't relly matter whether you put it or not.
It just documents the intent of the programmer that he doesn't use the return value.


>> 5) Is there any possibility for me getting a NULL when reading a directory?

Sure. There always is the potential that a function call fails, so you always have to check for error cases. Check the manual pages for the function to know more about what could go wrong.
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
Heh, sorry for repeating you, ssnkumar :)
0
 

Author Comment

by:crazy4s
Comment Utility
i checked the man page for readdir_r, all the headers seems to have included in my prog but i'm still not sure why there're still error for readdir_r

given in the man page: (it looks a bit different from the readdir_r in my prog?)

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

     struct dirent *readdir(DIR *dirp);

     struct dirent *readdir_r(DIR *dirp, struct dirent *entry);

cpfoo@csa02 as3$ gcc as3.c <- is it correct to compile like this?
as3.c: In function `process_directory':
as3.c:30: error: too many arguments to function `readdir_r'
as3.c:30: warning: assignment makes integer from pointer without a cast
as3.c:38: error: too many arguments to function `readdir_r'
as3.c:38: warning: assignment makes integer from pointer without a cast
as3.c:79: error: too many arguments to function `readdir_r'
as3.c:79: warning: assignment makes integer from pointer without a cast

2.

the chdir func that i've to use in this prog is used to go back to the parent directory?
can somebody lead me to use this func in this prog? i'm not sure how should i use this?

3.
so can i say return EXIT_SUCCESS; = return 0;?

5.
if let's say you've no permission to access the directory will you get a NULL for that too or error?
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>>      struct dirent *readdir_r(DIR *dirp, struct dirent *entry);

That one doesn't have three arguments like the standard one :

        int readdir_r(DIR *restrict dirp, struct dirent *restrict entry, struct dirent **restrict result);

So, you'll need to change every call to readdir_r to have only two arguments.


>> the chdir func that i've to use in this prog is used to go back to the parent directory?

chdir changes the working directory. Check the man page for more information ;)


>> so can i say return EXIT_SUCCESS; = return 0;?

That depends on the platform you're working on. On most platforms, yes.


>> if let's say you've no permission to access the directory will you get a NULL for that too or error?

opendir will generate an error if there is a permission issue with the directory.
You can check the man pages for all these functions to see what they do in all error cases.
0
 

Author Comment

by:crazy4s
Comment Utility
when i changed to retval = readdir_r( dir, &entry);
i have these errors:

as3.c: In function `process_directory':
as3.c:29: warning: assignment makes integer from pointer without a cast
as3.c:37: warning: assignment makes integer from pointer without a cast
as3.c:78: warning: assignment makes integer from pointer without a cast

somehow i know i've to do smt like that but i'm not sure correct or not?
chdir (entry.d_name) <-- this will be right before the while loop
and
chdir ("..") <-- this will be somewhere near the end of while loop

one more question does this above code have a recursive func in it?
just like the tree that've posted by one of the expert in the related question.
IF yes, is it the while loop that causes the recursive?
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
your readdir_r returns a struct dirent *, not an int. You'll have to adapt your code accordingly.

You wrote your code with another implementation of the readdir_r function in mind, so you have to change it to suit the actual implementation on your platform.
0
 

Author Comment

by:crazy4s
Comment Utility
so do you meant that i should change int retval to struct dirent *retval?
0
 

Author Comment

by:crazy4s
Comment Utility
i changed it to struct dirent *retval = 0;
compiled with no error but the output is something like that
CS224 is a directory where it has subdirectories and files; as3 is the subdir that has files in it.
the path is smt like /home/ugrad/cpfoo/CS224/as3

cpfoo@csa02 as3$ gcc as3.c -o MY
cpfoo@csa02 as3$ MY CS224
Error opening CS224: No such file or directorycpfoo@csa02 as3$
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
You cannot just change code without understanding it ... That rarely leads to good results :)

You first have to know what you want the readdir_r function to do for you, and then you figure out how you make it do that.

What do you want the readdir_r function to do for you ?
0
 

Author Comment

by:crazy4s
Comment Utility
to get the information of the particular directory (theDir)?
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
Ok, now have a look at the man page for the function. How does it explain to do that ? It takes two arguments, and returns one. What are the arguments it takes ? And what does it return ?
0
 

Author Comment

by:crazy4s
Comment Utility
The readdir_r() function will not return  directory  entries
     containing  empty  names.  It is unspecified whether entries
     are returned for . (dot) or .. (dot-dot).

     If a file is removed from or added to  the  directory  after
     the  most recent call to opendir() or rewinddir(), whether a
     subsequent call to readdir_r() returns  an  entry  for  that
     file is unspecified.

     The  readdir_r()  function  can  buffer  several   directory
     entries  per  actual read operation. It marks for update the
     st_atime field of the directory each time the  directory  is
     actually read.

     The standard-conforming version (see  standards(5))  of  the
     readdir_r()  function  performs all of the actions described
     above and sets the pointer pointed to by result. If a direc-
     tory  entry is returned, the pointer will be set to the same
     value as the entry argument; otherwise, it will  be  set  to
     NULL.

RETURN VALUES
     Upon  successful  completion,  readdir()  and  the   default
     readdir_r()  return  a  pointer  to an object of type struct
0
 

Author Comment

by:crazy4s
Comment Utility
but now my prob seems to appear in opendir rather than readdir_r because i got this after compiling
cpfoo@csa02 as3$ gcc as3.c -o MY
cpfoo@csa02 as3$ MY CS224
Error opening CS224: No such file or directorycpfoo@csa02 as3$
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
That's part of the man page, yes. So, what do you have to pass it as argument, and what do you do with the returned pointer ?
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> Error opening CS224: No such file or directory

Then maybe the error message isn't lying ;)
0
 

Author Comment

by:crazy4s
Comment Utility
the address of entry (which is a struct dirent)?
0
 

Author Comment

by:crazy4s
Comment Utility
hmm what you meant by this? but i do have the CS224 directory as i tried using pwd i got this
/home/ugrad/cpfoo/CS224/as3

>> Error opening CS224: No such file or directory

Then maybe the error message isn't lying ;)
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> the address of entry (which is a struct dirent)?

Where you want the next entry to be stored, yes.

When you call the function, check the returned pointer to see if there was an error, and if not, you can use the entry.


>> hmm what you meant by this? but i do have the CS224 directory as i tried using pwd i got this

which means that the directory CS224 is NOT in the current directory, but two levels up.
0
 

Author Comment

by:crazy4s
Comment Utility
and can someone lead me in doing the chdir? I really got no idea on how and where should i put in my prog but so far i know that i should've put something like this
chdir (entry.d_name) <-- this will be right before the while loop
                                         to change it to the subdir and check whether there're files or directories in it
chdir ("..") <-- this will be somewhere near the end of while loop
                       back to the parent directory and go to another subdir if there're a few of subdir in the dir?
i'm not sure what i understand is it correct, but pls do correct me if i'm wrong?
0
 

Author Comment

by:crazy4s
Comment Utility
hmm in a struct form?
but even if i use  as3 it still give me the same error...as3 is my current working directory

cpfoo@csa02 as3$ gcc as3.c -o MY
cpfoo@csa02 as3$ MY as3
Error opening as3: No such file or directorycpfoo@csa02 as3$
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> as3 is my current working directory

as3 is not IN the current working directory though.
0
 

Author Comment

by:crazy4s
Comment Utility
when i tried pwd it gives me
/home/ugrad/cpfoo/CS224/as3
hmm a current working directory should be in a path or just the name?
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
The current working directory is the directory you are currently in.

Everything shown by the command ls are the files and directories that are in the current working directory.

A directory can be specified with an absolute path (starting with a /, so from the root), or a relative path (starting from the current directory). If you specify "CS224", then it will look for that in the current working directory.
0
 

Author Comment

by:crazy4s
Comment Utility
yeah i understand that but why it appears error opening and stated there no such file or directory?
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> yeah i understand that but why it appears error opening and stated there no such file or directory?

Because there is no such directory in the current working directory.
0
 

Author Comment

by:crazy4s
Comment Utility
/home/ugrad/cpfoo/CS224/as3
so u meant that i've to compile this file let's say in cpfoo (currently in as3), and so they'll have the directory that i specified (CS224)?
hmm is that possible to look up into that directory even i'm in the sub directory(current working directory)?
0
 

Author Comment

by:crazy4s
Comment Utility
is that possible to use chdir so that i can change my current working directory?
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> so u meant that i've to compile this file let's say in cpfoo (currently in as3), and so they'll have the directory that i specified (CS224)?

If you would run the executable from the /home/ugrad/cpfoo directory, then it would have access to CS224, yes.
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> is that possible to use chdir so that i can change my current working directory?

Yes. But that's probably not what you want to do.

Instead, make use of absolute or relative paths to specify the directory you need.

        http://www.linux-tutorial.info/modules.php?name=MContent&pageid=17
0
 

Author Comment

by:crazy4s
Comment Utility
but in this assignment i was asked to use the chdir func to locate the directory and also back to the parent directory?
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> but in this assignment i was asked to use the chdir func to locate the directory and also back to the parent directory?

If it's your assignment, then I guess you'll have to do it ;)
0
 

Author Comment

by:crazy4s
Comment Utility
so how or where should i start from? i totally got no idea on this, hope you can lead me? thank you.
but so far i know that i should've put something like this
chdir (entry.d_name) <-- this will be right before the while loop
                                         to change it to the subdir and check whether there're files or directories in it
chdir ("..") <-- this will be somewhere near the end of while loop
                       back to the parent directory and go to another subdir if there're a few of subdir in the dir?
i'm not sure what i understand is it correct, but pls do correct me if i'm wrong?
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
That sounds good, yes.
0
 

Author Comment

by:crazy4s
Comment Utility
this is the latest code but i still got the same output:(
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <limits.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>

unsigned process_directory( char *theDir )
{
    	DIR *dir = NULL;
    	struct dirent entry;
    	struct dirent *entryPtr = NULL;
    	struct dirent *retval = 0;
    	unsigned count = 0;
	char pathName[PATH_MAX + 1];

    	/* Open the given directory, if you can. */  
    	dir = opendir( theDir );
    	if( dir == NULL ) 
	{
        	printf( "Error opening %s: %s", theDir, strerror( errno ) );
        	return 0;
    	}
	
	retval = readdir_r( dir, &entry);
	// Change to new directory
	chdir(entry.d_name);
    	while( entryPtr != NULL ) 
	{
        	struct stat entryInfo;
        
        	if( ( strncmp( entry.d_name, ".", PATH_MAX ) == 0 ) || ( strncmp( entry.d_name, "..", PATH_MAX ) == 0 ) ) 
		{
            		/* Short-circuit the . and .. entries. */
            		retval = readdir_r( dir, &entry);
            		continue;
        	}
		(void)strncpy( pathName, theDir, PATH_MAX );
        	(void)strncat( pathName, "/", PATH_MAX );
        	(void)strncat( pathName, entry.d_name, PATH_MAX );
        
        	if( lstat( pathName, &entryInfo ) == 0 ) 
		{
            		/* stat() succeeded, let's party */
            		count++;
            
            		if( S_ISDIR( entryInfo.st_mode ) ) 
			{            
				/* directory */
                		printf( "processing %s/\n", pathName );
                		count += process_directory( pathName );
            		} 
			else if( S_ISREG( entryInfo.st_mode ) ) 
			{ 
				/* regular file */
                		printf( "\t%s has %lld bytes\n", pathName, (long long)entryInfo.st_size );
            		} 
			else if( S_ISLNK( entryInfo.st_mode ) ) 
			{ 
				/* symbolic link */
                		char targetName[PATH_MAX + 1];
                		if( readlink( pathName, targetName, PATH_MAX ) != -1 ) 
				{
                    			printf( "\t%s -> %s\n", pathName, targetName );
                		} 
				else 
				{
                    			printf( "\t%s -> (invalid symbolic link!)\n", pathName );
                		}
            		}
        	} 
		else 
		{
            		printf( "Error statting %s: %s\n", pathName, strerror( errno ) );
        	}
 		retval = readdir_r( dir, &entry);
		/* Switch up to parent directory
		   Now that all directories at this level have been processed*/
		chdir(".."); 
    	}
    
    	/* Close the directory and return the number of entries. */
    	(void)closedir( dir );
    	return count;
}

/* readdir_demo main()
 * 
 * Run through the specified directories, and pass them
 * to process_directory().
 */
int main( int argc, char **argv )
{
    int idx = 0;
    unsigned count = 0;
    
    for( idx = 1; idx < argc; idx++ ) {
        count += process_directory( argv[idx] );
    }
    
    return EXIT_SUCCESS;
}

Open in new window



cpfoo@csa02 as3$ gcc as3.c -o MY
cpfoo@csa02 as3$ MY CS224
Error opening CS224: No such file or directorycpfoo@csa02 as3$
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
Well, you can't expect the result to be different if you don't change anything ;)

You're still running the code from a directory where there is NO CS224 directory.
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 

Author Comment

by:crazy4s
Comment Utility
hmm but i thought we can use the chdir to change the working directory, do we still need to shift?
anyway i've shifted my as3.c to cpfoo but when i compile i got these error:

cpfoo@csa02 ~$ gcc as3.c -o MY
as3.c: In function `process_directory':
as3.c:77: error: missing terminating " character
as3.c:78: error: syntax error before '!' token
as3.c:78: error: stray '\' in program
as3.c:78: error: missing terminating " character

it seems the error appears at the error statting line?
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> hmm but i thought we can use the chdir to change the working directory, do we still need to shift?

You can use chdir to change the working directory, yes. But you still need to change it to a valid working directory, and you need to change it at the right time.


>> anyway i've shifted my as3.c to cpfoo but when i compile i got these error:

The error messages are pretty clear. Just go to the indicated line for the first error, and look for the missing ".
0
 

Author Comment

by:crazy4s
Comment Utility
so how should i check this error? using gdb? but because i've to input a dir at the command line i got no idea how to check? can you lead me?
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
This is a compilation error, so you cannot use gdb.

Just look at the source code, at the indicated line, and look for the missing "
0
 

Author Comment

by:crazy4s
Comment Utility
but i don't see any error in these few lines?
else
            {
                        printf( "Error statting %s: %s\n", pathName, strerror( errno ) );
              }
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
Then maybe you're not compiling the file you think you are.
0
 

Author Comment

by:crazy4s
Comment Utility
ah yeah you're right i'm still using the old ones=P
but i got nothing output

cpfoo@csa02 ~$ gcc as3.c -o MY
cpfoo@csa02 ~$ MY CS224
cpfoo@csa02 ~$
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> but i got nothing output

Have a closer look at what your code is doing.

Hint : you never actually get into the while loop.
0
 

Author Comment

by:crazy4s
Comment Utility
hoh yeah because of the changes that i've made in readdir, the entryPtr seems to be no more functioning is it?
can i change it into something like this while (retval != NULL) as in referring to struct dirent *retval?
0
 

Author Comment

by:crazy4s
Comment Utility
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <limits.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>

unsigned process_directory( char *theDir )
{
    	DIR *dir = NULL;
    	struct dirent entry;
    	struct dirent *retval = 0;
    	unsigned count = 0;
	char pathName[PATH_MAX + 1];

    	/* Open the given directory, if you can. */  
    	dir = opendir( theDir );
    	if( dir == NULL ) 
	{
        	printf( "Error opening %s: %s", theDir, strerror( errno ) );
        	return 0;
    	}
	
	retval = readdir_r( dir, &entry);
	// Change to new directory
	chdir(entry.d_name);
    	while( retval != NULL ) 
	{
        	struct stat entryInfo;
        
        	if( ( strncmp( entry.d_name, ".", PATH_MAX ) == 0 ) || ( strncmp( entry.d_name, "..", PATH_MAX ) == 0 ) ) 
		{
            		/* Short-circuit the . and .. entries. */
            		retval = readdir_r( dir, &entry);
            		continue;
        	}
		(void)strncpy( pathName, theDir, PATH_MAX );
        	(void)strncat( pathName, "/", PATH_MAX );
        	(void)strncat( pathName, entry.d_name, PATH_MAX );
        
        	if( lstat( pathName, &entryInfo ) == 0 ) 
		{
            		/* stat() succeeded, let's party */
            		count++;
            
            		if( S_ISDIR( entryInfo.st_mode ) ) 
			{            
				/* directory */
                		printf( "processing %s/\n", pathName );
                		count += process_directory( pathName );
            		} 
			else if( S_ISREG( entryInfo.st_mode ) ) 
			{ 
				/* regular file */
                		printf( "\t%s has %lld bytes\n", pathName, (long long)entryInfo.st_size );
            		} 
			else if( S_ISLNK( entryInfo.st_mode ) ) 
			{ 
				/* symbolic link */
                		char targetName[PATH_MAX + 1];
                		if( readlink( pathName, targetName, PATH_MAX ) != -1 ) 
				{
                    			printf( "\t%s -> %s\n", pathName, targetName );
                		} 
				else 
				{
                    			printf( "\t%s -> (invalid symbolic link!)\n", pathName );
                		}
            		}
        	} 
		else 
		{
            		printf( "Error statting %s: %s\n", pathName, strerror( errno ) );
        	}
 		retval = readdir_r( dir, &entry);
		/* Switch up to parent directory
		   Now that all directories at this level have been processed*/
		chdir(".."); 
    	}
    
    	/* Close the directory and return the number of entries. */
    	(void)closedir( dir );
    	return count;
}

/* readdir_demo main()
 * 
 * Run through the specified directories, and pass them
 * to process_directory().
 */
int main( int argc, char **argv )
{
    int idx = 0;
    unsigned count = 0;
    
    for( idx = 1; idx < argc; idx++ ) {
        count += process_directory( argv[idx] );
    }
    
    return EXIT_SUCCESS;
}

Open in new window


cpfoo@csa02 ~$ gcc as3.c -o MY
cpfoo@csa02 ~$ MY CS224
processing CS224/as3/
      CS224/as3/ourhdr.h has 4128 bytes
Error statting CS224/as3/error.c: No such file or directory
Error statting CS224/as3/as3.c: No such file or directory
Error statting CS224/as1: No such file or directory
Error statting CS224/.deps: No such file or directory
Error statting CS224/test: No such file or directory
Error statting CS224/as2: No such file or directory
cpfoo@csa02 ~$

dunno why it keeps appearing no such file or directory?
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> can i change it into something like this while (retval != NULL) as in referring to struct dirent *retval?

If you think that would do what you want it to do ... why not ? :)


Btw, we've strayed quite far from the original question now. So, let's go back to the original question. If you have any more questions about that, feel free to ask. Otherwise, this question should probably be closed. When doing so, keep in mind that you should accept those post(s) that answered the original question - not the ones that answered all the follow-up stuff ;)
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> dunno why it keeps appearing no such file or directory?

Because you changed the working directory with chdir ;)
0
 

Author Comment

by:crazy4s
Comment Utility
ok so back to my question 2? how should i put it so i make full use of this func?
currently i'm getting error because of this func?
0
 

Author Comment

by:crazy4s
Comment Utility
but even without the chdir func i seems to get a segmentation fault at the end?

cpfoo@csa02 ~$ gcc as3.c -o MY
cpfoo@csa02 ~$ MY CS224
processing CS224/as3/
      CS224/as3/ourhdr.h has 4128 bytes
      CS224/as3/error.c has 1837 bytes
      CS224/as3/as3.c has 2887 bytes
processing CS224/as1/
      CS224/as1/stamp-h1 has 23 bytes
      CS224/as1/configure has 137161 bytes
      CS224/as1/cpwh.c has 3503 bytes
      CS224/as1/missing has 11492 bytes
      CS224/as1/error.o has 5604 bytes
      CS224/as1/config.h.in has 625 bytes
Segmentation Fault (core dumped)
0
 

Author Comment

by:crazy4s
Comment Utility
the segmentation fault appeared is it because the files in that sub dir are not dir or files but more to some kind like hmm i'm not sure what's that like command that I used "MY"?
because when i used other directory that only have files, it compiled with no segmentation fault?
sorry i know i get out of the question.
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> ok so back to my question 2? how should i put it so i make full use of this func?

You mean chdir ?

You use it when you want to change the working directory. When you do that, is up to you, and depends on what you're trying to do.
For example, if you have the name of a directory in the current working directory, then you can chdir into this directory, and perform some actions in there.


>> but even without the chdir func i seems to get a segmentation fault at the end?

Make sure to always check for NULL and other error conditions.
0
 

Author Comment

by:crazy4s
Comment Utility
how if let's say i remove the first chdir(entry.d_name) and remain the 2nd chdir("..") before the end of the loop just to switch back to the parent directory? is this possible?
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
Everything is possible. But would it be useful ?

When is it that you want to change directories ? Or maybe a better question is : why ?
0
 

Author Comment

by:crazy4s
Comment Utility
hmm let's say cpfoo is my cwd... and i have subdir like cs224 and cs224 has subdir and files in it.
so when i enter cs224 in my command line...
supposed to be output all the sub dir and files in it... but the sub dir may have files in it too....
so when it is in this subdir, after finish processing this sub dir, we've to move on to the next sub dir in cs224, so that's why i need chdir here? am i correct?
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
If you list all files/directories in the current directory, and iterate over all of them, then for each, there are two possibilities :

(a) it's a directory : chdir into it, and do the same (list all files/directories, etc.). When done, chdir out of it.

(b) it's not a directory
0
 

Author Comment

by:crazy4s
Comment Utility
yes that's what i want for chdir
1)is to switch to a new directory if the sub directory is found as a directory not file (not sure where and what i should edit my codes)
2)switch back up to the parent directory (this one i put before the end of while loop)

so how should i edit it?
btw i've open a new related questions here
http://www.experts-exchange.com/Programming/Languages/C/Q_26886500.html
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
So, let's move to the other question then :)
0
 

Author Comment

by:crazy4s
Comment Utility
i suddenly found this

cpfoo@csa02 ~$ man readdir
Reformatting page.  Please Wait... done

Standard C Library Functions                          readdir(3C)

NAME
     readdir, readdir_r - read directory

SYNOPSIS
     #include <sys/types.h>
     #include <dirent.h>

     struct dirent *readdir(DIR *dirp);

     struct dirent *readdir_r(DIR *dirp, struct dirent *entry);

  Standard conforming
     cc [ flag... ] file... -D_POSIX_PTHREAD_SEMANTICS [ library... ]

     int readdir_r(DIR *restrict dirp, struct dirent *restrict entry,
         struct dirent **restrict result);

is this means that i can use the readdir_r with 3 arguments?
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> is this means that i can use the readdir_r with 3 arguments?

if you use that compiler flag, yes.
0
 

Author Comment

by:crazy4s
Comment Utility
how to use a compiler flag? can you lead me?
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
The man page shows how to do it :

>>      cc [ flag... ] file... -D_POSIX_PTHREAD_SEMANTICS [ library... ]
0
 

Author Comment

by:crazy4s
Comment Utility
hmm i'm not quite understand but is it smt like that  at the command line?
gcc as3.c -D_POSIX_PTHREAD_SEMANTICS?
0
 

Author Comment

by:crazy4s
Comment Utility
even i've changed it back i still get the segmentation fault?

cpfoo@csa02 ~$ gcc as3.c -D_POSIX_PTHREAD_SEMANTICS  
cpfoo@csa02 ~$ DirTrav CS224
processing CS224/as3/
        CS224/as3/ourhdr.h has 4128 bytes
        CS224/as3/error.c has 1837 bytes
        CS224/as3/as3.c has 2887 bytes
processing CS224/as1/
        CS224/as1/stamp-h1 has 23 bytes
        CS224/as1/configure has 137161 bytes
        CS224/as1/cpwh.c has 3503 bytes
        CS224/as1/missing has 11492 bytes
        CS224/as1/error.o has 5604 bytes
        CS224/as1/config.h.in has 625 bytes
Segmentation Fault (core dumped)

can't get it why i got this error?
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> hmm i'm not quite understand but is it smt like that  at the command line?
>> gcc as3.c -D_POSIX_PTHREAD_SEMANTICS?

Looks good.


>> even i've changed it back i still get the segmentation fault?

Switching implementations will not magically resolve this segmentation fault, because it's unrelated to the readdir function.

For both versions of the readir_r function, you were using it correctly, so switching to the other implementation doesn't gain you much (if anything).
0
 

Author Comment

by:crazy4s
Comment Utility
hmm i'm totally stuck because i'm not sure what that make it a segmentation fault?
do u have any suggestions?
i tried bt by using gdb core and it gives me this as the prob seems to happen in as1(subdir)

(gdb) bt
#0  0xff2e5694 in readdir64_r () from /usr/lib/libc.so.1
#1  0xff2e57f4 in readdir_r () from /usr/lib/libc.so.1
#2  0x00010b90 in process_directory (theDir=0xffbff4c8 "CS224/as1") at as3.c:83
#3  0x00010a4c in process_directory (theDir=0xffbffaeb "CS224") at as3.c:57
#4  0x00010c0c in main (argc=2, argv=0xffbff9dc) at as3.c:105
(gdb) up
#1  0xff2e57f4 in readdir_r () from /usr/lib/libc.so.1
(gdb) n
The program is not being run.
(gdb) up
#2  0x00010b90 in process_directory (theDir=0xffbff4c8 "CS224/as1") at as3.c:83
83                      retval = readdir_r( dir, &entry);
(gdb) up
#3  0x00010a4c in process_directory (theDir=0xffbffaeb "CS224") at as3.c:57
57                                      count += process_directory( pathName );
(gdb) up
#4  0x00010c0c in main (argc=2, argv=0xffbff9dc) at as3.c:105
105             count += process_directory( argv[idx] );
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> hmm i'm totally stuck because i'm not sure what that make it a segmentation fault?

That's what your other question is about, no ?
0
 

Author Comment

by:crazy4s
Comment Utility
0
 
LVL 8

Expert Comment

by:ssnkumar
Comment Utility
I think I have Solaris 10 virtual machine at home.
If I can get it, I will try to execute your code and see if it crashes for me also.

I don't think you are completely stuck.
You just need to debug and find your way out.
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> yes >> http://www.experts-exchange.com/Programming/Languages/C/Q_26886500.html#a35138030

And you're not receiving the help you need for this there ?
0
 

Author Comment

by:crazy4s
Comment Utility
no but more help will be better for me to find where it gets wrong:)
0
 
LVL 8

Expert Comment

by:ssnkumar
Comment Utility
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
Using libpcap/Jpcap to capture and send packets on Solaris version (10/11) Library used: 1.      Libpcap (http://www.tcpdump.org) Version 1.2 2.      Jpcap(http://netresearch.ics.uci.edu/kfujii/Jpcap/doc/index.html) Version 0.6 Prerequisite: 1.      GCC …
The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now