[Mono-dev] File.Copy on unix with symbolic link / atime and mtime / stat64

Jonathan Pryor jonpryor at vt.edu
Tue Mar 13 07:56:32 EDT 2007

On Mon, 2007-03-05 at 13:06 +0100, Lorenzo Delana wrote:
> OK, the paragon between two different OS view of a concept (.lnk and symlink) 
> that aren't the same thing is not correct,

No, really, they're not at all the same thing:


Look at the list of items that .lnk files permit.   Four of the items in
that list CANNOT be done with Unix-style symbolic links (FAT doesn't
support them, it makes NO sense to copy a symlink to a floppy disk,
their appearance cannot be customized unless you delve into the world of
alternate file streams, and you can't create a symlink to something that
isn't a file/directory, such as a network share, control panel applets,
dial-up networking connections, etc.)

And as Dick pointed out, Vista *has* Unix-style symbolic links, but you
need to be an administrator to even create them (!), and it allows such
(expected) "bizarreness" such as having a "directory" (symlink) on the
server point to a file on the local machine.

> If I copy a symlink I would to have a resulting symlink and not a resulting 
> dereferenced object, and to fix this I don't need to know nothing about 
> windows but only linux.

Then use the Mono.Unix APIs.  That's what they're for.

The System.IO APIs copy what .NET does, and since .NET runs on Windows,
and (until Vista) Windows doesn't support symbolic links, the current
behavior (dereference symlinks) is the only sensible solution.

What would be interesting to do is to see what .NET does on Vista when
it's given a symlink...

> 3)
> NOTE on Mono.Unix.Native.Stat the member st_size is of type off_t instead of 
> off64_t and the call used is stat and not stat64;

Mono.Unix.Native.Stat.st_size is a C# long, a 64-bit data type.  This is
off64_t for all intents and purposes.

The actual MonoPosixHelper source may use stat(2) instead of stat64(),
but the _FILE_OFFSET_BITS=64 macro is passed to the C compiler, which on
Linux causes stat(2) to be stat64(), so you're still using the stat64()
API.  `objdump -t libMonoPosixHelper.so` confirms that
__xstat64@@GLIBC_2.2 is imported.

> so if I use 
> Mono.Unix.UnixFileSystemInfo.GetFileStatus I will get an erroneus size for a 
> file that is bigger than 4gig.

I've just tested this, and UnixFileInfo.Length properly returns the file
size for files > 4GB:

        $ dir f.iso
        -rw-r--r-- 1 jon users 8020951040 2007-03-13 07:26 f.iso
        $ mono ~/tmp/mstat.exe f.iso
        Local Unix Epoch: 1970-01-01 00:00:00.000000 -05:00
        Current Time Zone: EDT
        Current Time Zone: EST
          File: `f.iso'
          Size: 8020951040       Blocks: 15681248   IO Block: 4096   unknown file type
        Device: 341h/833d        Inode: 12927141    Links: 1
        Access: (0644/-rw-r--r--)   Uid: (  500/     jon)   Gid: (  100/   users)
                   Protection: S_IROTH, S_IRGRP, S_IWUSR, S_IRUSR, S_IFREG
        FileAccessPermissions: OtherRead, GroupRead, UserWrite, UserRead
        FileSpecialAttributes: 0
                     FileType: RegularFile
        Access: 2007-03-13 07:17:27.000000 -04:00
        Modify: 2007-03-13 07:26:07.000000 -04:00
        Change: 2007-03-13 07:26:07.000000 -04:00

 - Jon

More information about the Mono-devel-list mailing list