Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Why isn't there a "copy" function?

by johnnywang (Priest)
on Sep 09, 2004 at 18:35 UTC ( [id://389823]=perlquestion: print w/replies, xml ) Need Help??

johnnywang has asked for the wisdom of the Perl Monks concerning the following question:

Seeking enlightment:

I've always been wondering why perl does't have a file "copy" function, it has "rename" and "unlink"(actually why is it named "unlink"? rather than something like "rm" given perl's ties to shell?). It seems to be a trouble to resort to a separate module File::Copy for such a common functionality.

Replies are listed 'Best First'.
Re: Why isn't there a "copy" function?
by ysth (Canon) on Sep 09, 2004 at 18:41 UTC
    Because perl functions started out mostly as direct interfaces to C library functions, which include rename and unlink but don't include copy. If anything, there are too many such functions, and more of them should be only available from modules. Perhaps you need to adjust your perception of what is "trouble" and "resorting" to not include something so straightforward and easy as using a core module.
Re: Why isn't there a "copy" function?
by hardburn (Abbot) on Sep 09, 2004 at 18:40 UTC

    I ask a different question: why aren't "rename" and "unlink" in a seperate module like "copy" is? (I know, the reason is historical.)

    Oh, and it's called "unlink" because that's what it's called in the underlieing POSIX lib. Perl is full of Unix-isms like this.

    "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

      Perl IS portable Unix, that is it's strength and personality. (btw this recent flurry of windows programmers without unixy background using perl seems to confirm how strong and usefull this design philosophy is).

      So this is rather - why doesn't Un*x have 'filecopy' syscall? Because it's not that common operation, when you work on something you move it, rename it, modify it AND archive it.

      'copy' syscall would be usefull for archiving... or would it?

      Besides, unix way is to be ascetic and elegant, avoiding putting messy and slow algorithms under the hood, and filecopy is definitely slow ( you want syscall with fast filecopy - great, here's hardlink for you ).

      That is also a reason why rename fails across filesystems, it would be possible to have 'rename' call that works in such conditions ( look at the source of 'mv' command, such non-unix 'complete' design would put all that source into system, this would also add non-determinism to syscalls - normal rename returns very fast, across filesystems rename would take forever )

      It seems like you don't appreciate that?

        If I'm not mistaken, in the early days mv was _not_ able to move a file across file system boundaries, because it only implemented a rename. In those days you had to copy the file to the target FS and afterwards rm the leftovers on the source FS. Yes, you could call that ascetic. :-)

        It seems like you don't appreciate that?

        Huh? What makes you draw that conclusion? I don't want a lot of this stuff in the core simply because I'd like the core to be as minimilistic as possible (for one thing, it would encourage new programmers to use modules). It's too late for Perl5, but I can dream, can't I?

        "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

Re: Why isn't there a "copy" function?
by ikegami (Patriarch) on Sep 09, 2004 at 21:12 UTC

    I tried to answer this earlier, but I got nowhere. There's really no good answer to 'Why isn't there a "copy" function?'. I could say it has to do with there not being an equivalent OS call and C function (like "rename" and "unlink"), but like you said, manupilating files is very a common activity in perl.

    Keep in mind that "copy" can be created from other system calls (open + sysread + syswrite + close), while "rename" and "unlink" cannot.

    Then again, if we started including everything common into core... I guess the answer is bloat protection. That begs the question "Should many core functions be moved into modules?" Well, not in perl5, that would break too much, but that's something we could do in perl6.

    Ah well, just felt like writting a mini-essay.

Re: Why isn't there a "copy" function?
by iburrell (Chaplain) on Sep 09, 2004 at 23:02 UTC
    Because Unix does not have a copy function. Doing a file copy requires extra code, which is in File::Copy. This isn't too inconsistent since file moves across filesystems requires similar support, like with File::Copy::move.

    A better question is why Unix does not have a copy function to copy files. The operating system can do a better job copying files than user code. It can be much more efficient with network file systems, knows more about file attributes, better optimize IO, and could implement copy-on-write behavior. A copy() that only worked within a filesystem would be similar to rename().

      Consideration is currently going into Linux to add sendfile file-to-file semantics, which would be basically equivalent to a copyfile system call. The major problem is that, if you were to copy a 2GiB file, for example, it would freeze the system as the kernel took up all available processing time doing the copy. So, copyfile system calls would tend to expose a local DoS attack, because they happen in a place where execution can't normally be interrupted to allow for multitasking.
      Good point,
      On unix, File::Copy needs to be called when moving a file, but on Windows Win32::FileCopy is more reliable.
      copy-ing a file works best when the direct OS API's are called. (has to do with file permissions etc... ).

      ---------------------------
      Dr. Mark Ceulemans
      Senior Consultant
      BMC, Belgium
        On unix, File::Copy needs to be called when moving a file,

        If you like to be surprised or use non-flexible API, you'd use File::Copy. If you're smart, you'd use system cp. Things that are easy with system cp and awkward with File::Copy include:

            cp file1 file2 dir
            cp -r dir1 dir2
            cp -p file1 file2
            cp exe1 exe2
        
        Not to mention that I can stick an 'r' or an 's' in front of it, and copy from one machine to another.
Re: Why isn't there a "copy" function?
by Anonymous Monk on Sep 10, 2004 at 09:01 UTC
    actually why is it named "unlink"? rather than something like "rm" given perl's ties to shell?

    Because unlink (and rm) does precisely that, unlink a file. It doesn't remove a file, although the effect of unlinking may cause a file to be removed.

    To understand that, one first needs to know how a (Unix) filesystem works. This is a sketch of a file:

     
         +----------+
         | #i-node  |        +--------------+
         |          |------->|   Content    |
         +----------+        |              |
                             |              |
                             |              |
                             |              |
                             |              |
                             |              |
                             +--------------+
    
    It consists of two parts, an i-node with meta-information about the file, and a data part with the actual content of the file. Except for the pointer to the content of the file, all information stored in an i-node is returned by the stat() call. If you look up what stat() is returning, you will notice that it does not return the name of the file. That's right, the name of the file is not stored in the i-node.

    Then were is the name of the file stored? For that, we need to know how directories look like. Directories look like files, they have i-nodes as well, but what is interesting for us the content part. It looks like this:

        +-------------------+
        | name1 | #i-node-a |
        | name2 | #i-node-b |
        | name3 | #i-node-c |
        | name4 | #i-node-b |
        +-------------------+
    
    It is basically a table with two columns. It maps file names to i-nodes. This is called a link. Note that the mapping isn't unique, in the example above, name2 and name4 map to the same i-node. If you look once again at what stat() returns, you see that the fourth element that is returned is the number of links to the file. In the example above, a stat() on #i-node-a or #i-node-c would return 1 as the number of links, but doing a stat() on #i-node-b would return 2.

    What unlink is doing is that it removes one entry from the directory. A link disappears, hence the name unlink. Now, if after performing an unlink, the number of links to an i-node is 0, and the file hasn't been opened, the file will be removed by the kernel.

    Hence, the question shouldn't be "why isn't unlink named rm?", but, "why isn't rm named unlink?".

Re: Why isn't there a "copy" function?
by jacques (Priest) on Sep 09, 2004 at 21:31 UTC
    I've always been wondering why perl does't have a file "copy" function

    Because then you would have to include all of these other "must have" functions and Perl would no longer be Perl. It would be PHP.

Re: Why isn't there a "copy" function?
by ctilmes (Vicar) on Sep 10, 2004 at 09:03 UTC
    It's a bit like saying "Why doesn't C have a printf() function? It seems to be a trouble to resort to including stdio.h for such a common functionality."

    Yes, it is common, that's why it is a Core Module.

    (The real answer has already been provided -- Unix heritage.)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://389823]
Approved by jdtoronto
Front-paged by broquaint
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (4)
As of 2024-04-24 19:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found