Questions on Unix File/Directory Manipulation using C 
Author Message
 Questions on Unix File/Directory Manipulation using C

1. How can I rename (move) files across filesystems?

   I need a C function that can move files across machines/filesystems,
   just as user-command "mv".  The program I'm writing should create
   files in /tmp/ and choose based on input to copy some of the files
   to current directory.

   "rename" can't work across filesystems, as explained in rename(2).
   I tried to write my own version using "link", and neither does link
   work, as explained in link(2).

    int myRename(char *old_file, char *new_file) {
      if (rename(old_file, new_file) == 0) {
        return 0;
      }
      else if (errno == EXDEV) {
        /* link() can't work across filesystems too. */
        if (link(old_file, new_file) != 0)
          return -1;
        return unlink(old_file);
      }
      else {
        perror("myRename");
        return -1;
      }
    }

   The only solution I can think of is to copy files, and then delete
   the old files.

    int myRename(char *old_file, char *new_file) {
      if (rename(old_file, new_file) == 0) {
        return 0;
      }
      else if (errno == EXDEV) {
        FILES *old_fd, *new_fd;
        char buf[MAX_BUF];
        int file_size;
        old_fd = fopen(old_file, "r");
        new_fd = fopen(new_file, "w");
        file_size = fread(buf, sizeof(char), MAX_BUF, old_fd);
        fwrite(buf, sizeof(char), file_size, new_fd);

        return unlink(old_file);
      }
      else {
        perror("myRename");
        return -1;
      }
    }

   But, I think the solution above is inefficient and has serious
   limitation, namely what if the "old_file" has size larger than
   MAX_BUF.  It means I have to implement a while loop to complete the
   copy.  Does someone know a better (more efficient) way to implement
   myRename?  Or is there a C function that does the same job as
   user-command "cp"?

2. Where (which lib) does basename() function reside in Solaris 2.5.1,
   and how to link its object using gcc?

   Here is a portion of my code that uses basename().

    #include <libgen.h>

    char myProjFile[] = "/proj/foo/bar.c";
    printf("The basename of '%s' is '%s'\n", myProjFile,
           basename(myProjFile));

   I compiled it with both gcc 2.8.1 and gcc 2.95.2 on Solaris 2.5.1,
   both returned the following errors.

    Undefined                       first referenced
     symbol                             in file
    basename                            /var/tmp/cca002G51.o
    ld: fatal: Symbol referencing errors. No output written to foo

   However, if I compile it on Solaris 2.7 using either version of gcc,
   it works fine.  Hence, I assume it's not gcc problem.

   Is this a common/known problem for Solaris 2.5.1, or is the problem
   specific to my Solaris 2.5.1 machine?  In either case, how can I fix
   it?

Thanks.  I appreciate your help.

Hon-Chi

Sent via Deja.com http://www.*-*-*.com/
Before you buy.



Sat, 29 Jun 2002 03:00:00 GMT  
 Questions on Unix File/Directory Manipulation using C

Quote:

> 1. How can I rename (move) files across filesystems?

>    I need a C function that can move files across machines/filesystems,
>    just as user-command "mv".  The program I'm writing should create
>    files in /tmp/ and choose based on input to copy some of the files
>    to current directory.

>    "rename" can't work across filesystems, as explained in rename(2).
>    I tried to write my own version using "link", and neither does link
>    work, as explained in link(2).

>     int myRename(char *old_file, char *new_file) {
>       if (rename(old_file, new_file) == 0) {
>         return 0;
>       }
>       else if (errno == EXDEV) {
>         /* link() can't work across filesystems too. */
>         if (link(old_file, new_file) != 0)
>           return -1;
>         return unlink(old_file);
>       }
>       else {
>         perror("myRename");
>         return -1;
>       }
>     }

>    The only solution I can think of is to copy files, and then delete
>    the old files.

>     int myRename(char *old_file, char *new_file) {
>       if (rename(old_file, new_file) == 0) {
>         return 0;
>       }
>       else if (errno == EXDEV) {
>         FILES *old_fd, *new_fd;
>         char buf[MAX_BUF];
>         int file_size;
>         old_fd = fopen(old_file, "r");
>         new_fd = fopen(new_file, "w");
>         file_size = fread(buf, sizeof(char), MAX_BUF, old_fd);
>         fwrite(buf, sizeof(char), file_size, new_fd);

>         return unlink(old_file);
>       }
>       else {
>         perror("myRename");
>         return -1;
>       }
>     }

