1126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood/* 2126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * 3126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * Copyright (C) 2008, The Android Open Source Project 4126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * 5126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * Licensed under the Apache License, Version 2.0 (the "License"); 6126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * you may not use this file except in compliance with the License. 7126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * You may obtain a copy of the License at 8126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * 9126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * http://www.apache.org/licenses/LICENSE-2.0 10126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * 11126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * Unless required by applicable law or agreed to in writing, software 12126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * distributed under the License is distributed on an "AS IS" BASIS, 13126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * See the License for the specific language governing permissions and 15126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * limitations under the License. 16126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood */ 17126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood 18126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood#include <dirent.h> 19126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood#include <fcntl.h> 20126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood#include <sys/stat.h> 2114df3564fbff5ea9e5fd7d43806258faed46f046Elliott Hughes#include <unistd.h> 22126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood 23126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood#include <diskusage/dirsize.h> 24126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood 25126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwoodint64_t stat_size(struct stat *s) 26126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood{ 27126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood int64_t blksize = s->st_blksize; 287719b85bf89530c88807ce605308ffc3d50f3b58Marco Nelissen // count actual blocks used instead of nominal file size 297719b85bf89530c88807ce605308ffc3d50f3b58Marco Nelissen int64_t size = s->st_blocks * 512; 30126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood 31126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood if (blksize) { 32126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood /* round up to filesystem block size */ 33126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood size = (size + blksize - 1) & (~(blksize - 1)); 34126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood } 35126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood 36126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood return size; 37126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood} 38126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood 39126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwoodint64_t calculate_dir_size(int dfd) 40126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood{ 41126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood int64_t size = 0; 42126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood struct stat s; 43126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood DIR *d; 44126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood struct dirent *de; 45126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood 46126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood d = fdopendir(dfd); 47126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood if (d == NULL) { 48126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood close(dfd); 49126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood return 0; 50126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood } 51126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood 52126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood while ((de = readdir(d))) { 53126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood const char *name = de->d_name; 54126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood if (fstatat(dfd, name, &s, AT_SYMLINK_NOFOLLOW) == 0) { 55126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood size += stat_size(&s); 56126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood } 57126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood if (de->d_type == DT_DIR) { 58126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood int subfd; 59126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood 60126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood /* always skip "." and ".." */ 61126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood if (name[0] == '.') { 62126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood if (name[1] == 0) 63126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood continue; 64126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood if ((name[1] == '.') && (name[2] == 0)) 65126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood continue; 66126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood } 67126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood 68126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY); 69126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood if (subfd >= 0) { 70126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood size += calculate_dir_size(subfd); 71126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood } 72126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood } 73126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood } 74126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood closedir(d); 75126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood return size; 76126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood} 77