Determine file/folder in C - c

I have the following code in C:
DIR *mydir = opendir("/");
struct dirent *entry = NULL;
while((entry = readdir(mydir)))
{
printf("%s\n", entry->d_name);
//printf("%i\n", entry->d_type);
}
closedir(mydir);
It works and shows the files/folders in the location, correctly.
However, I want to tell if it is a folder or a file. How can I do this? I tried with d_type (as you can see on the code) but no success.

Use stat():
struct stat st;
stat("nodename", &st);
int isDirectory = S_ISDIR(st.st_mode);

You should use stat() function wich get you a stat structure.
struct stat s;
if( stat(path,&s) == 0 )
{
if( s.st_mode & S_IFDIR )
{
//it's a directory
}
else if( s.st_mode & S_IFREG )
{
//it's a file
}
else
{
//something else
}
}
else
{
//error
}

You can use built in macros like this:
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
int main(void)
{
DIR *mydir = opendir(/);
struct dirent *entry = NULL;
struct stat buf;
while((entry = readdir(mydir)))
{
printf("%s\n", entry->d_name);
if (stat(entry, &buf))
{
perror("stat");
exit(-1);
}
if ( S_ISDIR(buf.st_mode) )
{
printf("%s is a directory\n", entry);
}
if ( S_ISREG(buf.st_mode) )
{
printf("%s is a regular file\n", entry);
}
}
closedir(mydir);
return 0;
}
See man 2 stat in a shell for more information.

This is system-specific and we cannot give a completely solid answer without knowing your OS and possibly other settings.
d_type in fact does work for at least some systems. Your code gives a useful answer on RedHat Linux with a value of 4 for directories, 8 for regular files, and other values for other file types. This is with a fix to the typo to surround the name / in the call to opendir with quotes.

Related

Methods to iterate every file in a directory?

I've been looking around for methods by which a directory can be monitored for file creation/modification etc. however all the previous posts I've found for Windows are C++ specific.
Microsoft does list ReadDirectoryChangesW, but this too is for C++ (I haven't the knowledge to assess whether these are compatible for C). I've only knowledge with inotify for Linux, which is fairly straightforward, and wondered if there are any simple examples of the Windows equivalent? (I do not want to use inotify on Windows despite it technically being achievable).
If you are just looking for methods, maybe this will help a bit:
https://www.geeksforgeeks.org/c-program-list-files-sub-directories-directory/
(just copy-pasted the code in case)
Tested it on linux machine and it seems to work. Not recursive though.
int main(void)
{
struct dirent *de; /* Pointer for directory entry */
/* opendir() returns a pointer of DIR type. */
DIR *dr = opendir(".");
if (dr == NULL) /* opendir returns NULL if couldn't open directory */
{
printf("Could not open current directory" );
return 0;
}
/* Refer http://pubs.opengroup.org/onlinepubs/7990989775/xsh/readdir.html
for readdir() */
while ((de = readdir(dr)) != NULL)
printf("%s\n", de->d_name);
closedir(dr);
return 0;
}
Also, see this question if you need to check if a listed file is a directory:
Checking if a dir. entry returned by readdir is a directory, link or file
This method may not be as portable as it seems, but worth a try.
Cheers!
Using FindFirstFile to hit the first node of certain directory, then to call FindNextFile to iterate files one by one inside one directory layer.
Here is my sample code for your reference, there is a recursive funcion.
#include "stdafx.h"
#include <string>
static void iterate_dir(std::string dir) {
WIN32_FIND_DATA fd;
HANDLE hFind;
std::wstring fn_ws;
std::string fn;
int pos = 0;
int count_bg = 0;
int count_fg = 0;
std::string dir_bkp = dir;
std::string dir_sub;
std::string str_wide_char_for_any = "*.*";
std::string str_folder_node = "..";
if (dir.length() - dir.find_last_of("\\") > 1) //dir ends without "\\"
dir += "\\";
dir += str_wide_char_for_any;
std::wstring dir_wstr = std::wstring(dir.begin(), dir.end());
LPCWSTR dir_wc = dir_wstr.c_str();
hFind = FindFirstFile(dir_wc, &fd);
if (hFind == INVALID_HANDLE_VALUE) {
FindClose(hFind);
return;
}
while(true) {
if (!FindNextFile(hFind, &fd)) {
break;
}
if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
fn_ws = std::wstring(fd.cFileName);
fn = std::string(fn_ws.begin(), fn_ws.end());
if (fn.compare(str_folder_node) == 0) {
continue;
}
else {
if ((pos = dir.rfind(str_wide_char_for_any)) != std::string::npos) {
dir_sub = dir;
dir_sub = dir_sub.replace(dir_sub.begin()+pos, dir_sub.end(), fn.begin(), fn.end());
}
else if (dir.length() - (pos = dir.rfind("\\")) > 1) {
dir_sub = dir;
dir_sub += "\\";
dir_sub += fn;
}
else {
dir_sub = dir;
dir_sub += fn;
}
printf("[%s][directory]:%s\n", __func__, dir.c_str());
iterate_dir(dir_sub);
continue;
}
}
else if (fd.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) {
fn_ws = std::wstring(fd.cFileName);
fn = std::string(fn_ws.begin(), fn_ws.end());
printf("[%s][file]:%s\n", __func__, fn.c_str());
}
else {
fn_ws = std::wstring(fd.cFileName);
fn = std::string(fn_ws.begin(), fn_ws.end());
printf("[%s][unspecified attribute file]:%s\n", __func__, fn.c_str());
}
}
FindClose(hFind);
return;
}
You can have a main.cpp like:
int main() {
std::string dir_name("C:\\test");
iterate_dir(dir);
return 0;
}

