Trash spec 0.4

Alexander Larsson alexl at
Thu Sep 9 11:08:43 EEST 2004

On Thu, 2004-09-09 at 02:39 +0400, Mikhail Ramendik wrote:
> Hello,
> The Trash specification, version 0.4, is now available at:
> The main reason for the speedy release of a newversion is the Trash
> entry to Trash info change.

Comments on version 0.5:

> The $trash/info directory contains an information file for
> every file and directory in $trash/files. This file MUST have exactly
> the same name as the file or directory in $trash/files, plus the
> extension .trashinfo. 

I'm not sure about this. Adding 10 characters to the filename makes it
very likely to not fit in the filename length limit on many filesystems.
Do we really need the extension for this? 

> The system SHOULD only support absolute pathnames in the home
> trash directory, not in the directories under $topdir. 

Why is this? There are many cases where the relative pathname without
".." will not allow you to express all files on the mountpoint.

A common situation is if you have the fs mounted somewhere and use
symlinks into it. Say, filesystem on /mnt/hda2. Symlinks from /opt
to /mnt/hda2/opt. The trashdir would be /mnt/hda2/opt/.Trash, but the
trashed file /opt/filename, or ../../../opt/filename. We could resolve
the symlink, but the reason the opt symlink was created is to hide the
fact that its mounted on hda2. Maybe its a network filesystem mounted in
different places on different machines. 

Another problem is if someone uses --bind mounts instead of symlinks,
and in that case we cannot even resolve the real pathname.

> The value type for this key is localestring it should use
> the locale in which file names are stored on this file systems, or, if
> this is unknown, UTF-8. 

This is wrong, and cannot work. The encoding of a filename is
unknowable, and the locale for a file might differ between users,
sessions, etc. You also cannot convert a pathname to a different
encoding and expect it to work! If you change the name of one of the
directories to utf8 from say latin-1, you will put the file back in a
different place!

No, filenames are raw byte-stings without the slash character or the
zero byte, containing the exact bytes of the original filename. Anything
else will break. How to display the filename (i.e. convert it to
unicode) is up to the desktop, and each implementation already has code
to do this for normal files.

> When trashing a file or directory, the implementation SHOULD create
> the corresponding file in $trash/info first. Moreover, it SHOULD use
> O_EXCL when creating it. Before creating this file, or before trying
> again if the creation fails, the implementation should check whether a
> file with the same already exists; if so, the name should be
> changed. (This prevents a race condition if two processes try to trash
> files at the same time, and attempt to use the same file name.) 

Why do you describe this racy way to prevent race condition, and why do
you say SHOULD instead of MUST about O_EXCL, when that is the only way
to create a unique filename in a non-racy way?

The right algorithm is:

1. Make up a name you haven't tried before
2. open (filename, O_CREAT|O_EXCL, mode)
3. if the open failed with EEXIST, there was already a file with that
name. Goto 1.
4. Now you have a filedescriptor to a file that is atomically guaranteed
to not have existed before. (Or, the open failed for another reason,
such as out of space.)
5. Write the trashinfo file to the filedescriptor.
6. We're now guaranteed there is no file with the same name in the files
subdir, so move the trashed file there.

This also means the implementations *MUST* create the info files first.
Otherwise you're not guaranteed that after the info file is created
moving the trash file will not fail.

 Alexander Larsson                                            Red Hat, Inc 
                   alexl at    alla at 
He's a bookish vegetarian werewolf on a mission from God. She's a manipulative 
mute safe cracker with an MBA from Harvard. They fight crime! 

More information about the xdg mailing list