3

rename (), link() don't work

Thanks!

Chris Gerken
  • 16,221
  • 6
  • 44
  • 59
JJ Liu
  • 1,351
  • 8
  • 20
  • 36
  • 3
    `fopen` + `fread` + `fwrite` + `fclose`. Different partitions means you must copy. – Nemo Nov 02 '11 at 23:41

3 Answers3

5

Have you tried using standard old C functions?

`fopen` the source on one partition
`fopen` the destination on the other partition

LOOP while `fread` > 0
   `fread` from the source to a buff
   `fwrite` to the dest from a buff

And then close your files (ie. fclose).

This is also more portable.

EDIT: If you wanted it to be really basic why not just use a scripting language (python/bash) and get it done in a few lines.

AusCBloke
  • 18,014
  • 6
  • 40
  • 44
  • especially easy with something like [`shutil.copy()`](http://docs.python.org/library/shutil.html#shutil.copy) – Greg Hewgill Nov 02 '11 at 23:56
  • 1
    "This is also more portable" - sort of. The problem with setting out to implement a "portable file copy" is that different systems have different file metadata, starting with file permissions and moving on through access times, ownership, ACLs and extra data streams. So the resulting copy is portable, but what it does isn't necessarily very useful, since it doesn't copy what any sensible user thinks of as "the file", just the file contents. – Steve Jessop Nov 03 '11 at 00:36
  • The source code for `cp --preserve` should give an idea of what else you might want to copy, and how to do so under linux. – Steve Jessop Nov 03 '11 at 00:44
  • @SteveJessop yeah that's why I italicised the "more" and suggested using copy functions from Python or bash, rather than copying the file contents with C functions. – AusCBloke Nov 03 '11 at 01:00
0

This is how I would do it. It's pretty simple and leaves the tricky part of the actual copying to the cp tool, which has successfully done this task for several years.

#include <assert.h>
#include <string.h>

#include <sys/wait.h>
#include <unistd.h>

int
runvp(int *ret_status, const char *command, const char * const *argv)
{
  pid_t pid;
  int status;
  char * const *execv_argv;

  pid = fork();
  if (pid == (pid_t) -1)
    return -1;

  if (pid == 0) {
    /*
     * Circumvent the C type conversion rules;
     * see ISO C99: 6.5.16.1#6 for details.
     */
    assert(sizeof(execv_argv) == sizeof(argv));
    memcpy(&execv_argv, &argv, sizeof(execv_argv));

    (void) execvp(command, execv_argv);
    return -1;
  }

  if (waitpid(pid, &status, 0) == -1)
    return -1;

  *ret_status = status;
  return 0;
}

This is a wrapper around fork and execvp that I wrote several years ago. It can be used like this:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
  int exitcode;
  const char *cmdline[] = {
    "cp",
    "--",
    argv[1],
    argv[2],
    NULL
  };

  if (runvp(&exitcode, cmdline[0], cmdline) == -1) {
    perror("runvp");
    return EXIT_FAILURE;
  }
  return EXIT_SUCCESS;
}
Roland Illig
  • 40,703
  • 10
  • 88
  • 121
  • 1
    Bad idea. You lose any ability to tell what went wrong if `cp` encounters an error, plus it will spew something to stderr in the process, plus it will pick up whatever "cp" happens to be in the PATH (i.e. potential security hole), plus it is longer and more complex than just writing your own copy function. – Nemo Nov 02 '11 at 23:53
-3

rename() should work. Have you checked the error it returns? rename() returns 0 if it succeeded according to the documentation:

http://www.cplusplus.com/reference/clibrary/cstdio/rename/

You can use perror() to print the error string to standard error (stderr, usually the screen):

http://www.cplusplus.com/reference/clibrary/cstdio/perror/

stuyguy
  • 239
  • 1
  • 3