How does the mv command work with external drives? The Next CEO of Stack OverflowHow can the 'mail' command be used?How can I remove the Mac recovery partition from an external drive?How do I write-protect a partition of a USB drive on OSX that can work cross-platform?Fixing my external hard drive's partition mapExternal hard drive : Problems were found with the partition mapIs it possible or likely for malware or a virus to be transferred by plugging a USB hard drive into my Mac?can i use migration assistant to migrate files to a secondary drive?Mounting an external hard disk clone that shares the same partition GUIDs as the source/host hard diskMake Time Machine use two drives from TerminalWhat is the most efficient and reliable method for transfering/copying a large number of files from one external hard drive to another?
Won the lottery - how do I keep the money?
Would a galaxy be visible from outside, but nearby?
Complex fractions
Do I need to enable Dev Hub in my PROD Org?
How to prove the convergence of the following series
Why do we use the plural of movies in this phrase "We went to the movies last night."?
WOW air has ceased operation, can I get my tickets refunded?
Does it take more energy to get to Venus or to Mars?
Workaholic Formal/Informal
Giving the same color to different shapefiles in QGIS
What happened in Rome, when the western empire "fell"?
Skipping indices in a product
Is it professional to write unrelated content in an almost-empty email?
Example of a Mathematician/Physicist whose Other Publications during their PhD eclipsed their PhD Thesis
How do I go from 300 unfinished/half written blog posts, to published posts?
Is it possible to search for a directory/file combination?
Is there a difference between "Fahrstuhl" and "Aufzug"
Indicator light circuit
What is the purpose of the Evocation wizard's Potent Cantrip feature?
How to log in to Centos 7 using RDP from Win10
Elegant way to replace substring in a regex with optional groups in Python?
Why do remote companies require working in the US?
Why is there a PLL in CPU?
How to safely derail a train during transit?
How does the mv command work with external drives?
The Next CEO of Stack OverflowHow can the 'mail' command be used?How can I remove the Mac recovery partition from an external drive?How do I write-protect a partition of a USB drive on OSX that can work cross-platform?Fixing my external hard drive's partition mapExternal hard drive : Problems were found with the partition mapIs it possible or likely for malware or a virus to be transferred by plugging a USB hard drive into my Mac?can i use migration assistant to migrate files to a secondary drive?Mounting an external hard disk clone that shares the same partition GUIDs as the source/host hard diskMake Time Machine use two drives from TerminalWhat is the most efficient and reliable method for transfering/copying a large number of files from one external hard drive to another?
On the same drive I assume it would change something like a FAT table to repoint to the location of files.
Question
When going to a different drive (maybe even partition) does the mv command first copy, then remove the old files - in order to prevent data loss if an exception occured ?
macos command-line external-disk
add a comment |
On the same drive I assume it would change something like a FAT table to repoint to the location of files.
Question
When going to a different drive (maybe even partition) does the mv command first copy, then remove the old files - in order to prevent data loss if an exception occured ?
macos command-line external-disk
add a comment |
On the same drive I assume it would change something like a FAT table to repoint to the location of files.
Question
When going to a different drive (maybe even partition) does the mv command first copy, then remove the old files - in order to prevent data loss if an exception occured ?
macos command-line external-disk
On the same drive I assume it would change something like a FAT table to repoint to the location of files.
Question
When going to a different drive (maybe even partition) does the mv command first copy, then remove the old files - in order to prevent data loss if an exception occured ?
macos command-line external-disk
macos command-line external-disk
asked 2 hours ago
JacksonkrJacksonkr
15218
15218
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
OS X's mv is based on the BSD source code. You can find the source code to the mv command online. Using https://github.com/freebsd/freebsd/blob/master/bin/mv/mv.c as a reference, you can see that they do indeed first try to rename the file and then if it is crossing filesystems, it does a cp followed by a rm.
/*
* If rename fails because we're trying to cross devices, and
* it's a regular file, do the copy internally; otherwise, use
* cp and rm.
*/
if (lstat(from, &sb))
warn("%s", from);
return (1);
return (S_ISREG(sb.st_mode) ?
fastcopy(from, to, &sb) : copy(from, to));
}
The source code snippet you link to actually do not have something to do with the detecting a cross-filesystem move or actually doing a cp followed by a rm. It is only the comment that describes this behavior - the actual code for it is really before the comment. The code after the comment already assumes that it is a cross-device move, and determines whether the source is a regular file to be copied internally, or something else that is moved using calls to the external programs cp and mv.
– jksoegaard
2 hours ago
@jksoegaard - Correct. I was highlighting the section of code from the linked source code that directly addressed the question being posed.
– ParanoidGeek
1 hour ago
add a comment |
Yes, you're right in thinking that moving a single file on the same file system is really just implemented as a rename operating that the file system structure is changed to update the new name/location of the file, but the file contents are not read/written to the drive again.
When the move happens across two different file systems (drives or partitions), then the mv commands first deletes the destination (if there were an old file there already), copies over the contents of the file to the destination and then finally removes the source file.
The behavior is explained in the manual for mv on macOS:
As the rename(2) call does not work across file systems, mv uses cp(1) and rm(1) to accomplish the move. The effect is equivalent to:
rm -f destination_path &&
cp -pRP source_file destination &&
rm -rf source_file
In regards to the other answer that compares this behavior with the FreeBSD source code - the mv command on macOS is actually a bit different than on FreeBSD. In particular it makes sure that extended attributes and resource forks are moved over correctly and do not disappear when moving across file system boundaries.
You can read the actual macOS source for mv here:
https://opensource.apple.com/source/file_cmds/file_cmds-272.220.1/mv/mv.c.auto.html
You'll see that it is similar in structure as the FreeBSD version, but contains various Apple specific enhancement. In addition to the functionality regarding extended attributes and resource forks as described above, it also has performance enhancements for use with Xsan (distributed file system).
You'll find in the code that first a rename is attempted:
if (!rename(from, to))
if (vflg)
printf("%s -> %sn", from, to);
return (0);
If this rename() fails, the code checks why it failed. Especially it checks for the error number EXDEV, which means that the rename would have crossed file systems, and thus cannot be done:
if (errno == EXDEV)
struct statfs sfs;
char path[PATH_MAX];
/* Can't mv(1) a mount point. */
if (realpath(from, path) == NULL)
warnx("cannot resolve %s: %s", from, path);
return (1);
if (!statfs(path, &sfs) && !strcmp(path, sfs.f_mntonname))
warnx("cannot rename a mount point");
return (1);
else
warn("rename %s to %s", from, to);
return (1);
Note here that this code aborts the move in case that the source contains unresolvable symbolic links, or if it is actually a mount point - and also generally if the rename() fails for other reasons than EXDEV.
Only in case that rename() fails with error number EXDEV, and not for the above mentioned reasons, the following code is run:
/*
* If rename fails because we're trying to cross devices, and
* it's a regular file, do the copy internally; otherwise, use
* cp and rm.
*/
if (lstat(from, &sb))
warn("%s", from);
return (1);
return (S_ISREG(sb.st_mode) ?
fastcopy(from, to, &sb) : copy(from, to));
This code branches out to do the move between file systems in two different ways depending on whether or not the source to be moved is actually a regular file - or it is something else. "Something else" is usually a directory, a symbolic link, a device node or similar.
In case of a regular file, it uses fastcopy() which simply opens the source and destion files, read()s the data from the source and write()s them to the destination. Unlike the FreeBSD version, the fastcopy() function uses fcopyfile() to copy over ACLs and extended attributes from the source to the destination.
In case of something that is not a regular file, it simply spawns external commands to perform the move: "cp" for copying and "rm" for deleting.
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "118"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fapple.stackexchange.com%2fquestions%2f355169%2fhow-does-the-mv-command-work-with-external-drives%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
OS X's mv is based on the BSD source code. You can find the source code to the mv command online. Using https://github.com/freebsd/freebsd/blob/master/bin/mv/mv.c as a reference, you can see that they do indeed first try to rename the file and then if it is crossing filesystems, it does a cp followed by a rm.
/*
* If rename fails because we're trying to cross devices, and
* it's a regular file, do the copy internally; otherwise, use
* cp and rm.
*/
if (lstat(from, &sb))
warn("%s", from);
return (1);
return (S_ISREG(sb.st_mode) ?
fastcopy(from, to, &sb) : copy(from, to));
}
The source code snippet you link to actually do not have something to do with the detecting a cross-filesystem move or actually doing a cp followed by a rm. It is only the comment that describes this behavior - the actual code for it is really before the comment. The code after the comment already assumes that it is a cross-device move, and determines whether the source is a regular file to be copied internally, or something else that is moved using calls to the external programs cp and mv.
– jksoegaard
2 hours ago
@jksoegaard - Correct. I was highlighting the section of code from the linked source code that directly addressed the question being posed.
– ParanoidGeek
1 hour ago
add a comment |
OS X's mv is based on the BSD source code. You can find the source code to the mv command online. Using https://github.com/freebsd/freebsd/blob/master/bin/mv/mv.c as a reference, you can see that they do indeed first try to rename the file and then if it is crossing filesystems, it does a cp followed by a rm.
/*
* If rename fails because we're trying to cross devices, and
* it's a regular file, do the copy internally; otherwise, use
* cp and rm.
*/
if (lstat(from, &sb))
warn("%s", from);
return (1);
return (S_ISREG(sb.st_mode) ?
fastcopy(from, to, &sb) : copy(from, to));
}
The source code snippet you link to actually do not have something to do with the detecting a cross-filesystem move or actually doing a cp followed by a rm. It is only the comment that describes this behavior - the actual code for it is really before the comment. The code after the comment already assumes that it is a cross-device move, and determines whether the source is a regular file to be copied internally, or something else that is moved using calls to the external programs cp and mv.
– jksoegaard
2 hours ago
@jksoegaard - Correct. I was highlighting the section of code from the linked source code that directly addressed the question being posed.
– ParanoidGeek
1 hour ago
add a comment |
OS X's mv is based on the BSD source code. You can find the source code to the mv command online. Using https://github.com/freebsd/freebsd/blob/master/bin/mv/mv.c as a reference, you can see that they do indeed first try to rename the file and then if it is crossing filesystems, it does a cp followed by a rm.
/*
* If rename fails because we're trying to cross devices, and
* it's a regular file, do the copy internally; otherwise, use
* cp and rm.
*/
if (lstat(from, &sb))
warn("%s", from);
return (1);
return (S_ISREG(sb.st_mode) ?
fastcopy(from, to, &sb) : copy(from, to));
}
OS X's mv is based on the BSD source code. You can find the source code to the mv command online. Using https://github.com/freebsd/freebsd/blob/master/bin/mv/mv.c as a reference, you can see that they do indeed first try to rename the file and then if it is crossing filesystems, it does a cp followed by a rm.
/*
* If rename fails because we're trying to cross devices, and
* it's a regular file, do the copy internally; otherwise, use
* cp and rm.
*/
if (lstat(from, &sb))
warn("%s", from);
return (1);
return (S_ISREG(sb.st_mode) ?
fastcopy(from, to, &sb) : copy(from, to));
}
answered 2 hours ago
ParanoidGeekParanoidGeek
25114
25114
The source code snippet you link to actually do not have something to do with the detecting a cross-filesystem move or actually doing a cp followed by a rm. It is only the comment that describes this behavior - the actual code for it is really before the comment. The code after the comment already assumes that it is a cross-device move, and determines whether the source is a regular file to be copied internally, or something else that is moved using calls to the external programs cp and mv.
– jksoegaard
2 hours ago
@jksoegaard - Correct. I was highlighting the section of code from the linked source code that directly addressed the question being posed.
– ParanoidGeek
1 hour ago
add a comment |
The source code snippet you link to actually do not have something to do with the detecting a cross-filesystem move or actually doing a cp followed by a rm. It is only the comment that describes this behavior - the actual code for it is really before the comment. The code after the comment already assumes that it is a cross-device move, and determines whether the source is a regular file to be copied internally, or something else that is moved using calls to the external programs cp and mv.
– jksoegaard
2 hours ago
@jksoegaard - Correct. I was highlighting the section of code from the linked source code that directly addressed the question being posed.
– ParanoidGeek
1 hour ago
The source code snippet you link to actually do not have something to do with the detecting a cross-filesystem move or actually doing a cp followed by a rm. It is only the comment that describes this behavior - the actual code for it is really before the comment. The code after the comment already assumes that it is a cross-device move, and determines whether the source is a regular file to be copied internally, or something else that is moved using calls to the external programs cp and mv.
– jksoegaard
2 hours ago
The source code snippet you link to actually do not have something to do with the detecting a cross-filesystem move or actually doing a cp followed by a rm. It is only the comment that describes this behavior - the actual code for it is really before the comment. The code after the comment already assumes that it is a cross-device move, and determines whether the source is a regular file to be copied internally, or something else that is moved using calls to the external programs cp and mv.
– jksoegaard
2 hours ago
@jksoegaard - Correct. I was highlighting the section of code from the linked source code that directly addressed the question being posed.
– ParanoidGeek
1 hour ago
@jksoegaard - Correct. I was highlighting the section of code from the linked source code that directly addressed the question being posed.
– ParanoidGeek
1 hour ago
add a comment |
Yes, you're right in thinking that moving a single file on the same file system is really just implemented as a rename operating that the file system structure is changed to update the new name/location of the file, but the file contents are not read/written to the drive again.
When the move happens across two different file systems (drives or partitions), then the mv commands first deletes the destination (if there were an old file there already), copies over the contents of the file to the destination and then finally removes the source file.
The behavior is explained in the manual for mv on macOS:
As the rename(2) call does not work across file systems, mv uses cp(1) and rm(1) to accomplish the move. The effect is equivalent to:
rm -f destination_path &&
cp -pRP source_file destination &&
rm -rf source_file
In regards to the other answer that compares this behavior with the FreeBSD source code - the mv command on macOS is actually a bit different than on FreeBSD. In particular it makes sure that extended attributes and resource forks are moved over correctly and do not disappear when moving across file system boundaries.
You can read the actual macOS source for mv here:
https://opensource.apple.com/source/file_cmds/file_cmds-272.220.1/mv/mv.c.auto.html
You'll see that it is similar in structure as the FreeBSD version, but contains various Apple specific enhancement. In addition to the functionality regarding extended attributes and resource forks as described above, it also has performance enhancements for use with Xsan (distributed file system).
You'll find in the code that first a rename is attempted:
if (!rename(from, to))
if (vflg)
printf("%s -> %sn", from, to);
return (0);
If this rename() fails, the code checks why it failed. Especially it checks for the error number EXDEV, which means that the rename would have crossed file systems, and thus cannot be done:
if (errno == EXDEV)
struct statfs sfs;
char path[PATH_MAX];
/* Can't mv(1) a mount point. */
if (realpath(from, path) == NULL)
warnx("cannot resolve %s: %s", from, path);
return (1);
if (!statfs(path, &sfs) && !strcmp(path, sfs.f_mntonname))
warnx("cannot rename a mount point");
return (1);
else
warn("rename %s to %s", from, to);
return (1);
Note here that this code aborts the move in case that the source contains unresolvable symbolic links, or if it is actually a mount point - and also generally if the rename() fails for other reasons than EXDEV.
Only in case that rename() fails with error number EXDEV, and not for the above mentioned reasons, the following code is run:
/*
* If rename fails because we're trying to cross devices, and
* it's a regular file, do the copy internally; otherwise, use
* cp and rm.
*/
if (lstat(from, &sb))
warn("%s", from);
return (1);
return (S_ISREG(sb.st_mode) ?
fastcopy(from, to, &sb) : copy(from, to));
This code branches out to do the move between file systems in two different ways depending on whether or not the source to be moved is actually a regular file - or it is something else. "Something else" is usually a directory, a symbolic link, a device node or similar.
In case of a regular file, it uses fastcopy() which simply opens the source and destion files, read()s the data from the source and write()s them to the destination. Unlike the FreeBSD version, the fastcopy() function uses fcopyfile() to copy over ACLs and extended attributes from the source to the destination.
In case of something that is not a regular file, it simply spawns external commands to perform the move: "cp" for copying and "rm" for deleting.
add a comment |
Yes, you're right in thinking that moving a single file on the same file system is really just implemented as a rename operating that the file system structure is changed to update the new name/location of the file, but the file contents are not read/written to the drive again.
When the move happens across two different file systems (drives or partitions), then the mv commands first deletes the destination (if there were an old file there already), copies over the contents of the file to the destination and then finally removes the source file.
The behavior is explained in the manual for mv on macOS:
As the rename(2) call does not work across file systems, mv uses cp(1) and rm(1) to accomplish the move. The effect is equivalent to:
rm -f destination_path &&
cp -pRP source_file destination &&
rm -rf source_file
In regards to the other answer that compares this behavior with the FreeBSD source code - the mv command on macOS is actually a bit different than on FreeBSD. In particular it makes sure that extended attributes and resource forks are moved over correctly and do not disappear when moving across file system boundaries.
You can read the actual macOS source for mv here:
https://opensource.apple.com/source/file_cmds/file_cmds-272.220.1/mv/mv.c.auto.html
You'll see that it is similar in structure as the FreeBSD version, but contains various Apple specific enhancement. In addition to the functionality regarding extended attributes and resource forks as described above, it also has performance enhancements for use with Xsan (distributed file system).
You'll find in the code that first a rename is attempted:
if (!rename(from, to))
if (vflg)
printf("%s -> %sn", from, to);
return (0);
If this rename() fails, the code checks why it failed. Especially it checks for the error number EXDEV, which means that the rename would have crossed file systems, and thus cannot be done:
if (errno == EXDEV)
struct statfs sfs;
char path[PATH_MAX];
/* Can't mv(1) a mount point. */
if (realpath(from, path) == NULL)
warnx("cannot resolve %s: %s", from, path);
return (1);
if (!statfs(path, &sfs) && !strcmp(path, sfs.f_mntonname))
warnx("cannot rename a mount point");
return (1);
else
warn("rename %s to %s", from, to);
return (1);
Note here that this code aborts the move in case that the source contains unresolvable symbolic links, or if it is actually a mount point - and also generally if the rename() fails for other reasons than EXDEV.
Only in case that rename() fails with error number EXDEV, and not for the above mentioned reasons, the following code is run:
/*
* If rename fails because we're trying to cross devices, and
* it's a regular file, do the copy internally; otherwise, use
* cp and rm.
*/
if (lstat(from, &sb))
warn("%s", from);
return (1);
return (S_ISREG(sb.st_mode) ?
fastcopy(from, to, &sb) : copy(from, to));
This code branches out to do the move between file systems in two different ways depending on whether or not the source to be moved is actually a regular file - or it is something else. "Something else" is usually a directory, a symbolic link, a device node or similar.
In case of a regular file, it uses fastcopy() which simply opens the source and destion files, read()s the data from the source and write()s them to the destination. Unlike the FreeBSD version, the fastcopy() function uses fcopyfile() to copy over ACLs and extended attributes from the source to the destination.
In case of something that is not a regular file, it simply spawns external commands to perform the move: "cp" for copying and "rm" for deleting.
add a comment |
Yes, you're right in thinking that moving a single file on the same file system is really just implemented as a rename operating that the file system structure is changed to update the new name/location of the file, but the file contents are not read/written to the drive again.
When the move happens across two different file systems (drives or partitions), then the mv commands first deletes the destination (if there were an old file there already), copies over the contents of the file to the destination and then finally removes the source file.
The behavior is explained in the manual for mv on macOS:
As the rename(2) call does not work across file systems, mv uses cp(1) and rm(1) to accomplish the move. The effect is equivalent to:
rm -f destination_path &&
cp -pRP source_file destination &&
rm -rf source_file
In regards to the other answer that compares this behavior with the FreeBSD source code - the mv command on macOS is actually a bit different than on FreeBSD. In particular it makes sure that extended attributes and resource forks are moved over correctly and do not disappear when moving across file system boundaries.
You can read the actual macOS source for mv here:
https://opensource.apple.com/source/file_cmds/file_cmds-272.220.1/mv/mv.c.auto.html
You'll see that it is similar in structure as the FreeBSD version, but contains various Apple specific enhancement. In addition to the functionality regarding extended attributes and resource forks as described above, it also has performance enhancements for use with Xsan (distributed file system).
You'll find in the code that first a rename is attempted:
if (!rename(from, to))
if (vflg)
printf("%s -> %sn", from, to);
return (0);
If this rename() fails, the code checks why it failed. Especially it checks for the error number EXDEV, which means that the rename would have crossed file systems, and thus cannot be done:
if (errno == EXDEV)
struct statfs sfs;
char path[PATH_MAX];
/* Can't mv(1) a mount point. */
if (realpath(from, path) == NULL)
warnx("cannot resolve %s: %s", from, path);
return (1);
if (!statfs(path, &sfs) && !strcmp(path, sfs.f_mntonname))
warnx("cannot rename a mount point");
return (1);
else
warn("rename %s to %s", from, to);
return (1);
Note here that this code aborts the move in case that the source contains unresolvable symbolic links, or if it is actually a mount point - and also generally if the rename() fails for other reasons than EXDEV.
Only in case that rename() fails with error number EXDEV, and not for the above mentioned reasons, the following code is run:
/*
* If rename fails because we're trying to cross devices, and
* it's a regular file, do the copy internally; otherwise, use
* cp and rm.
*/
if (lstat(from, &sb))
warn("%s", from);
return (1);
return (S_ISREG(sb.st_mode) ?
fastcopy(from, to, &sb) : copy(from, to));
This code branches out to do the move between file systems in two different ways depending on whether or not the source to be moved is actually a regular file - or it is something else. "Something else" is usually a directory, a symbolic link, a device node or similar.
In case of a regular file, it uses fastcopy() which simply opens the source and destion files, read()s the data from the source and write()s them to the destination. Unlike the FreeBSD version, the fastcopy() function uses fcopyfile() to copy over ACLs and extended attributes from the source to the destination.
In case of something that is not a regular file, it simply spawns external commands to perform the move: "cp" for copying and "rm" for deleting.
Yes, you're right in thinking that moving a single file on the same file system is really just implemented as a rename operating that the file system structure is changed to update the new name/location of the file, but the file contents are not read/written to the drive again.
When the move happens across two different file systems (drives or partitions), then the mv commands first deletes the destination (if there were an old file there already), copies over the contents of the file to the destination and then finally removes the source file.
The behavior is explained in the manual for mv on macOS:
As the rename(2) call does not work across file systems, mv uses cp(1) and rm(1) to accomplish the move. The effect is equivalent to:
rm -f destination_path &&
cp -pRP source_file destination &&
rm -rf source_file
In regards to the other answer that compares this behavior with the FreeBSD source code - the mv command on macOS is actually a bit different than on FreeBSD. In particular it makes sure that extended attributes and resource forks are moved over correctly and do not disappear when moving across file system boundaries.
You can read the actual macOS source for mv here:
https://opensource.apple.com/source/file_cmds/file_cmds-272.220.1/mv/mv.c.auto.html
You'll see that it is similar in structure as the FreeBSD version, but contains various Apple specific enhancement. In addition to the functionality regarding extended attributes and resource forks as described above, it also has performance enhancements for use with Xsan (distributed file system).
You'll find in the code that first a rename is attempted:
if (!rename(from, to))
if (vflg)
printf("%s -> %sn", from, to);
return (0);
If this rename() fails, the code checks why it failed. Especially it checks for the error number EXDEV, which means that the rename would have crossed file systems, and thus cannot be done:
if (errno == EXDEV)
struct statfs sfs;
char path[PATH_MAX];
/* Can't mv(1) a mount point. */
if (realpath(from, path) == NULL)
warnx("cannot resolve %s: %s", from, path);
return (1);
if (!statfs(path, &sfs) && !strcmp(path, sfs.f_mntonname))
warnx("cannot rename a mount point");
return (1);
else
warn("rename %s to %s", from, to);
return (1);
Note here that this code aborts the move in case that the source contains unresolvable symbolic links, or if it is actually a mount point - and also generally if the rename() fails for other reasons than EXDEV.
Only in case that rename() fails with error number EXDEV, and not for the above mentioned reasons, the following code is run:
/*
* If rename fails because we're trying to cross devices, and
* it's a regular file, do the copy internally; otherwise, use
* cp and rm.
*/
if (lstat(from, &sb))
warn("%s", from);
return (1);
return (S_ISREG(sb.st_mode) ?
fastcopy(from, to, &sb) : copy(from, to));
This code branches out to do the move between file systems in two different ways depending on whether or not the source to be moved is actually a regular file - or it is something else. "Something else" is usually a directory, a symbolic link, a device node or similar.
In case of a regular file, it uses fastcopy() which simply opens the source and destion files, read()s the data from the source and write()s them to the destination. Unlike the FreeBSD version, the fastcopy() function uses fcopyfile() to copy over ACLs and extended attributes from the source to the destination.
In case of something that is not a regular file, it simply spawns external commands to perform the move: "cp" for copying and "rm" for deleting.
edited 2 hours ago
answered 2 hours ago
jksoegaardjksoegaard
19.8k2150
19.8k2150
add a comment |
add a comment |
Thanks for contributing an answer to Ask Different!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fapple.stackexchange.com%2fquestions%2f355169%2fhow-does-the-mv-command-work-with-external-drives%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown