1

I am trying to figure out how the program /bin/ls -l calculates the total size (block count) for a directory. By this I mean the output total number that it prints right before the directory contents.

There is a similar question here: https://stackoverflow.com/questions/7401704/what-is-that-total-in-the-very-first-line-after-ls-l but it doesn't fully answer the question nor explain exactly how it is calculated.

I've tried adding the numbers of 512B blocks allocated for all the (non-hidden) files in a directory.  Here is how I am trying to go about it (in C):

 int getBlockSize(char* directory) {
   int size = 0;

   DIR *d;
   struct dirent *dir;
   struct stat fileStat;
   d = opendir(directory);
   if (d) {
       while ((dir = readdir(d)) != NULL) {
           if (dir->d_name[0] != '.') { // Ignore hidden files
               // Create the path to stat
               char info_path[PATH_MAX + 1];
               strcpy(info_path, directory);
               if (directory[strlen(directory) - 1] != '/')
                   strcat(info_path, "/");
               strcat(info_path, dir->d_name);

               stat(info_path, &fileStat);

               size += fileStat.st_blocks;
           }
       }
   }

   return size;
}

However this is giving me a much different number compared to the ls command.

What is 'wrong' with my approach?  How does ls compute the total?

Edit:

To test I made a folder which contains files test_file1.txt and test_file2.txt each containing the text Hello World!. When I run ls -l I get the following output

total 1
-rw-------. 1 aaa111 ugrad 13 Oct 27 13:17 test_file1.txt
-rw-------. 1 aaa111 ugrad 13 Oct 27 13:17 test_file2.txt

However when I run my code using the method above I get

total 2
-rw-------. 1 aaa111 ugrad 13 Oct 27 13:17 test_file1.txt
-rw-------. 1 aaa111 ugrad 13 Oct 27 13:17 test_file2.txt 
0

The ls default on Linux is to present the total line in 1K blocks, so your result is correct since you're counting 512-byte blocks.

You can force ls to count in 512-byte blocks using POSIXLY_CORRECT:

POSIXLY_CORRECT=1 ls -l

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.