FileReference>>#moveTo: across filesystems

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

FileReference>>#moveTo: across filesystems

Claudio Corrodi
Hi all,

Manuel Leuenberger and I ran into an issue with the
FileReference>>#moveTo: method last week. On my system, I have "/" and
"/home" in two different partitions/file systems. If I do something like
the following, Pharo complains with a PrimitiveFailed signal:

'/tmp/aFile.txt' asFileReference moveTo: '/home/claudio/aFile.txt'
asFileReference

I do not know how this is implemented exactly, but assume that the
"rename" syscall is used (on Linux systems, that is), which does not
work across file systems. The issue does not arise if I moveTo: inside
the same filesystem.

Is this expected behaviour? It is not obvious (to me) that
FileReference>>#moveTo: requires source and target to be on the same
filesystem. It would therefore make more sense to me if there were a
fallback that copies and deletes if two filesystems are involved (much
like "mv" behaves).

What do you think?

Cheers,
Claudio

Reply | Threaded
Open this post in threaded view
|

Re: FileReference>>#moveTo: across filesystems

alistairgrant
Hi Claudio,

On 13 November 2017 at 18:49, Claudio Corrodi <[hidden email]> wrote:

> Hi all,
>
> Manuel Leuenberger and I ran into an issue with the FileReference>>#moveTo:
> method last week. On my system, I have "/" and "/home" in two different
> partitions/file systems. If I do something like the following, Pharo
> complains with a PrimitiveFailed signal:
>
> '/tmp/aFile.txt' asFileReference moveTo: '/home/claudio/aFile.txt'
> asFileReference
>
> I do not know how this is implemented exactly, but assume that the "rename"
> syscall is used (on Linux systems, that is), which does not work across file
> systems. The issue does not arise if I moveTo: inside the same filesystem.
>
> Is this expected behaviour? It is not obvious (to me) that
> FileReference>>#moveTo: requires source and target to be on the same
> filesystem. It would therefore make more sense to me if there were a
> fallback that copies and deletes if two filesystems are involved (much like
> "mv" behaves).
>
> What do you think?
>
> Cheers,
> Claudio

This issue was fixed some time ago.  I'm having trouble finding the
fogbugz issue, but it is definitely fixed in Pharo 7.  Would you
please let me know which build of Pharo you are using, and take a look
at FileSystem>>move:to: and compare it to (minus the formatting
changes :-)):

move: sourcePath to: destination
"Move the file /directory referenced as sourcePath to the destination
referred as destPath.
If there is no file at sourcePath, raise FileDoesNotExist.
If destPath is a file, raise FileExists.
If destPath is a directory, move the sourcePath in to the directory"

| fullDestination |

destination isFile ifTrue: [ FileExists signalWith: destination ].
destination isDirectory
ifTrue: [ fullDestination := destination / sourcePath basename ]
ifFalse: [ fullDestination := destination ].
self = destination fileSystem ifTrue:
[
"Ideally we would test whether the source and destination are on the
same filesystem from the OSs perspective.
Since we can't do that, just try rename, and if that fails, copy and delete."
[ self rename: sourcePath to: fullDestination resolve path ]
on: Error
do: [ :error | self copyAndDelete: sourcePath to: fullDestination ].
] ifFalse:
[ self copyAndDelete: sourcePath to: fullDestination ].
^fullDestination


Cheers,
Alistair

Reply | Threaded
Open this post in threaded view
|

Re: FileReference>>#moveTo: across filesystems

Stephane Ducasse-3
This is great to see FileSystem improving.

On Mon, Nov 13, 2017 at 7:11 PM, Alistair Grant <[hidden email]> wrote:

