Home Messages Index
[Date Prev][Date Next][Thread Prev][Thread Next]
Author IndexDate IndexThread Index

Re: [News] Moronic Error Messages in Windows

  • Subject: Re: [News] Moronic Error Messages in Windows
  • From: The Ghost In The Machine <ewill@xxxxxxxxxxxxxxxxxxxxxxx>
  • Date: Thu, 30 Nov 2006 16:18:51 -0800
  • Newsgroups: comp.os.linux.advocacy
  • References: <1488024.kuR4ZZdnM7@schestowitz.com> <456F54B1.2030603@bullet3.fsnet.oc.ku>
  • User-agent: slrn/0.9.8.1 (Linux)
  • Xref: news.mcc.ac.uk comp.os.linux.advocacy:1189128
In comp.os.linux.advocacy, Robert Newson
<ReapNewsB@xxxxxxxxxxxxxxxxxxx>
 wrote
on Thu, 30 Nov 2006 21:56:05 GMT
<456F54B1.2030603@xxxxxxxxxxxxxxxxxxx>:
> Roy Schestowitz wrote:
>
>> No, not just meaningless hexadecimal codes in a blue screen...
>> 
>> Windows: "Cannot remove folder because it's not empty."
>
> $ cd /tmp
> $ mkdir fred
> $ touch fred/bloggs
> $ rmdir fred
> rmdir: fred: Directory not empty
>
> Looks like Windwos has caught up with *nix...
>
> [PS fixed on * nix dead easy:
>
> $ rm -fr fred
> $ ls fred
> ls: fred: No such file or directory
>
> so not really an issue...Windwos normally can't delete something if its open 
> - no problem under *nix.]

Actually, it's a bit more subtle than that; Linux can't
delete something that's open either.  What Linux does (and
Unix did before it), is, when one uses the 'rm' command
(or unlink()) the directory entry for the given item
(a name holding an inode) is removed, basically hiding
the still-open file from view, and deleting it when no
one is provably using it.  Inodes, in this context, are
where all the data is, except for the access name/pathname.

rm -r is a recursive unlink; if rm -r encounters a directory,
it attempts to recursively delete everything underneath the
directory first.  (This could be a problem if the subdirectory
is busily being populated with files from another program.)

One can represent it this way.  (This is an strace-like syntax.)

mkdir("scratch") = 0;
open("scratch/myfile", O_WRONLY|O_CREAT, 0600) = 3;
write(3, "blah blah...", 1024) = 1024;
unlink("scratch/myfile") = 0;
rmdir("scratch") = 0;
close(3) = 0;

Let's dig down a little further.

mkdir("scratch") = 0;

This works more or less as expected; I'm creating a scratch directory
just to simplify things.  Note that '0' is the generic success code
in Unix -- pure convention.  [*]

open("scratch/myfile", O_WRONLY|O_CREAT) = 3;

This creates an inode and a directory entry in scratch pointing to it.
The inode has use count 2 (scratch is holding onto it, and so is the
file descriptor #3 in the current process).

write(3, "blah blah...", 1024) = 1024;

Scribbling onto the open file; 1024 bytes were successfully written.

unlink("scratch/myfile") = 0;

This removes the entry in the scratch subdirectory,
*but the file is still on disk and is still open*.
However, Linux keeps track of its usecount, which is now 1;
a call to fstat() can be used to verify this.

The inode is also unnamed (although inodes really don't
have names anyway).  Without specialized code (or fork())
other processes would have a lot of trouble finding this
file, but it's there.

rmdir("scratch") = 0;

Scratch is now no more, but the file is still out there.

close(3) = 0;

The file is closed and its usecount decremented.
The usecount is now 0, and only now is the disk space
reclaimed -- and I'm not even sure of that, as journaling
is presumably involved on ext3, reiserfs, and jfs.
However, the rest of the system can probably behave as
though the space is there, as the journal will allow for
the space reclaimation at the proper time -- before new
blocks are allocated for a new file object needing them.

If one were to do the following:

mkdir("scratch") = 0;
open("scratch/myfile", O_WRONLY|O_CREAT, 0600) = 3;
write(3, "blah blah...", 1024) = 1024;
unlink("scratch/myfile") = 0;
open("scratch/myfile", O_WRONLY|O_CREAT, 0600) = 4;
unlink("scratch/myfile") = 0;
rmdir("scratch") = 0;

one would now have *two* unnnamed inodes open.  Windows would take
one look at this sequence and run screaming, losing its pants in
the process... :-)  (Not that it would do all that well with the
first sequence.)

Fork()s make life interesting; I'd have to study the details.
Basically, after a fork, file descriptor #3 is open in both
child and parent.  Since fork()s are very common the kernel
hopefully does the right thing.

Hardlinks are also possible, if the entries are on the
same partition; if a file has been hardlinked to another
name entry, both name entries now point to the same inode,
and the link count should be the number of names pointing
to it, plus the number of successful opens of that file.

One can create a file, hardlink another name to that file,
and delete the original name -- and Linux wouldn't be able
to tell the difference between that sequence and a sequence
creating the second name in the first place.  (This is
somewhat distinct from the Amiga, which used a different
record type in its filesystem to represent a hard link.)

There are also symlinks, which in Linux (IIRC) are
represented by putting the symlink text in an inode
descriptor.  If the text is too long a data block or two
might be allocated as well.  As far as the application
program is concerned it's readlink() and symlink(), and
magic happens.

Inodes are very straightforward locking at the kernel level
and very flexible at the application level.  It might be
a bit confusing at the newbie level but Unix got it right
long ago.  Microsoft botched it by using .LNK hacks,
which are only interpretable by Internet Explorer, but
do allow for searching.  (Gnome and KDE have a similar
concept of more limited scope; the .desktop file looks to
be a mixture of .LNK and .PIF.)

>
>> ,----[ Quote ]
>> | It cannot remove the folder, true. The directory is not empty, that's
>> | also correct. But the directory not being empty doesn't quite seem like
>> | a valid reason for not being able to remove it.
>
> Normally Windwos asks if I want the folder and its contents to be moved to 
> the recycle bin (at which point I scream, click No & re-issue the delete 
> whilst holding down the shift key...).
>

Nothing like Windows convenience. :-)

[*] VAX/VMS had a more complicated return strategy,
basically allowing for the return of an arbitrary
status code.  Odd status codes indicated success; even
status codes indicated warnings or failures.  0x44, for
instance, was %SYSTEM-F-ABORT if memory serves; 0x01 was
%SYSTEM-S-SUCCESS.  Needless to say, there were some issues
between VMS and C at one point -- complicated further by
the existence of two C compilers for VMS.

-- 
#191, ewill3@xxxxxxxxxxxxx
Useless C++ Programming Idea #2239120:
void f(char *p) {char *q = p; strcpy(p,q); }

-- 
Posted via a free Usenet account from http://www.teranews.com


[Date Prev][Date Next][Thread Prev][Thread Next]
Author IndexDate IndexThread Index