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

Lorenzo Delana lorenzo.delana at gmail.com
Mon Mar 5 07:06:12 EST 2007


Alle 11:27, lunedì 05 marzo 2007, Dick Porter ha scritto:
> On Mon, 2007-03-05 at 07:31 +0100, lorenzo wrote:
> > I'm developing a backup utility and this involves the use of File.Copy
> > static method to make a copy of a file to another file.
> >
> > On Windows:
> > a link to another file or directory ( the .lnk extension file ) is copied
> > as is to destination.
> >
> > On Linux:
> > a link to another file or directory ( the symlink ) is dereferenced and
> > the destination result in the dereferenced file or directory.
> >
> > Why is used this implementation of the File.Copy w/symlink on Unix?
> > The application work very different if I execute the same IL code on
> > different platform. Is necessary to mantain this different behavior?
>
> POSIX symlinks and windows lnk files are two completely different
> concepts.  In fact, I believe the latest version of windows has support
> for symlinks too.  See
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/
>symbolic_link_effects_on_file_systems_functions.asp
>
> (I don't think we completely match the behaviour of the MS runtime wrt
> symlinks, and fixing it would require figuring out how they map the .net

OK, the paragon between two different OS view of a concept (.lnk and symlink) 
that aren't the same thing is not correct, but serve me to expose a problem 
related essentially to Linux only UNIX systems.

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.
First of all we have to accord that a copy of a symlink should be a symlink, 
after this we can see the rest of this message.

Checking the source of mono in file -> mcs/class/File.cs
function Copy (src,dest,overwrite):

                        if (!MonoIO.CopyFile (src, dest, overwrite, out 
error)){
                                string p = Locale.GetText ("{0}\" or \"{1}", 
src, dest);
                                throw MonoIO.GetException (p, error);
                        }

this piece of code indicate the call of MonoIO.CopyFile that is in file -> 
mono/io-layer/io.c
function CopyFile (name,dest_name,fail_if_exists):

in this piece of code you use a unix copy operation allocation a buffer of 
size st_blksize from stat info. So you can use the S_ISLNK(m) macro to check 
if the file is a symlink and then use symlink(oldpath,newpath) to create the 
symlink using the readlink(path,buf,bufsize) to check the link pointed to by 
the source file symlink.

2)
As in my email with subject "File.Copy Modify/Access time file attribute" I 
stated another problem that can be fixed always in that io.c code setting the 
modification/access time of the file created using the access time of the 
file created and modification time of the source file using 
utime(filename,buf) and having in this manner the bahvior of "cp -p" linux 
program.

In synthesis all of these two arguments ( symlink and modify time on copying 
of a file ) are argument subject to an arbitrary interpretation? or we can 
find a specification reference?

In any case we can choose a behavior that makes the same result on different 
platform to let be more simpler the porting.

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; so if I use 
Mono.Unix.UnixFileSystemInfo.GetFileStatus I will get an erroneus size for a 
file that is bigger than 4gig.

> calls to the windows system calls.)
>
> > Is there another solution to make a symlink copied as a symlink without
> > using Mono.Unix libraries?
>
> Not at the moment.
>
> - Dick

bye,
lorenzo



More information about the Mono-devel-list mailing list