4 ms·
After staring at the listing for a while, I think it is a kind of garbage collector for removing unlinked files from directory listings ("pack directory"?). As
by Pete_D 7y ago
After staring at the listing for a while, I think it is a kind of garbage collector for removing unlinked files from directory listings ("pack directory"?). As best as I can work out, the code does:
open ..
loop
read a directory entry into tbuf
if we read 0 bytes (eof presumably), break loop
if tbuf[0] == '\0', go back to start of loop
append tbuf to dir
done
close ..
reopen .. with creat
write the stuff we built up into dir to ..
close ..
exit
- saagarjha 7y agoLooking at this again, your psuedocode seems to be pretty reasonable. However, I'm still left wondering why this command would be necessary: doesn't it just read the directory entry into memory and write it back out again? I'm also curious why "sys write" takes .. directly when all the other calls seem to need dotdot.
- Pete_D 7y agoIf my reading is right, it filters out any with a leading null-byte before writing back out. My guess is that that is how they implemented unlink/rm - just write zeroes over the entry. As for the sys write: my current hypothesis is that .. there is a placeholder for an argument which is written to by the preceding dac .+4. ('"If a program can't rewrite its own code", he asked, "what good is it?"'). But I can't make sense of what it's actually putting there - I'd guess length, but it looks like ~(dir - 2) + 8.
- kps 7y ago> but it looks like ~(dir - 2) + 8. That took me a while. The ‘8’ in ‘tad 8' is the contents of memory location 8, i.e. the destination pointer in the memory copy, so it's ~(dir - 2) + dst. And since -x = ~x + 1 (there being no negation instruction), that works out to the length, dst - dir + 1.
- microtherion 7y agoMaurice Bach, "The Design of the UNIX Operating System", on page 73 describes the format of directory entries: https://archive.org/details/DesignOfTheUnixOperatingSystemByMauriceBach/page/n85 https://archive.org/details/DesignOfTheUnixOperatingSystemBy... "Directory entries may be empty, indicated by an inode number of 0". So if the pseudo-code is correct, this may be an utility to squeeze out those empty entries.
- kps 7y agoI think you're right. My C-ish translation (that ignores errors) is: int dst /*8*/, src /*9*/, c1, df, tbuf[8], dir[BIG]; char dotdot[] = ".. "; df = open(dotdot, O_RDONLY); dst = dir - 1; while (read(df, tbuf, 8) != 0) { if (tbuf[0] != 0) { c1 = -8; src = tbuf - 1; do { *++dst = *++src; } while (++c1 != 0); } } close(df); df = creat(dotdot); write(df, dir, dst - dir + 1); close(df); exit(); That is, copy any directory entry with a non-zero inode into dir[], and then write that back. Pack Directory. According to https://wiki.tuhs.org/doku.php?id=systems:pdp7_unix https://wiki.tuhs.org/doku.php?id=systems:pdp7_unix ‘..’ was the name of the current directory (i.e. what is now ‘.’), so this operated on the current directory.