Operating System - HP-UX
1824879 Members
4052 Online
109675 Solutions
New Discussion юеВ

Re: c code help on determining an existing directory

 
SOLVED
Go to solution
Hanry Zhou
Super Advisor

c code help on determining an existing directory

Hi,

I need to determine if there is directory existed on the system, /a/b/c/d, if yes, I would set the variable xyz="yes", if not, set it to "no".

It has to be achieved by c code. Can anybody please help me the detail code?

Thanks,
none
8 REPLIES 8
A. Clay Stephenson
Acclaimed Contributor
Solution

Re: c code help on determining an existing directory

This is actually quite easy. The ket is the stat() system call + some macro's defined in stat.h. Man stat for details.

The isdir function returns 0 if the file/directory exists AND it sets a boolean to a non-zero value if the file is indeed a directory.

-----------------------------------------

#include
#include
#include

extern int errno;

#define assign_errno(x) ((errno != 0) ? errno : (x))

#ifndef FALSE
#define FALSE (0)
#endif

int isdir(char *fname, int *is_dir)
{
int cc = 0;
struct stat s;

*is_dir = FALSE;
cc = stat(fname,&s);
if (cc == 0)
{
*is_dir = (S_ISDIR(s.st_mode));
}
else
{
cc = assign_errno(-1);
(void) fprintf(stderr,"Can't stat %s (%d)\n",fname,cc);
}
return(cc);
} /* isdir */

int main(int argc, char *argv[])
{
int cc = 0,i = 1,isadir = FALSE;

while (i < argc)
{
cc = isdir(argv[i],&isadir);
(void) printf("File: %s cc = %d isadir = %d\n",argv[i],cc,isadir);
++i;
}
return(cc);
}

------------------------------------------
Note the use of the S_ISDIR macro. If I have made any typo's this should do it for you.

If it ain't broke, I can fix that.
Hanry Zhou
Super Advisor

Re: c code help on determining an existing directory

Hi,

Thanks for the code.

The first question came to my mind is following:

The code only can determine if it is a file or not, but can not determine the directory.
let say, I have /a/b/c/d, if "d" is a file, I will get "0" return, if "d" is directory, I will get non-zero return. Is my statement correctly?

Also, if I will get non-zero return when it is directory, then that is not good to determine it is directory or not. I mean, is there a way to see if it is directory or not?
none
A. Clay Stephenson
Acclaimed Contributor

Re: c code help on determining an existing directory

No, it does both things.

int cc = 0,isadir = 0;

cc = isdir(fname,&isadir);

Note that we pass in two arguments: the pathname and a pointer to an int. The convention for C functions is to return 0 for success. Your function might fail for several reasons: e.g. file/dir not found, you might not have permission to follow a path, filename too long to name just a few.
If the stat command fails for any reason, a meaningful (errno) non-zero result is returned. Only when the return result is 0 do you now check to see if the second argument (isadir) has been set to a non-zero status indicating that the file is in fact a directory. Remember, in UNIX speak, directories (along with device nodes, pipes, and symbolic links) are files too. The correct way to phrase your question is "Is a/b/c/d a REGULAR file or a directory?".


You could simply do this:
(void) isadir("/a/b/c/d",&isdir);
if (isdir) printf("Is a directory\n");
else printf("Not a directory\n");

The problem with that approach is that all you know is whether or not it is a directory but if not, you know nothing else. Was it an IO failure? Permissions? or simply a file instead of a directory?
If it ain't broke, I can fix that.
A. Clay Stephenson
Acclaimed Contributor

Re: c code help on determining an existing directory

Oops, my last example would be better if I kept the function/varible names consistant:

You could simply do this:
(void) isadir("/a/b/c/d",&isdir);
if (isdir) printf("Is a directory\n");
else printf("Not a directory\n");

SHOULD BE:

You could simply do this:
(void) isdir("/a/b/c/d",&isadir);
if (isadir) printf("Is a directory\n");
else printf("Not a directory\n");


If it ain't broke, I can fix that.
Hanry Zhou
Super Advisor

Re: c code help on determining an existing directory

Thank you so much for the detail message.
but, Sorry, I'm a slow man, still confused.

1. As you said, non-zero return will be indicating an error, so how can you conculude that if (isadir) has been set to a non-zero status indicating that the file is in fact a directory?

2. *is_dir = (S_ISDIR(s.st_mode));
does this line actually tell you if the "d" is directory or not.



none
Hanry Zhou
Super Advisor

Re: c code help on determining an existing directory

If I understand you correctly in the case of S_ISDIR(...), since it is macro, so if it returns a non-zero, then that will indicate that it is directory. Right?

Also, for "cc = stat(fname,&s);", it will retrun zero if it is either a regular file or directory, and that is why we need have "
*is_dir = (S_ISDIR(s.st_mode));". Right?
none
A. Clay Stephenson
Acclaimed Contributor

Re: c code help on determining an existing directory

Yes, you have it now. You could actually determine if the file were a directory after doing a stat by looking at some bits in the "mode" field.

int md;

md = (s.st_mode & 0170000) >> 12;
switch(md)
{
case 012:
(void) printf("Symbolic link\n"):
break;
case 010:
(void) printf("Regular file\n");
break;
case 006:
(void) printf("Block special\n");
break;
case 004:
(void) print("Directory\n");
break;
case 002:
(void) printf("Character Special\n");
break;
case 001:
(void) printf("FIFO/Pipe\n");
break;
default :
(void) printf("Unknown\n");
break;
} /* switch */

The S_ISDIR() macro is a bit easier to use but it's essentially:
((s.st_mode & 0170000) == 040000)
If that expression is non-zero then the file is a directory.

NOTE: All of these constants are octal values/
If it ain't broke, I can fix that.
A. Clay Stephenson
Acclaimed Contributor

Re: c code help on determining an existing directory

I'll try to bit a little more clear:

The stat() system call, if sucessful, returns
a 0 if ok or -1 if not and sets the global variable errno to indicate the error. This is the standard convention for all UNIX system calls. If the result is zero, a data structure containing all the metadata (modification, change, and last access times, owner, group, mode, file length, and others) is filled in and then we need to examine the fields within this structure for more detailed knowledge. Specifically, we need to examine the st_mode field which encodes the file type (what you are interested in), the setuid, setgid, and "sticky" bits, as well as the more familiar permissions for owner, group, and other.
If it ain't broke, I can fix that.