user/rm.c
About this file
rm name ... removes each name from its directory with the unlink system call
(sys_unlink). Removing a name is not quite the same as deleting a file. A file
can have several names (hard links, made by user/ln.c); unlink
removes one of them and decrements the inode’s link count (nlink). The file’s blocks are
freed only when no name is left and no process has it open: iput checks both
when the last reference is dropped.
xv6’s rm also removes directories, as long as they are empty (Unix rm refuses unless
given -r or -d; there is also a separate rmdir). It cannot remove . or ...
Read before: user/mkdir.c, which has the same structure. Read next:
user/ln.c.
Headers
user/user.h declares unlink. kernel/stat.h is not used.
At least one name is required
With no name after the program name, print a usage message on standard error and exit with status 1 (exit status).
Unlink each name, stopping at the first failure
In the kernel, sys_unlink finds the parent directory and the entry,
refuses . and .., refuses a directory that still contains entries other than .
and .. (isdirempty), then overwrites the directory entry with zeros
(which is why ls skips entries with inode number 0) and decrements the inode’s
link count. All of it happens in one transaction, so after a crash the name is
either fully there or fully gone. unlink returns -1 if the name does not exist or
one of these checks fails.
As in user/mkdir.c, the first failure is reported and ends the loop, so later
names are left alone, and the program still exits with status 0.
Remove the name argv[i] (sys_unlink). This frees the file’s data only if
it was the last name and the file is not open anywhere.
Name the path that could not be removed, on standard error.
Stop: the remaining names are skipped.
Exit with status 0, even after a failure.