>    But, I think the solution above is inefficient and has serious
>    limitation, namely what if the "old_file" has size larger than
>    MAX_BUF.  It means I have to implement a while loop to complete the
>    copy.  Does someone know a better (more efficient) way to implement
>    myRename?  Or is there a C function that does the same job as
>    user-command "cp"?

> 2. Where (which lib) does basename() function reside in Solaris 2.5.1,
>    and how to link its object using gcc?

>    Here is a portion of my code that uses basename().

>     #include <libgen.h>

>     char myProjFile[] = "/proj/foo/bar.c";
>     printf("The basename of '%s' is '%s'\n", myProjFile,
>            basename(myProjFile));

>    I compiled it with both gcc 2.8.1 and gcc 2.95.2 on Solaris 2.5.1,
>    both returned the following errors.

>     Undefined                       first referenced
>      symbol                             in file
>     basename                            /var/tmp/cca002G51.o
>     ld: fatal: Symbol referencing errors. No output written to foo

>    However, if I compile it on Solaris 2.7 using either version of gcc,
>    it works fine.  Hence, I assume it's not gcc problem.

>    Is this a common/known problem for Solaris 2.5.1, or is the problem
>    specific to my Solaris 2.5.1 machine?  In either case, how can I fix
>    it?

> Thanks.  I appreciate your help.

> Hon-Chi

> Sent via Deja.com http://www.deja.com/
> Before you buy.

1. IMO the best solution is to write a hybrid function that firstly
tries to use the link()/unlink() method. If you attempt a cross-device
link, link() will fail and errno will be set to EXDEV. If this happens
you must then revert to the copy technique. AFAIK this is how mv is
usually implemented.

2. Include stdgen.h and link with -lgen.



Sat, 29 Jun 2002 03:00:00 GMT  
 Questions on Unix File/Directory Manipulation using C

|> >
|> > 1. How can I rename (move) files across filesystems?
|>
|> 1. IMO the best solution is to write a hybrid function that firstly
|> tries to use the link()/unlink() method. ...

Yes.  But (to the original poster and people following up), please
do not cross-post this to comp.std.c or even comp.lang.c.  It is not
a C language question, still less one about C standardisation.  It
is a Unix question.

If I could remember the details or be bothered to look them up,
I could give you a response in terms of the MVS primitives.  This
would not be helpful, but is equally valid in C terms :-)

Regards,
Nick Maclaren,
University of Cambridge Computing Service,
New Museums Site, Pembroke Street, Cambridge CB2 3QG, England.

Tel.:  +44 1223 334761    Fax:  +44 1223 334679



Sat, 29 Jun 2002 03:00:00 GMT  
 Questions on Unix File/Directory Manipulation using C

Quote:

> 1. How can I rename (move) files across filesystems?

>    I need a C function that can move files across machines/filesystems,
>    just as user-command "mv".  The program I'm writing should create
>    files in /tmp/ and choose based on input to copy some of the files
>    to current directory.

>    "rename" can't work across filesystems, as explained in rename(2).
>    I tried to write my own version using "link", and neither does link
>    work, as explained in link(2).

>     int myRename(char *old_file, char *new_file) {
>       if (rename(old_file, new_file) == 0) {
>         return 0;
>       }
>       else if (errno == EXDEV) {
>         /* link() can't work across filesystems too. */
>         if (link(old_file, new_file) != 0)
>           return -1;
>         return unlink(old_file);
>       }
>       else {
>         perror("myRename");
>         return -1;
>       }
>     }

>    The only solution I can think of is to copy files, and then delete
>    the old files.

>     int myRename(char *old_file, char *new_file) {
>       if (rename(old_file, new_file) == 0) {
>         return 0;
>       }
>       else if (errno == EXDEV) {
>         FILES *old_fd, *new_fd;
>         char buf[MAX_BUF];
>         int file_size;
>         old_fd = fopen(old_file, "r");
>         new_fd = fopen(new_file, "w");
>         file_size = fread(buf, sizeof(char), MAX_BUF, old_fd);
>         fwrite(buf, sizeof(char), file_size, new_fd);

>         return unlink(old_file);
>       }
>       else {
>         perror("myRename");
>         return -1;
>       }
>     }

>    But, I think the solution above is inefficient and has serious
>    limitation, namely what if the "old_file" has size larger than
>    MAX_BUF.  It means I have to implement a while loop to complete the
>    copy.  Does someone know a better (more efficient) way to implement
>    myRename?  Or is there a C function that does the same job as
>    user-command "cp"?

> 2. Where (which lib) does basename() function reside in Solaris 2.5.1,
>    and how to link its object using gcc?