C function to remove a directory [duplicate]

How to delete a non empty directory in C or C++? Is there any function? rmdir only deletes empty directory. Please provide a way without using any external library.
Also tell me how to delete a file in C or C++?
You want to write a function (a recursive function is easiest, but can easily run out of stack space on deep directories) that will enumerate the children of a directory. If you find a child that is a directory, you recurse on that. Otherwise, you delete the files inside. When you are done, the directory is empty and you can remove it via the syscall.
To enumerate directories on Unix, you can use opendir(), readdir(), and closedir(). To remove you use rmdir() on an empty directory (i.e. at the end of your function, after deleting the children) and unlink() on a file. Note that on many systems the d_type member in struct dirent is not supported; on these platforms, you will have to use stat() and S_ISDIR(stat.st_mode) to determine if a given path is a directory.
On Windows, you will use FindFirstFile()/FindNextFile() to enumerate, RemoveDirectory() on empty directories, and DeleteFile() to remove files.
Here's an example that might work on Unix (completely untested):
int remove_directory(const char *path) {
DIR *d = opendir(path);
size_t path_len = strlen(path);
int r = -1;
if (d) {
struct dirent *p;
r = 0;
while (!r && (p=readdir(d))) {
int r2 = -1;
char *buf;
size_t len;
/* Skip the names "." and ".." as we don't want to recurse on them. */
if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, ".."))
continue;
len = path_len + strlen(p->d_name) + 2;
buf = malloc(len);
if (buf) {
struct stat statbuf;
snprintf(buf, len, "%s/%s", path, p->d_name);
if (!stat(buf, &statbuf)) {
if (S_ISDIR(statbuf.st_mode))
r2 = remove_directory(buf);
else
r2 = unlink(buf);
}
free(buf);
}
r = r2;
}
closedir(d);
}
if (!r)
r = rmdir(path);
return r;
}
Many unix-like systems (Linux, the BSDs, and OS X, at the very least) have the fts functions for directory traversal.
To recursively delete a directory, perform a depth-first traversal (without following symlinks) and remove every visited file:
int recursive_delete(const char *dir)
{
int ret = 0;
FTS *ftsp = NULL;
FTSENT *curr;
// Cast needed (in C) because fts_open() takes a "char * const *", instead
// of a "const char * const *", which is only allowed in C++. fts_open()
// does not modify the argument.
char *files[] = { (char *) dir, NULL };
// FTS_NOCHDIR - Avoid changing cwd, which could cause unexpected behavior
// in multithreaded programs
// FTS_PHYSICAL - Don't follow symlinks. Prevents deletion of files outside
// of the specified directory
// FTS_XDEV - Don't cross filesystem boundaries
ftsp = fts_open(files, FTS_NOCHDIR | FTS_PHYSICAL | FTS_XDEV, NULL);
if (!ftsp) {
fprintf(stderr, "%s: fts_open failed: %s\n", dir, strerror(errno));
ret = -1;
goto finish;
}
while ((curr = fts_read(ftsp))) {
switch (curr->fts_info) {
case FTS_NS:
case FTS_DNR:
case FTS_ERR:
fprintf(stderr, "%s: fts_read error: %s\n",
curr->fts_accpath, strerror(curr->fts_errno));
break;
case FTS_DC:
case FTS_DOT:
case FTS_NSOK:
// Not reached unless FTS_LOGICAL, FTS_SEEDOT, or FTS_NOSTAT were
// passed to fts_open()
break;
case FTS_D:
// Do nothing. Need depth-first search, so directories are deleted
// in FTS_DP
break;
case FTS_DP:
case FTS_F:
case FTS_SL:
case FTS_SLNONE:
case FTS_DEFAULT:
if (remove(curr->fts_accpath) < 0) {
fprintf(stderr, "%s: Failed to remove: %s\n",
curr->fts_path, strerror(curr->fts_errno));
ret = -1;
}
break;
}
}
finish:
if (ftsp) {
fts_close(ftsp);
}
return ret;
}
If you are using a POSIX compliant OS, you could use nftw() for file tree traversal and remove (removes files or directories). If you are in C++ and your project uses boost, it is not a bad idea to use the Boost.Filesystem as suggested by Manuel.
In the code example below I decided not to traverse symbolic links and mount points (just to avoid a grand removal:) ):
#include <stdio.h>
#include <stdlib.h>
#include <ftw.h>
static int rmFiles(const char *pathname, const struct stat *sbuf, int type, struct FTW *ftwb)
{
if(remove(pathname) < 0)
{
perror("ERROR: remove");
return -1;
}
return 0;
}
int main(int argc, char *argv[])
{
if (argc != 2)
{
fprintf(stderr,"usage: %s path\n",argv[0]);
exit(1);
}
// Delete the directory and its contents by traversing the tree in reverse order, without crossing mount boundaries and symbolic links
if (nftw(argv[1], rmFiles,10, FTW_DEPTH|FTW_MOUNT|FTW_PHYS) < 0)
{
perror("ERROR: ntfw");
exit(1);
}
return 0;
}
The easiest way to do this is with remove_all function of the Boost.Filesystem library. Besides, the resulting code will be portable.
If you want to write something specific for Unix (rmdir) or for Windows (RemoveDirectory) then you'll have to write a function that deletes are subfiles and subfolders recursively.
EDIT
Looks like this question was already asked, in fact someone already recommended Boost's remove_all. So please don't upvote my answer.
C++17 has <experimental\filesystem> which is based on the boost version.
Use std::experimental::filesystem::remove_all to remove recursively.
If you need more control, try std::experimental::filesystem::recursive_directory_iterator.
You can also write your own recursion with the non-resursive version of the iterator.
namespace fs = std::experimental::filesystem;
void IterateRecursively(fs::path path)
{
if (fs::is_directory(path))
{
for (auto & child : fs::directory_iterator(path))
IterateRecursively(child.path());
}
std::cout << path << std::endl;
}
You can use opendir and readdir to read directory entries and unlink to delete them.
//======================================================
// Recursely Delete files using:
// Gnome-Glib & C++11
//======================================================
#include <iostream>
#include <string>
#include <glib.h>
#include <glib/gstdio.h>
using namespace std;
int DirDelete(const string& path)
{
const gchar* p;
GError* gerr;
GDir* d;
int r;
string ps;
string path_i;
cout << "open:" << path << "\n";
d = g_dir_open(path.c_str(), 0, &gerr);
r = -1;
if (d) {
r = 0;
while (!r && (p=g_dir_read_name(d))) {
ps = string{p};
if (ps == "." || ps == "..") {
continue;
}
path_i = path + string{"/"} + p;
if (g_file_test(path_i.c_str(), G_FILE_TEST_IS_DIR) != 0) {
cout << "recurse:" << path_i << "\n";
r = DirDelete(path_i);
}
else {
cout << "unlink:" << path_i << "\n";
r = g_unlink(path_i.c_str());
}
}
g_dir_close(d);
}
if (r == 0) {
r = g_rmdir(path.c_str());
cout << "rmdir:" << path << "\n";
}
return r;
}
How to delete a non empty folder using unlinkat() in c?
Here is my work on it:
/*
* Program to erase the files/subfolders in a directory given as an input
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void remove_dir_content(const char *path)
{
struct dirent *de;
char fname[300];
DIR *dr = opendir(path);
if(dr == NULL)
{
printf("No file or directory found\n");
return;
}
while((de = readdir(dr)) != NULL)
{
int ret = -1;
struct stat statbuf;
sprintf(fname,"%s/%s",path,de->d_name);
if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
continue;
if(!stat(fname, &statbuf))
{
if(S_ISDIR(statbuf.st_mode))
{
printf("Is dir: %s\n",fname);
printf("Err: %d\n",ret = unlinkat(dirfd(dr),fname,AT_REMOVEDIR));
if(ret != 0)
{
remove_dir_content(fname);
printf("Err: %d\n",ret = unlinkat(dirfd(dr),fname,AT_REMOVEDIR));
}
}
else
{
printf("Is file: %s\n",fname);
printf("Err: %d\n",unlink(fname));
}
}
}
closedir(dr);
}
void main()
{
char str[10],str1[20] = "../",fname[300]; // Use str,str1 as your directory path where it's files & subfolders will be deleted.
printf("Enter the dirctory name: ");
scanf("%s",str);
strcat(str1,str);
printf("str1: %s\n",str1);
remove_dir_content(str1); //str1 indicates the directory path
}
This code will open particular directory and iterate over all files and delete them which are under that directory. After that it will delete empty directory at the end.
/**
* #file RemoveDir.c
* #author Om Patel (ompatel1861#gmail.com)
* #brief This program will remove non empty directory.
* #version 0.1
* #date 2022-05-31
*
* #copyright Copyright (c) 2022
*
*/
#include<stdio.h>
#include<string.h>
#include<dirent.h>
#include <unistd.h>
int main()
{
DIR* dir = opendir("OUTPUT/Aakash");
struct dirent* entity;
entity = readdir(dir);
while(entity != NULL){
char path[30] ="OUTPUT/Aakash/";
printf("%s\n",entity->d_name);
strcat(path,entity->d_name);
printf("PAth: %s\n",path);
remove(path);
entity = readdir(dir);
}
char path1[30] ="OUTPUT/Aakash";
rmdir(path1);
closedir(dir);
char out[20]="OUTPUT/";
char fol_file[30];
sprintf(fol_file,"%s\\",out);
printf("%s",fol_file);
return 0;
}

