aboutsummaryrefslogtreecommitdiff
path: root/toys/posix/du.c
diff options
context:
space:
mode:
Diffstat (limited to 'toys/posix/du.c')
-rw-r--r--toys/posix/du.c282
1 files changed, 140 insertions, 142 deletions
diff --git a/toys/posix/du.c b/toys/posix/du.c
index 8013810c..68cf286d 100644
--- a/toys/posix/du.c
+++ b/toys/posix/du.c
@@ -1,6 +1,4 @@
-/* vi: set sw=4 ts=4:
- *
- * du.c - disk usage program.
+/* du.c - disk usage program.
*
* Copyright 2012 Ashwini Kumar <ak.ashwini@gmail.com>
*
@@ -9,45 +7,45 @@
USE_DU(NEWTOY(du, "d#<0hmlcaHkLsx", TOYFLAG_USR|TOYFLAG_BIN))
config DU
- bool "du"
- default y
- help
- usage: du [-d N] [-askxHLlmc] [file...]
-
- Estimate file space usage (default in unit of 512 blocks).
- -a Show all file sizes
- -H Follow symlinks on cmdline
- -L Follow all symlinks
- -k Show size in units of 1024.
- -s Show only the total Size for each file specified
- -x Estimate size only on the same device
- -c Print total size of all arguments
- -d N Limit output to directories (and files with -a) of depth < N
- -l Count sizes many times if hard linked
- -h Sizes in human readable format (e.g., 1K 243M 2G )
- -m Sizes in megabytes
+ bool "du"
+ default y
+ help
+ usage: du [-d N] [-askxHLlmc] [file...]
+
+ Estimate file space usage (default in unit of 512 blocks).
+ -a Show all file sizes
+ -H Follow symlinks on cmdline
+ -L Follow all symlinks
+ -k Show size in units of 1024.
+ -s Show only the total Size for each file specified
+ -x Estimate size only on the same device
+ -c Print total size of all arguments
+ -d N Limit output to directories (and files with -a) of depth < N
+ -l Count sizes many times if hard linked
+ -h Sizes in human readable format (e.g., 1K 243M 2G )
+ -m Sizes in megabytes
*/
#define FOR_du
#include "toys.h"
GLOBALS(
- long maxdepth;
- long depth;
- long *dirsum;
- long total;
- dev_t st_dev;
- struct arg_list *inodes;
+ long maxdepth;
+ long depth;
+ long *dirsum;
+ long total;
+ dev_t st_dev;
+ struct arg_list *inodes;
)
typedef struct node_size {
- struct dirtree *node;
- long size;
+ struct dirtree *node;
+ long size;
}node_size;
typedef struct inode_ent {
- ino_t ino;
- dev_t dev;
+ ino_t ino;
+ dev_t dev;
}inode_ent_t;
/*
@@ -56,18 +54,18 @@ typedef struct inode_ent {
char *make_pathproper(char *str)
{
- char *path = str;
- switch(strlen(str)) {
- case 1:
- if(str[0] == '.') path = xstrdup("./");
- break;
- case 2:
- if(str[0] == '.' && str[1] == '.') path = xstrdup("../");
- break;
- default:
- break;
- }
- return path;
+ char *path = str;
+ switch(strlen(str)) {
+ case 1:
+ if(str[0] == '.') path = xstrdup("./");
+ break;
+ case 2:
+ if(str[0] == '.' && str[1] == '.') path = xstrdup("../");
+ break;
+ default:
+ break;
+ }
+ return path;
}
/*
@@ -75,38 +73,38 @@ char *make_pathproper(char *str)
*/
void print(long size, char* name)
{
- unsigned long long tempsize = (unsigned long long)size * 512;
- unsigned long unit = 512;
- char *sizestr = NULL;
- if(TT.depth > TT.maxdepth) return;
- if(toys.optflags & FLAG_h) unit = 0;
- if(toys.optflags & FLAG_k) unit = 1024;
- if(toys.optflags & FLAG_m) unit = 1024*1024;
- sizestr = make_human_readable(tempsize, unit); //make human readable string, depending upon unit size.
- xprintf("%s\t%s\n",sizestr, name);
- free(sizestr);
+ unsigned long long tempsize = (unsigned long long)size * 512;
+ unsigned long unit = 512;
+ char *sizestr = NULL;
+ if(TT.depth > TT.maxdepth) return;
+ if(toys.optflags & FLAG_h) unit = 0;
+ if(toys.optflags & FLAG_k) unit = 1024;
+ if(toys.optflags & FLAG_m) unit = 1024*1024;
+ sizestr = make_human_readable(tempsize, unit); //make human readable string, depending upon unit size.
+ xprintf("%s\t%s\n",sizestr, name);
+ free(sizestr);
}
/*
- * free the inodes which are stored for hard link reference
+ * free the inodes which are stored for hard link reference
*/
void free_inodes(void *data)
{
- void *arg = ((struct arg_list*)data)->arg;
- if(arg) free(arg);
- free(data);
+ void *arg = ((struct arg_list*)data)->arg;
+ if(arg) free(arg);
+ free(data);
}
/*
* allocate and add a node to the list
*/
static void llist_add_inode(struct arg_list **old, void *data)
-{
- struct arg_list *new = xmalloc(sizeof(struct arg_list));
+{
+ struct arg_list *new = xmalloc(sizeof(struct arg_list));
- new->arg = (char*)data;
- new->next = *old;
- *old = new;
+ new->arg = (char*)data;
+ new->next = *old;
+ *old = new;
}
/*
@@ -114,14 +112,14 @@ static void llist_add_inode(struct arg_list **old, void *data)
*/
int is_inode_present(struct stat *st)
{
- struct arg_list *temparg = NULL;
- inode_ent_t *ent = NULL;
- if(!TT.inodes) return 0;
- for(temparg = TT.inodes; temparg; temparg = (struct arg_list *)temparg->next) {
- ent = (inode_ent_t*)temparg->arg;
- if(ent && ent->ino == st->st_ino && ent->dev == st->st_dev) return 1;
- }
- return 0;
+ struct arg_list *temparg = NULL;
+ inode_ent_t *ent = NULL;
+ if(!TT.inodes) return 0;
+ for(temparg = TT.inodes; temparg; temparg = (struct arg_list *)temparg->next) {
+ ent = (inode_ent_t*)temparg->arg;
+ if(ent && ent->ino == st->st_ino && ent->dev == st->st_dev) return 1;
+ }
+ return 0;
}
/*
@@ -129,66 +127,66 @@ int is_inode_present(struct stat *st)
*/
int do_du(struct dirtree *node)
{
- inode_ent_t *ino_details = NULL;
- node_size *nd = NULL;
- if(!dirtree_notdotdot(node)) return 0;
- if((toys.optflags & FLAG_x) && (TT.st_dev != node->st.st_dev)) //if file not on same device, don't count size
- return DIRTREE_RECURSE;
-
- if(!(toys.optflags & FLAG_l) && node->st.st_nlink > 1 && !node->extra) { //keeping reference for hard links
- if(is_inode_present(&node->st)) return DIRTREE_RECURSE;
- ino_details = xzalloc(sizeof(inode_ent_t));
- ino_details->ino = node->st.st_ino;
- ino_details->dev = node->st.st_dev;
- llist_add_inode(&TT.inodes, (void*)ino_details);
- }
+ inode_ent_t *ino_details = NULL;
+ node_size *nd = NULL;
+ if(!dirtree_notdotdot(node)) return 0;
+ if((toys.optflags & FLAG_x) && (TT.st_dev != node->st.st_dev)) //if file not on same device, don't count size
+ return DIRTREE_RECURSE;
- if(S_ISDIR(node->st.st_mode)) {
- if(!(node->extra && (long)((node_size*)(node->extra))->node == (long)node)) {
- nd = xzalloc(sizeof(node_size));
- nd->node = node;
- nd->size = 0;
- TT.dirsum = (long*)&(nd->size);
- node->extra = (long)nd;
- *TT.dirsum = 0;
- TT.depth++;
- return (DIRTREE_RECURSE|DIRTREE_COMEAGAIN | ((toys.optflags & FLAG_L) ? DIRTREE_SYMFOLLOW : 0)); //DIRTREE_COMEAGAIN to comeback and print the entry.
- }
- else if(node->extra) { //extra is set for a returning DIR entry.
- long offset = 0;
- nd = (node_size*)node->extra;
- offset = nd->size;
- nd->size += node->st.st_blocks;
- TT.depth--;
- if(!(toys.optflags & FLAG_s))
- print(*TT.dirsum, dirtree_path(node, NULL));
- if((node->parent) && (node->parent->extra)) {
- /* when returning from internal directory, get the saved size of the parent and continue from there */
- nd = (node_size*)node->parent->extra;
- TT.dirsum = (long*)&(nd->size);
- *TT.dirsum += offset;
- *TT.dirsum += node->st.st_blocks;
- return DIRTREE_RECURSE;
- }
- else if(!node->parent) {
- /*if node has no parent, it means it is the top in the tree, stop recursing here */
- TT.total += *TT.dirsum;
- if((toys.optflags & FLAG_s))
- print(*TT.dirsum, dirtree_path(node, NULL));
- return 0;
- }
- }
+ if(!(toys.optflags & FLAG_l) && node->st.st_nlink > 1 && !node->extra) { //keeping reference for hard links
+ if(is_inode_present(&node->st)) return DIRTREE_RECURSE;
+ ino_details = xzalloc(sizeof(inode_ent_t));
+ ino_details->ino = node->st.st_ino;
+ ino_details->dev = node->st.st_dev;
+ llist_add_inode(&TT.inodes, (void*)ino_details);
+ }
+
+ if(S_ISDIR(node->st.st_mode)) {
+ if(!(node->extra && (long)((node_size*)(node->extra))->node == (long)node)) {
+ nd = xzalloc(sizeof(node_size));
+ nd->node = node;
+ nd->size = 0;
+ TT.dirsum = (long*)&(nd->size);
+ node->extra = (long)nd;
+ *TT.dirsum = 0;
+ TT.depth++;
+ return (DIRTREE_RECURSE|DIRTREE_COMEAGAIN | ((toys.optflags & FLAG_L) ? DIRTREE_SYMFOLLOW : 0)); //DIRTREE_COMEAGAIN to comeback and print the entry.
}
- else if(!(node->parent)) {
- /* this is the file specified on cmdline */
- TT.total += node->st.st_blocks;
- print(node->st.st_blocks, dirtree_path(node, NULL));
+ else if(node->extra) { //extra is set for a returning DIR entry.
+ long offset = 0;
+ nd = (node_size*)node->extra;
+ offset = nd->size;
+ nd->size += node->st.st_blocks;
+ TT.depth--;
+ if(!(toys.optflags & FLAG_s))
+ print(*TT.dirsum, dirtree_path(node, NULL));
+ if((node->parent) && (node->parent->extra)) {
+ /* when returning from internal directory, get the saved size of the parent and continue from there */
+ nd = (node_size*)node->parent->extra;
+ TT.dirsum = (long*)&(nd->size);
+ *TT.dirsum += offset;
+ *TT.dirsum += node->st.st_blocks;
+ return DIRTREE_RECURSE;
+ }
+ else if(!node->parent) {
+ /*if node has no parent, it means it is the top in the tree, stop recursing here */
+ TT.total += *TT.dirsum;
+ if((toys.optflags & FLAG_s))
+ print(*TT.dirsum, dirtree_path(node, NULL));
return 0;
+ }
}
- if(TT.dirsum) *TT.dirsum += node->st.st_blocks;
- if(toys.optflags & FLAG_a && !(toys.optflags & FLAG_s))
- print(node->st.st_blocks, dirtree_path(node, NULL));
- return DIRTREE_RECURSE;
+ }
+ else if(!(node->parent)) {
+ /* this is the file specified on cmdline */
+ TT.total += node->st.st_blocks;
+ print(node->st.st_blocks, dirtree_path(node, NULL));
+ return 0;
+ }
+ if(TT.dirsum) *TT.dirsum += node->st.st_blocks;
+ if(toys.optflags & FLAG_a && !(toys.optflags & FLAG_s))
+ print(node->st.st_blocks, dirtree_path(node, NULL));
+ return DIRTREE_RECURSE;
}
/*
@@ -196,22 +194,22 @@ int do_du(struct dirtree *node)
*/
void du_main(void)
{
- int symfollow = toys.optflags & (FLAG_H | FLAG_L);
- TT.total = 0;
- TT.inodes = NULL;
-
- if(!(toys.optflags & FLAG_d)) TT.maxdepth = INT_MAX;
- if(toys.optc == 0) toys.optargs[0] = "./";
- while(*toys.optargs) {
- TT.depth = 0;
- char *path = make_pathproper(*toys.optargs);
- struct dirtree *root = dirtree_add_node(AT_FDCWD, path, symfollow); //create a node
- if(root) {
- TT.st_dev = root->st.st_dev;
- handle_callback(root, do_du); //this will recurse thru the DIR children.
- }
- toys.optargs++;
+ int symfollow = toys.optflags & (FLAG_H | FLAG_L);
+ TT.total = 0;
+ TT.inodes = NULL;
+
+ if(!(toys.optflags & FLAG_d)) TT.maxdepth = INT_MAX;
+ if(toys.optc == 0) toys.optargs[0] = "./";
+ while(*toys.optargs) {
+ TT.depth = 0;
+ char *path = make_pathproper(*toys.optargs);
+ struct dirtree *root = dirtree_add_node(AT_FDCWD, path, symfollow); //create a node
+ if(root) {
+ TT.st_dev = root->st.st_dev;
+ handle_callback(root, do_du); //this will recurse thru the DIR children.
}
- if(TT.inodes) llist_traverse(TT.inodes, free_inodes); //free the stored nodes
- if(toys.optflags & FLAG_c) print(TT.total, "total");
+ toys.optargs++;
+ }
+ if(TT.inodes) llist_traverse(TT.inodes, free_inodes); //free the stored nodes
+ if(toys.optflags & FLAG_c) print(TT.total, "total");
}