So many wrong assertions in so few paragraphs...
On 05.05.2009 sawyer x wrote:
> This seems like something that should fail regardless of the rename.
> It's insecure, can cause FS problems and doesn't make a lot of sense.
Insecure? FS problems?
Since these assertions are so far fetched, let's skip them and
continue with the real stuff.
> In UNIX (I'm not sure how it is with Windows), there is no
> "renaming" folders function. It doesn't exist.
Wrong, it's a system call. please RTFM:
man 2 rename
> You "mv" stuff. That doesn't just rename it, it gives it a different
> inode and everything.
Wrong again. The mv(1) command calls rename(2). This means it's the same
inode (which means the same ownership/permissions/etc btw), only the
name changes.
The only exception to this is when you move something between different
file systems (e.g: separate partitions/disks). In this case the mv(1)
command tries to rename(2), fails with a specific errno and falls back
to copying and removing the original (which means it's a different inode).
This behavior can be easily verified even without going to the source code
simply by system call tracing:
# Let's see what mv does
strace -o output mv t.c /tmp # My /tmp and /home are separate
Excerpt from output:
...
rename("t.c", "/tmp/t.c") = -1 EXDEV (Invalid cross-device link)
...
open("t.c", O_RDONLY|O_LARGEFILE|O_NOFOLLOW) = 3
...
open("/tmp/t.c", O_WRONLY|O_CREAT|O_EXCL|O_LARGEFILE, 0600) = 4
...
read(3, "#include <stdio.h>\n#include <stdl"..., 524288) = 139
write(4, "#include <stdio.h>\n#include <stdl"..., 139) = 139
> That means that - to the OS and FS - it's not the same folder. This
> detaches the script's environment, making it much easier to
> compromise. Beyond that, you can have serious errors trying to change
> or fetch environment variables. When running with FS functions, it
> usually calls environment variables or uses the environment in some
> way which a good point to target when trying to compromise the script.
Let's lower the science fiction factor, the only environment variable
that won't reflect reality is ... $ENV{PWD} (how surprising).
> There is no original "rename" function in UNIX. There is a "rename"
> utility Larry Wall wrote, that helps you change files.
I'm tired of repeating myself, let's run something instead...
1. A two-liner:
#! /bin/sh
mv $PWD $PWD/../t4
/bin/pwd
2. But this is perl-il!
#!/usr/bin/perl -w
$cwd = readlink "/proc/self/cwd";
rename("$cwd", "$cwd/../t4") or die "rename($cwd): $!";
system "/bin/pwd";
Implementation notes:
* Both scripts use absolute paths. Running mv . ../t4 won't work.
* In the end I use /bin/pwd and not the shell's built in pwd.
This is because the shell does not know the directory was moved
under its feet.
* As a bonus, you see an alternative (linux-only) way to get your
current working directory "from the horse mouth" (the kernel).
> I think you better check modules that provide portability:
Good advice.
> My advice on your act is:
> - Run the script from outside
Good advice.
> - Do an atomic operation with rename so it wouldn't be a problem
Good, but rename(2) is atomic on any POSIX system.
Cheers,
--
Oron Peled Voice: +972-4-8228492
[email protected] http://www.actcom.co.il/~oron
"When you understand UNIX, you will understand the world.
When you understand NT....you will understand NT" - Richard Thieme
_______________________________________________
Perl mailing list
[email protected]
http://mail.perl.org.il/mailman/listinfo/perl