[comp.unix.wizards] . file question

tedj@hpcilzb.HP.COM (Ted Johnson) (08/04/88)

When does the "." file, which describes the current directory,
get updated?  Only when you do an fsck?  

In the following example, I created a directory and make 2 files.
After deleting one of the files, the "." file thought that they
were both still there.  Is this a bug???

This is on HP-UX 6.01, ksh, running on an HP 9000/350.

-Ted

------------------------cut here--------------------------

Script started on Wed Aug  3 11:06:39 1988
hpcillm(tedj) 277>mkdir testdir
hpcillm(tedj) 278>cd testdir
./testdir
hpcillm(tedj) 279>strings .
hpcillm(tedj) 280>touch file1
hpcillm(tedj) 281>strings .
file1
hpcillm(tedj) 282>touch file2
hpcillm(tedj) 283>strings .
file1
file2
hpcillm(tedj) 284>rm file2
hpcillm(tedj) 285>strings .
file1
file2
hpcillm(tedj) 286>ls
file1
hpcillm(tedj) 287>exit

script done on Wed Aug  3 11:07:20 1988

chris@mimsy.UUCP (Chris Torek) (08/05/88)

In article <1670002@hpcilzb.HP.COM> tedj@hpcilzb.HP.COM (Ted Johnson) writes:
>When does the "." file, which describes the current directory,
>get updated?

Whenever it gets updated.  `.' is a *link* to that directory.  Any
change to that directory is reflected immediately, because the name `.'
resolves to that directory.

>hpcillm(tedj) 279>strings .
>hpcillm(tedj) 280>touch file1
 ...
>hpcillm(tedj) 282>touch file2
>hpcillm(tedj) 283>strings .
>file1
>file2
>hpcillm(tedj) 284>rm file2
>hpcillm(tedj) 285>strings .
>file1
>file2
>hpcillm(tedj) 286>ls
>file1
>hpcillm(tedj) 287>exit

As the `ls' shows, file2 has been deleted.  The directory has been
rewritten so that the `inode number' associated with the entry for
file2 is zero: this marks a free slot.  A free slot can have any
sort of trash in its name field, which is why one reads directories
with `readdir' or `ls' (portable readdir implementations are available
for those whose vendors fail to supply them; e.g., Doug Gwyn has one).
It just happens that the Unix system you have leaves the old name
there.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

rjd@occrsh.ATT.COM (Randy_Davis) (08/06/88)

In article <1670002@hpcilzb.HP.COM> tedj@hpcilzb.HP.COM (Ted Johnson) writes:
:
:When does the "." file, which describes the current directory,
:get updated?  Only when you do an fsck?  
:
:In the following example, I created a directory and make 2 files.
:After deleting one of the files, the "." file thought that they
:were both still there.  Is this a bug???

  No it didn't, the names just happened to still be in the file, but they
were marked as removed by setting the inode reference to zero, something that
the strings program will not show you.

:hpcillm(tedj) 279>strings .
:hpcillm(tedj) 280>touch file1
:hpcillm(tedj) 281>strings .
:file1
:hpcillm(tedj) 282>touch file2
:hpcillm(tedj) 283>strings .
:file1
:file2
:hpcillm(tedj) 284>rm file2
:hpcillm(tedj) 285>strings .
:file1
:file2
:hpcillm(tedj) 286>ls
:file1

Try "od -c .", if you have it.  It will show everything pertainent.

Randy

merlyn@intelob (Randal L. Schwartz @ Stonehenge) (08/06/88)

In article <1670002@hpcilzb.HP.COM>, tedj@hpcilzb (Ted Johnson) writes:
| 
| When does the "." file, which describes the current directory,
| get updated?  Only when you do an fsck?
[ ... ]
| Script started on Wed Aug  3 11:06:39 1988
| hpcillm(tedj) 277>mkdir testdir
| hpcillm(tedj) 278>cd testdir
| ./testdir
| hpcillm(tedj) 279>strings .
| hpcillm(tedj) 280>touch file1
| hpcillm(tedj) 281>strings .
| file1
| hpcillm(tedj) 282>touch file2
| hpcillm(tedj) 283>strings .
| file1
| file2
| hpcillm(tedj) 284>rm file2
| hpcillm(tedj) 285>strings .
| file1
| file2
| hpcillm(tedj) 286>ls
| file1

(Lezzeee if I can do this better than I did the ctime field, sheesh...)

A directory file (like the one referenced by ".") is not a text file.
In original UN*X (as DMR et. al. intended it :-), a directory
consisted of one or more 16-byte entries.  Each entry had two bytes
for an Inode number, and 14 bytes for the file name (null-padded on
the right if the name was shorter than 14 bytes).  When a file was
deleted, only the two Inode bytes had to be changed, to zero,
specifically, since the zero Inode was reserved.  But, the value of
the filename remained.

strings(1) ignores the presence or absence of the zero-inode
indication.  For more accurate results, repeat your example, but use
"od -c" every place you used "strings".  You'll see Inode numbers come
and go, the same way the UN*X kernel handles them.

(Well, gurus?  Can I keep my UNIX Driver's License card now?)

Yours for a better tomorrow,
-- 
Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095
on contract to BiiN Technical Publications (for now :-), Hillsboro, Oregon
<merlyn@intelob.intel.com> or ...!tektronix!ogcvax!omepd!intelob!merlyn
Standard disclaimer: I *am* my employer!

seindal@freja.dk (Rene' Seindal) (08/06/88)

In article <1670002@hpcilzb.HP.COM> tedj@hpcilzb.HP.COM (Ted Johnson) writes:

>When does the "." file, which describes the current directory,
>get updated?  Only when you do an fsck?  

>In the following example, I created a directory and make 2 files.
>After deleting one of the files, the "." file thought that they
>were both still there.  Is this a bug???

>This is on HP-UX 6.01, ksh, running on an HP 9000/350.

>-Ted

[long example deleted]

No.  It is not a bug.  Directories consist of (file-name, inode) pairs, and
when you delete a file, only the inode part gets cleared.  Therefore strings
will keep showing the name, at least until the directory slot is reused.

Try to create a file with a shorter name that the first.  That ought to
overwrite the name, because the slot would be reused.

Rene' Seindal, DIKU, U. of Copenhagen, Denmark. (seindal@diku.dk)

allbery@ncoast.UUCP (Brandon S. Allbery) (08/08/88)

As quoted from <1670002@hpcilzb.HP.COM> by tedj@hpcilzb.HP.COM (Ted Johnson):
+---------------
| In the following example, I created a directory and make 2 files.
| After deleting one of the files, the "." file thought that they
| were both still there.  Is this a bug???
| 
| hpcillm(tedj) 283>strings .
| file1
| file2
| hpcillm(tedj) 284>rm file2
| hpcillm(tedj) 285>strings .
| file1
| file2
| hpcillm(tedj) 286>ls
| file1
+---------------

A directory is an indexing mechanism for inodes, nothing more.  What you are
seeing with "strings" is only the ASCII portion of the directory; under non-
BSD directory formats, the actual representation of a file in a directory is:

	two-byte binary integer i-number
	14-character string filename

"Deleting" a file sets the i-number field to 0; this flags the entry as
reuseable, so doing a "touch ./file3" in that directory will reuse the slot
where file2 used to be.  This is needed because otherwise the kernel must
shift things around if you delete a file whose directory entry is in the
middle of the directory file, possibly having to shift many KB of data
around (granted, if that actually happens then the directory is for all
practical purposes overloaded, but many real-world (not to say RealWorld(tm)
;-) applications actually require this).  This is pretty much unacceptable
overhead, so the entry is merely marked for re-use later.

Berkeley UNIX does things a bit differently; under certain circumstances the
kernel will actually compact a directory (at least under 4.3BSD), but only
when it doesn't entail large amounts of overhead.  After all, how long do you
want to wait for the system to rm a file?

++Brandon
-- 
Brandon S. Allbery, uunet!marque!ncoast!allbery			DELPHI: ALLBERY
	    For comp.sources.misc send mail to ncoast!sources-misc

rbj@nav.icst.nbs.gov (Root Boy Jim) (08/12/88)

? When does the "." file, which describes the current directory,
? get updated?  Only when you do an fsck?  

? In the following example, I created a directory and make 2 files.
? After deleting one of the files, the "." file thought that they
? were both still there.  Is this a bug???

? hpcillm(tedj) 279>strings .

Your problem is your use of the `strings' command. Allow me to explain
the situation by lying a bit.

Once upon a time, directory entrys were 16 bytes long. Fourteen of these
characters were the file name, zero terminated if less than 14 chars.
The other two were the inode number *if nonzero*, or an `empty slot'
*if zero*. To remove an file from a directory, UNIX looks up the name,
gets the inode, unlinks the file, and then sets the inode in the directory
to zero. It *does not* do anything with the 14 char name field (why bother?).

To add a new file to a directory, the system gets a new inode, looks
for an empty slot (it extends the directory if none is found), and
stores the (inode number, filename) pair in the slot.

The above is still true on Berkeley based systems with the following
complications: directory entrys are variable sized, with appropriate
char counts of the name field to handle the new format.

BTW, fsck will not remove the names either as far as I know.

The `ls' command ignores empty slots, but `strings' will find old names.

	(Root Boy) Jim Cottrell	<rbj@icst-cmr.arpa>
	National Bureau of Standards
	Flamer's Hotline: (301) 975-5688
	The opinions expressed are solely my own
	and do not reflect NBS policy or agreement
	Careful with that VAX Eugene!