> Hi Claudio,
>
> On 13 November 2017 at 18:49, Claudio Corrodi <[hidden email]> wrote:
>> Hi all,
>>
>> Manuel Leuenberger and I ran into an issue with the FileReference>>#moveTo:
>> method last week. On my system, I have "/" and "/home" in two different
>> partitions/file systems. If I do something like the following, Pharo
>> complains with a PrimitiveFailed signal:
>>
>> '/tmp/aFile.txt' asFileReference moveTo: '/home/claudio/aFile.txt'
>> asFileReference
>>
>> I do not know how this is implemented exactly, but assume that the "rename"
>> syscall is used (on Linux systems, that is), which does not work across file
>> systems. The issue does not arise if I moveTo: inside the same filesystem.
>>
>> Is this expected behaviour? It is not obvious (to me) that
>> FileReference>>#moveTo: requires source and target to be on the same
>> filesystem. It would therefore make more sense to me if there were a
>> fallback that copies and deletes if two filesystems are involved (much like
>> "mv" behaves).
>>
>> What do you think?
>>
>> Cheers,
>> Claudio
>
> This issue was fixed some time ago.  I'm having trouble finding the
> fogbugz issue, but it is definitely fixed in Pharo 7.  Would you
> please let me know which build of Pharo you are using, and take a look
> at FileSystem>>move:to: and compare it to (minus the formatting
> changes :-)):
>
> move: sourcePath to: destination
> "Move the file /directory referenced as sourcePath to the destination
> referred as destPath.
> If there is no file at sourcePath, raise FileDoesNotExist.
> If destPath is a file, raise FileExists.
> If destPath is a directory, move the sourcePath in to the directory"
>
> | fullDestination |
>
> destination isFile ifTrue: [ FileExists signalWith: destination ].
> destination isDirectory
> ifTrue: [ fullDestination := destination / sourcePath basename ]
> ifFalse: [ fullDestination := destination ].
> self = destination fileSystem ifTrue:
> [
> "Ideally we would test whether the source and destination are on the
> same filesystem from the OSs perspective.
> Since we can't do that, just try rename, and if that fails, copy and delete."
> [ self rename: sourcePath to: fullDestination resolve path ]
> on: Error
> do: [ :error | self copyAndDelete: sourcePath to: fullDestination ].
> ] ifFalse:
> [ self copyAndDelete: sourcePath to: fullDestination ].
> ^fullDestination
>
>
> Cheers,
> Alistair
>

Reply | Threaded
Open this post in threaded view
|

Re: FileReference>>#moveTo: across filesystems

alistairgrant
In reply to this post by alistairgrant
On 13 November 2017 at 19:11, Alistair Grant <[hidden email]> wrote:

> Hi Claudio,
>
> On 13 November 2017 at 18:49, Claudio Corrodi <[hidden email]> wrote:
>> Hi all,
>>
>> Manuel Leuenberger and I ran into an issue with the FileReference>>#moveTo:
>> method last week. On my system, I have "/" and "/home" in two different
>> partitions/file systems. If I do something like the following, Pharo
>> complains with a PrimitiveFailed signal:
>>
>> '/tmp/aFile.txt' asFileReference moveTo: '/home/claudio/aFile.txt'
>> asFileReference
>>
>> I do not know how this is implemented exactly, but assume that the "rename"
>> syscall is used (on Linux systems, that is), which does not work across file
>> systems. The issue does not arise if I moveTo: inside the same filesystem.
>>
>> Is this expected behaviour? It is not obvious (to me) that
>> FileReference>>#moveTo: requires source and target to be on the same
>> filesystem. It would therefore make more sense to me if there were a
>> fallback that copies and deletes if two filesystems are involved (much like
>> "mv" behaves).
>>
>> What do you think?
>>
>> Cheers,
>> Claudio
>
> This issue was fixed some time ago.  I'm having trouble finding the
> fogbugz issue, but it is definitely fixed in Pharo 7.


For future reference: https://pharo.fogbugz.com/f/cases/20172



> Would you
> please let me know which build of Pharo you are using, and take a look
> at FileSystem>>move:to: and compare it to (minus the formatting
> changes :-)):
>
> move: sourcePath to: destination
> "Move the file /directory referenced as sourcePath to the destination
> referred as destPath.
> If there is no file at sourcePath, raise FileDoesNotExist.
> If destPath is a file, raise FileExists.
> If destPath is a directory, move the sourcePath in to the directory"
>
> | fullDestination |
>
> destination isFile ifTrue: [ FileExists signalWith: destination ].
> destination isDirectory
> ifTrue: [ fullDestination := destination / sourcePath basename ]
> ifFalse: [ fullDestination := destination ].
> self = destination fileSystem ifTrue:
> [
> "Ideally we would test whether the source and destination are on the
> same filesystem from the OSs perspective.
> Since we can't do that, just try rename, and if that fails, copy and delete."
> [ self rename: sourcePath to: fullDestination resolve path ]
> on: Error
> do: [ :error | self copyAndDelete: sourcePath to: fullDestination ].
> ] ifFalse:
> [ self copyAndDelete: sourcePath to: fullDestination ].
> ^fullDestination
>
>
> Cheers,
> Alistair