checking directory paths ends with ".", ".."

I have a programming problem that I hope someone out there can help me with. I am trying to learn C programming for a task at work and I have set myself a little project, which consists of reading down a file tree including all the sub directories obtaining information about each file.
The problem I get is that my program dosen't ignore the directory path ends with either /. or /.. and when it prints all the directories, I want to give space in front of the subdirectories for the readablity.
so the error is occured at this part:
int isDir(const char *parent, char *name) {
struct stat st_buf; // file info
char buf[BUF_SIZE];
if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
return 0;
}
char *path = malloc(strlen(name) + strlen(parent) + 2);
//sprintf(char *buf, const char *format, [arg1],[arg2],...)
sprintf(path, "%s/%s", parent, name);
stat(path, &st_buf); //
return S_ISDIR(st_buf.st_mode); //directory
}
And this is main and list function:
int list(const char *name) {
DIR *dirp = opendir(name);
struct dirent *dentry;
char buf[BUF_SIZE];
while ((dentry = readdir(dirp)) != NULL) {
char *dir_name = dentry->d_name;
printf(" %s\n", dir_name);
//if it's dir, then go into dir
if (isDir(name, dir_name)) { //name : parent, dir_name : child
chdir(dir_name);
getcwd(buf, BUF_SIZE);
list(buf);
}
}
closedir(dirp);
}
int main()
{
list(".");
return 0;
}
The result is like this:
hm1.c
Data
lab1.txt
result1
lab3.txt
.
..
.
..
result2
lab3.txt
.
..
result3
lab3.txt
.
..
a.c
.
..
a.out
result I want to print
hm1.c
Data
lab1.txt
result1
lab3.txt
result2
lab3.txt
result3
lab3.txt
a.c
a.out
Your isDir is returning true/false where it returns false (or zero) if you have . oe .. and then the true/false value of S_ISDIR in other cases
What you really need is the function to return one of 3 values SKIP, isFILE or isDIR and then write your print logic based on that.
You also need to fix your memory leaks
Also note that chdir(dir_name); changes the actual directory of the process, so once you return fromlist within your loop you will no longer be able to open the files or directories that you are looping over (because you are now in a different directory)
This will fix your problems and print the format you want
enum { doSkip, isFile, isDir } testDir(char *path, char *name)
{
struct stat st_buf;
if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
return doSkip;
}
stat(path, &st_buf);
if (S_ISDIR(st_buf.st_mode))
return isDir;
return isFile;
}
void list(const char *path, int indentlevel)
{
DIR *dirp = opendir(path);
struct dirent *dentry;
char buf[10000]; // Lets just make the buffer sufficently big for this example
if (!dirp) {
printf("%*sNo access\n",indentlevel,"");
return;
}
while ((dentry = readdir(dirp)) != NULL) {
sprintf(buf,"%s/%s", path, dentry->d_name);
switch (testDir(buf,dentry->d_name)) {
case doSkip:
/* do nothing */
break;
case isDir:
printf("%*s%s:\n",indentlevel,"",dentry->d_name);
list(buf,indentlevel+4);
break;
case isFile:
printf("%*s%s\n",indentlevel,"",dentry->d_name);
break;
}
}
closedir(dirp);
}
int main()
{
list(".", 0);
return 0;
}
Another way to do it, if you're willing to go to C++, is to use std::experimental::filesystem, also (mostly) known as Boost.Filesystem. With that, you would do something like:
#include <experimental/filesystem> // Could substitute <boost/filesystem.hpp>
#include <boost/range/iterator_range.hpp>
#include <iostream>
using namespace std::experimental;
int main(int argc, char *argv[])
{
const auto path = filesystem::path{ argc > 1 ? argv[1] : "." };
if( filesystem::is_directory(path) )
{
std::cout << path << " is a directory containing:\n";
for( const auto& entry : boost::make_iterator_range( filesystem::recursive_directory_iterator{path}, {} ) )
{
std::cout << entry << "\n";
}
}
}
See it run here. Note that the directory iterators automatically skip . and ...

C opening and reading directories

So im trying to write a program in C that works like the ls command from Linux,
for the moment i've been capable of listing the files and directories inside my Current working directory, but i don't seem to be capable of doing the same for directories that are not my CWD, do i need to change it before i start listing it? or does the function opendir() work for any directory?
It has to work like ls -li from Linux but i got the printing stuff handled.
In general my program looks like this (obvsly it has more things):
void function(char *directory_to_list){
DIR *d;
struct dirent *dirp;
struct stat filestat;
if ( (d = opendir(directory_to_list)) == NULL){
//print error
}
while ( ( dirp = readdir(d) ) != NULL){
//here i call the stat() function for every entry to get various information
if (stat(dirp->d_name, &filestat) == -1){
continue;
}
//various prints
}
closedir(d);
}
EDIT: The command would be -> ls -li [-dir] so if you dont get any dir you just list your CWD.
EDIT2: No error is being returned it just does nothing, it opens the directory just fine but doenst list anything so i guess the stat call is not being done well, also added the line for how i call stat().
Here is a working version. Pay special attention that you do not overflow the buffer. you'll have to do some significant error checking to make this secure:
#include <stdio.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
int function(char *);
int main(void)
{
function("/tmp");
return 0;
}
int function(char *path)
{
DIR *dir;
struct dirent *dentry;
struct stat filestat;
char *giantbuffer = malloc(sizeof(char) * ((PATH_MAX * 2 ) + 1) );
if ( ( dir = opendir(path) ) )
{
dentry = readdir(dir);
while ( dentry )
{
sprintf(giantbuffer, "%s/%s", path, dentry->d_name);
printf("%s ", giantbuffer);
if (stat(giantbuffer, &filestat) == 0)
printf("%zu\n", filestat.st_size);
dentry = readdir(dir);
}
closedir(dir);
}
else
return -1;
return 0;
}