>    Here is a portion of my code that uses basename().

>     #include <libgen.h>

>     char myProjFile[] = "/proj/foo/bar.c";
>     printf("The basename of '%s' is '%s'\n", myProjFile,
>            basename(myProjFile));

>    I compiled it with both gcc 2.8.1 and gcc 2.95.2 on Solaris 2.5.1,
>    both returned the following errors.

>     Undefined                       first referenced
>      symbol                             in file
>     basename                            /var/tmp/cca002G51.o
>     ld: fatal: Symbol referencing errors. No output written to foo

>    However, if I compile it on Solaris 2.7 using either version of gcc,
>    it works fine.  Hence, I assume it's not gcc problem.

>    Is this a common/known problem for Solaris 2.5.1, or is the problem
>    specific to my Solaris 2.5.1 machine?  In either case, how can I fix
>    it?

> Thanks.  I appreciate your help.

I'd do it like this:

1. Use fstat() to determine the file system of the file you wish to move.
2. Use fstat() to determine the file system of the directory where you want
to copy/move the file.
3. Compare the two file systems. If they are the same, use the link/unlink
technique. If they are different use the copy/unlink technique.

This avoids relying on an error message to determine which course of action
to take.

......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
......................................................
v



Sat, 29 Jun 2002 03:00:00 GMT  
 Questions on Unix File/Directory Manipulation using C
/    I need a C function that can move files across machines/filesystems,
/    just as user-command "mv".  The program I'm writing should create
/    files in /tmp/ and choose based on input to copy some of the files
/    to current directory.

