This function is supposed to delete all the contents of a folder in Linux, using Linux system calls (stat, readdir, unlink, rmdir, etc.).
It takes the path of a folder as a parameter, and it runs as expected when you call it on a folder that has files or empty folders.
If the target folder contains a subfolder, my function recursively makes another call to itself with that subfolder as the target parameter. This is done to empty all the subfolders before rmdir'ing them - since rmdir() cannot unlink a folder unless it is empty.
However, the recursion aspect does not work. It does delete files in subfolders, but not subfolders themselves.
Possible cause: As the recursion unwinds, the value of
itemPath
(which I believe should be local to the calling function instance) is altered by the recursive call and changed to the value of itemPath
that I thought should be unique to the recursive function instance.
I suspect that I'm misunderstanding something about how C allocates new variables during recursive calls, but I can't figure out how to fix this.
Example run: Debug output
Note that the value of itemPath
has changed between "beginning recursive call" and "end of recursion".
Example run is on this directory structure:
/tmp/testPopd/ <--- target parameter for test
/tmp/testPopd/file
/tmp/testPopd/dir/
/tmp/testPopd/dir/subfile
/tmp/testPopd/dir/subdir/
Code:
void deleteContents(const char* targetDir)
{
printf("func called with %s as parameter\n", targetDir);
// Oper targetDir
DIR* targetDirstream = opendir(targetDir);
struct dirent* targetDirent;
// This loop scans across all items in targetDir
int numEntries = 0;
while( ((targetDirent = readdir(targetDirstream)) != NULL) )
{
// Ensure that we do not delete the first 2 dir entries (. and ..)
numEntries++;
if (numEntries <= 2)
continue;
// Assemble the directory path and the filename into the full path for the item
char* itemPath;
strcpy(itemPath, targetDir);
strcat(itemPath, "/");
strcat(itemPath, targetDirent->d_name);
// Determine if the item is a directory, in order to apply correct system call
struct stat itemStat;
stat(itemPath, &itemStat);
if (S_ISDIR(itemStat.st_mode)) // Item is a directory, recur and remove using rmdir()
{
printf("beginning recursive call, var itemPath is %s \n", itemPath);
// Recur into subfolder to ensure it is empty
deleteContents(itemPath);
printf("end of recursion, var itemPath is %s \n", itemPath);
rmdir(itemPath);
}
else // Item is a file, remove using unlink()
{
printf("deleting file %s \n", itemPath);
unlink(itemPath);
}
}
closedir(targetDirstream);
}