How to get total size of a folder in C with recursivity?

All the folders have the size 4096 B.
How do I get the total size of a folder with all the file size inside?
For example:
> Dir1 (4096)
> -- File1.txt (100)
> -- Dir 2 (4096)
> ---- File2.txt (100)
When I try to get the size of Dir1, it gives me 4096.
The expected answer I wish to get is 8392
Another example:
DirA (4096)
-- FileA (100)
-- FileB (100)
The total should be 4296
I'm trying to figure out the algorithm but I can't find a way to detect if it's a folder or not. Sorry for the "vulgar" code below...
DIR *dir;
struct dirent *dp;
struct stat fileStat;
int getTotalDirSize()
{
while()
{
if(/*Detect Folder/Directory*/)
{
totalSize += 4096;
getTotalDirSize();
}
else
{
totalSize += fileSize;
}
}
return totalSize;
}
Note: I'm using the struct stat to get the size and the file/folder name.
Its working using with stat but only you have to do is give complete path to the stat like in your example Dir1->4096B then if you want to know size of the File1.txt use in stat like this:
strcpy(str,Dir1); //str is a string
strcat(str,"/");
strcat(str,filename);
Then use str in stat to get size of that file. I think here you have to use dirent structure and DIR for folder and its contents.
For finding folder use d_type = 4 for dirent structure pointer. For recursive action put all in one separate function and call it recursively until folder search completes.
struct stat buf;
DIR *dptr;
struct dirent *sdir;
int size=0;
char str[100];
dptr=opendir(folder);
while(sdir=readdir(dptr))
{
if(sdir->d_type==4)
{
if(sdir->d_name[0]!='.')
{
stat(sdir->d_name,&buf);
size=buf.st_size;
pf("size=%d\n",size);
}
}
else
{
strcpy(str,folder);
strcat(str,"/");
strcat(str,sdir->d_name);
stat(str,&buf);
size+=buf.st_size;
pf("size=%d\n",size);
}
}
I was just searching for a solution to this same problem when I encountered this thread and some others here on SO dealing with equal or similar problems (I found at the end 3 different codes aimed to calculate the total size of a folder with pure C). Unfortunately none of them worked by themselves or were incomplete, so I had to improve them (merging one into the other) and I came to the following complete and working code-and-example (should be put inside a main.c file, the exact folder changed and then just run). I hope it helps!
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <stdint.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
int readFolderSize(int* totalSize, char* folder)
{
char fullPath[256];
struct dirent *dirData;
struct stat buffer;
int exists;
DIR *poDir;
int resp = EXIT_SUCCESS;
poDir = opendir(folder);
if (poDir == NULL)
{
perror("general_getFolderSize: poDir fail!");
return EXIT_FAILURE;
}
while ((dirData = readdir(poDir)))
{
if (dirData == NULL)
{
const unsigned int err = errno;
fprintf(stderr, "general_getFolderSize: Failed in readdir (%u)\n",err);
resp = EXIT_FAILURE;
continue;
}
//
if (dirData->d_type == DT_DIR)
{
if (dirData->d_name[0] != '.')
{
//printf("general_getFolderSize: Is a directory: %s\n", dirData->d_name);
strcpy(fullPath,folder);
strcat(fullPath,"/");
strcat(fullPath,dirData->d_name);
//printf("general_getFolderSize: Accessing dir: %s\n", fullPath);
if (readFolderSize(totalSize,fullPath) == EXIT_FAILURE)
resp = EXIT_FAILURE;
}
}
else
{
strcpy(fullPath,folder);
strcat(fullPath,"/");
strcat(fullPath,dirData->d_name);
exists = stat(fullPath,&buffer);
if (exists < 0)
{
const unsigned int err = errno;
fprintf(stderr, "general_getFolderSize: Failed in stat (file) %s: %u\n", fullPath,err);
resp = EXIT_FAILURE;
continue;
}
else
{
(*totalSize) += buffer.st_size;
//printf("general_getFolderSize: Item size (file) (%s): %d\n",fullPath,(int)buffer.st_size);
}
}
}
closedir(poDir);
return resp;
}
/*!
* \brief general_getFolderSize returns the size of a folder in bytes.
* \param folder is the name of the folder (preferentially without a '/' at the end)
* \param totalSize is a pointer where the result value is given
* \return
*/
int general_getFolderSize(char* folder, int* totalSize)
{
printf("general_getFolderSize: Start\n");
//
if (readFolderSize(totalSize,folder) == EXIT_FAILURE)
{
perror("general_getFolderSize: Call to readFolderSize failed!");
return EXIT_FAILURE;
}
//
printf("general_getFolderSize: Stop\n");
return EXIT_SUCCESS;
}
int main()
{
int folderSize;
if (general_getFolderSize("/home/maiquel/Documents/TEMP/maindir",&folderSize) == EXIT_FAILURE)
{
printf("Error reading folder size!");
}
else
{
printf("Folder size: %d b (%d kb / %d Mb)\n", folderSize, folderSize/1024, folderSize/(1024 * 1024));
}
return EXIT_SUCCESS;
}
P.s.: Although I'm aware that EXIT_SUCCESS and EXIT_FAILURE are not supposed to be used as function return values, I preferred to do so instead of creating new defines in the name of code simplicity.

Resources