The easiest way would be
    char command[...];
    sprintf(command,"/bin/mv %s %s",source,destination");
    system(command);
Build on the existing base rather than start over.

--
CACS: Collective Against Consensual Sanity       v0.123
Now a text site map! http://www.angelfire.com/ca3/cacs/
pretty?     http://www.geocities.com/SoHo/Studios/5079/
SHOPPERS! Andrea Chen sock puppets on sale in aisle 14!



Sat, 29 Jun 2002 03:00:00 GMT  
 Questions on Unix File/Directory Manipulation using C

 >    sprintf(command,"/bin/mv %s %s",source,destination");
 >    system(command);

Breaks on filenames which contain whitespace, may introduce security-
problems, and is (IMHO) quite yucky.

                                                               robert



Sat, 29 Jun 2002 03:00:00 GMT  
 Questions on Unix File/Directory Manipulation using C

Quote:
>>>>> "robert" == robert  <robert> writes:


    >> sprintf(command,"/bin/mv %s %s",source,destination");
    >> system(command);

    robert> Breaks on filenames which contain whitespace, may
    robert> introduce security- problems, and is (IMHO) quite yucky.

Then one could fork(), and execl("/bin/mv", source, destination, NULL)
directly.  Not that it's much pretter, but it should solve the above
problems.

--

http://web.verbum.org/levanti
(1024D/C207843A) A580 5AA1 0887 2032 7EFB  19F4 9776 6282 C207 843A



Sat, 29 Jun 2002 03:00:00 GMT  
 Questions on Unix File/Directory Manipulation using C

Quote:

> I'd do it like this:

was there any reason to quote all of 80 lines, and then follow your text
with 90 lines of dots?

Quote:
> .......................................................

[snip]

I would have emailed this direct to you, but last time I tried to mail
you it bounced back <sigh>.

--
Ben Smithurst            | PGP: 0x99392F7D




Sat, 29 Jun 2002 03:00:00 GMT  
 Questions on Unix File/Directory Manipulation using C

| 1. How can I rename (move) files across filesystems?
|
|    The only solution I can think of is to copy files, and then delete
|    the old files.

In general, that's what you'll have to do. If the source and destination
reside on the same filesystem, you can just rename the file, but that's
a special case.

| 2. Where (which lib) does basename() function reside in Solaris 2.5.1

<libgen.h>

--



Sat, 29 Jun 2002 03:00:00 GMT  
 Questions on Unix File/Directory Manipulation using C


Quote:

> > 1. How can I rename (move) files across filesystems?

  ...

> > 2. Where (which lib) does basename() function reside in Solaris
2.5.1,
> >    and how to link its object using gcc?

  ...

> > Thanks.  I appreciate your help.

> > Hon-Chi

> 1. IMO the best solution is to write a hybrid function that firstly
> tries to use the link()/unlink() method. If you attempt a cross-device
> link, link() will fail and errno will be set to EXDEV. If this happens
> you must then revert to the copy technique. AFAIK this is how mv is
> usually implemented.

1. I believe rename() is equivalent to link() followed by unlink(), but
   I might be wrong.

Quote:

> 2. Include stdgen.h and link with -lgen.

2. I tried, but unfortunately it didn't work.  There isn't any stdgen.h
   in /usr/include/ nor any libgen.a in /usr/lib/ on my Solaris 2.5.1
   machine.  Does my Solaris 2.5.1 require a patch or something to get
   both the stdgen.h and libgen.a?  Has anybody encountered such
   problem before?

   As a side note, my Solaris 2.7 machine has /usr/lib/libgen.a, but
   doesn't have /usr/include/stdgen.h.

Thanks.

Hon-Chi

Sent via Deja.com http://www.deja.com/
Before you buy.



Sun, 30 Jun 2002 03:00:00 GMT  
 Questions on Unix File/Directory Manipulation using C


Quote:

> > 2. Where (which lib) does basename() function reside in Solaris
2.5.1,

> libresolv

> >    and how to link its object using gcc?

> gcc file.c -lresolv

It didn't work, i.e. I got the same "undefined symbol" error.  There is
no libresolv.a in /usr/lib/ on my Solaris 2.5.1 machine, except
/usr/lib/libresolv.so{,.1,.2}

Neither does my Solaris 2.7 machine have any /usr/lib/libresolv.a

BTW, how can I check what functions are in a given archive (.a)?

Quote:

> paul

Thanks.

Hon-Chi

Sent via Deja.com http://www.deja.com/
Before you buy.



Sun, 30 Jun 2002 03:00:00 GMT  
 Questions on Unix File/Directory Manipulation using C

Quote:
>It didn't work, i.e. I got the same "undefined symbol" error.  There is
>no libresolv.a in /usr/lib/ on my Solaris 2.5.1 machine, except
>/usr/lib/libresolv.so{,.1,.2}

.so's are the shared libraries which are used if they are available
(and are preferred) unless you specifically tell it to link with the
static .a's.

Quote:
>BTW, how can I check what functions are in a given archive (.a)?

nm  (works on both shared (.so) and static (.a))

--
________________________________________________________________________

Univ. of California at Berkeley         http://soar.Berkeley.EDU/~alanc/



Sun, 30 Jun 2002 03:00:00 GMT  
 Questions on Unix File/Directory Manipulation using C

Quote:

> 1. IMO the best solution is to write a hybrid function that firstly
> tries to use the link()/unlink() method. If you attempt a cross-device
> link, link() will fail and errno will be set to EXDEV. If this happens
> you must then revert to the copy technique. AFAIK this is how mv is
> usually implemented.

But isn't link/unlink equivalent to just `rename'?

--

Nate Eldredge



Sun, 30 Jun 2002 03:00:00 GMT  
 Questions on Unix File/Directory Manipulation using C

Quote:


>> I'd do it like this:

> was there any reason to quote all of 80 lines, and then follow your text
> with 90 lines of dots?

>> .......................................................
> [snip]

> I would have emailed this direct to you, but last time I tried to mail
> you it bounced back <sigh>.

I've asked him before,  he's stuck with Netscape as a news reader
and it's lamentable POS editor.  The news server won't let him post
if his new data is too much less the quoted data so ...

And Ken,  I tried mailing you at your BlueSax address,  but that bounced.
What gives?

--
Dan Mercer

Opinions expressed herein are my own and may not represent those of my employer.



Sun, 30 Jun 2002 03:00:00 GMT  
 Questions on Unix File/Directory Manipulation using C

Quote:

> >> .......................................................
> I've asked him before,  he's stuck with Netscape as a news reader
> and it's lamentable POS editor.  The news server won't let him post
> if his new data is too much less the quoted data so ...

I use Netscape for newsgroup reading and it works fine.
Don't blame Netscape for a news-server policy.
(We had such a policy at BRL at one time, under "rn".)


Sun, 30 Jun 2002 03:00:00 GMT  
 
 [ 25 post ]  Go to page: [1] [2]

 Relevant Pages 

1. Newbie: separate big .cs file into small .cs files

2. Adding cs-files from another directory in VS.NET

3. Need help with File and Directory Manipulations

4. Two CS files (using namespaces)

5. Using pointers for file manipulation

6. Check the file size and number symbols in a file using C in Unix

7. UNIX C DIRECTORY QUESTION

8. UNIX/C directories & files

9. Finding files/directories under UNIX.

10. File listing for current directory under Unix?

11. Find files of a directory in UNIX

12. File Manipulation question

 

 
Powered by phpBB® Forum Software