📄 du.c
字号:
size = (size + 1) / 2;
#endif
}
if ((stat_buf.st_mode & S_IFMT) == S_IFDIR)
{
unsigned pathlen;
dev_t dir_dev;
char *name_space;
char *namep;
dir_dev = stat_buf.st_dev;
if (opt_one_file_system && !top && last_dev != dir_dev)
return 0; /* Don't enter a new file system. */
if (chdir (ent) < 0)
{
error (0, errno, "cannot change to directory %s", path->text);
return 0;
}
errno = 0;
name_space = savedir (".", stat_buf.st_size);
if (name_space == NULL)
{
if (errno)
{
error (0, errno, "%s", path->text);
chdir (".."); /* Try to return to previous directory. */
return 0;
}
else
error (1, 0, "virtual memory exhausted");
}
/* Remember the current path. */
str_concatc (path, "/");
pathlen = path->length;
namep = name_space;
while (*namep != 0)
{
str_concatc (path, namep);
size += count_entry (namep, 0, dir_dev);
str_trunc (path, pathlen);
namep += strlen (namep) + 1;
}
free (name_space);
chdir ("..");
if (!opt_summarize_only || top)
{
printf ("%ld\t%s\n", output_size == size_bytes ? size
: convert_blocks (size, output_size == size_kilobytes),
path->text);
fflush (stdout);
}
}
else if (opt_all || top)
{
printf ("%ld\t%s\n", output_size == size_bytes ? size
: convert_blocks (size, output_size == size_kilobytes),
path->text);
fflush (stdout);
}
return size;
}
/* Allocate space for the hash structures, and set the global
variable `htab' to point to it. The initial hash module is specified in
MODULUS, and the number of entries are specified in ENTRY_TAB_SIZE. (The
hash structure will be rebuilt when ENTRY_TAB_SIZE entries have been
inserted, and MODULUS and ENTRY_TAB_SIZE in the global `htab' will be
doubled.) */
void
hash_init (modulus, entry_tab_size)
unsigned modulus;
unsigned entry_tab_size;
{
struct htab *htab_r;
htab_r = (struct htab *)
xmalloc (sizeof (struct htab) + sizeof (struct entry *) * modulus);
htab_r->entry_tab = (struct entry *)
xmalloc (sizeof (struct entry) * entry_tab_size);
htab_r->modulus = modulus;
htab_r->entry_tab_size = entry_tab_size;
htab = htab_r;
hash_reset ();
}
/* Reset the hash structure in the global variable `htab' to
contain no entries. */
void
hash_reset ()
{
int i;
struct entry **p;
htab->first_free_entry = 0;
p = htab->hash;
for (i = htab->modulus; i > 0; i--)
*p++ = NULL;
}
/* Insert an item (inode INO and device DEV) in the hash
structure in the global variable `htab', if an entry with the same data
was not found already. Return zero if the item was inserted and non-zero
if it wasn't. */
int
hash_insert (ino, dev)
ino_t ino;
dev_t dev;
{
struct htab *htab_r = htab; /* Initially a copy of the global `htab'. */
if (htab_r->first_free_entry >= htab_r->entry_tab_size)
{
int i;
struct entry *ep;
unsigned modulus;
unsigned entry_tab_size;
/* Increase the number of hash entries, and re-hash the data.
The method of shrimping and increasing is made to compactify
the heap. If twice as much data would be allocated
straightforwardly, we would never re-use a byte of memory. */
/* Let `htab' shrimp. Keep only the header, not the pointer vector. */
htab_r = (struct htab *)
xrealloc ((char *) htab_r, sizeof (struct htab));
modulus = 2 * htab_r->modulus;
entry_tab_size = 2 * htab_r->entry_tab_size;
/* Increase the number of possible entries. */
htab_r->entry_tab = (struct entry *)
xrealloc ((char *) htab_r->entry_tab,
sizeof (struct entry) * entry_tab_size);
/* Increase the size of htab again. */
htab_r = (struct htab *)
xrealloc ((char *) htab_r,
sizeof (struct htab) + sizeof (struct entry *) * modulus);
htab_r->modulus = modulus;
htab_r->entry_tab_size = entry_tab_size;
htab = htab_r;
i = htab_r->first_free_entry;
/* Make the increased hash table empty. The entries are still
available in htab->entry_tab. */
hash_reset ();
/* Go through the entries and install them in the pointer vector
htab->hash. The items are actually inserted in htab->entry_tab at
the position where they already are. The htab->coll_link need
however be updated. Could be made a little more efficient. */
for (ep = htab_r->entry_tab; i > 0; i--)
{
hash_insert2 (htab_r, ep->ino, ep->dev);
ep++;
}
}
return hash_insert2 (htab_r, ino, dev);
}
/* Insert INO and DEV in the hash structure HTAB, if not
already present. Return zero if inserted and non-zero if it
already existed. */
int
hash_insert2 (htab, ino, dev)
struct htab *htab;
ino_t ino;
dev_t dev;
{
struct entry **hp, *ep2, *ep;
hp = &htab->hash[ino % htab->modulus];
ep2 = *hp;
/* Collision? */
if (ep2 != NULL)
{
ep = ep2;
/* Search for an entry with the same data. */
do
{
if (ep->ino == ino && ep->dev == dev)
return 1; /* Found an entry with the same data. */
ep = ep->coll_link;
}
while (ep != NULL);
/* Did not find it. */
}
ep = *hp = &htab->entry_tab[htab->first_free_entry++];
ep->ino = ino;
ep->dev = dev;
ep->coll_link = ep2; /* `ep2' is NULL if no collision. */
return 0;
}
/* Initialize the struct string S1 for holding SIZE characters. */
void
str_init (s1, size)
string *s1;
unsigned size;
{
string s;
s = (string) xmalloc (sizeof (stringstruct));
s->text = xmalloc (size + 1);
s->alloc = size;
*s1 = s;
}
static void
ensure_space (s, size)
string s;
unsigned size;
{
if (s->alloc < size)
{
s->text = xrealloc (s->text, size + 1);
s->alloc = size;
}
}
/* Assign the null-terminated C-string CSTR to S1. */
void
str_copyc (s1, cstr)
string s1;
char *cstr;
{
unsigned l = strlen (cstr);
ensure_space (s1, l);
strcpy (s1->text, cstr);
s1->length = l;
}
void
str_concatc (s1, cstr)
string s1;
char *cstr;
{
unsigned l1 = s1->length;
unsigned l2 = strlen (cstr);
unsigned l = l1 + l2;
ensure_space (s1, l);
strcpy (s1->text + l1, cstr);
s1->length = l;
}
/* Truncate the string S1 to have length LENGTH. */
void
str_trunc (s1, length)
string s1;
unsigned length;
{
if (s1->length > length)
{
s1->text[length] = 0;
s1->length = length;
}
}
/* Allocate N bytes of memory dynamically, with error checking. */
char *
xmalloc (n)
unsigned n;
{
char *p;
p = malloc (n);
if (p == 0)
error (1, 0, "virtual memory exhausted");
return p;
}
/* Change the size of an allocated block of memory P to N bytes,
with error checking.
If P is NULL, run xmalloc.
If N is 0, run free and return NULL. */
char *
xrealloc (p, n)
char *p;
unsigned n;
{
if (p == 0)
return xmalloc (n);
if (n == 0)
{
free (p);
return 0;
}
p = realloc (p, n);
if (p == 0)
error (1, 0, "virtual memory exhausted");
return p;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -