Questions on Unix File/Directory Manipulation using C
Author |
Message |
Hon-Chi N #1 / 25
|
 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 |
|
 |
Andy Knigh #2 / 25
|
 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 |
|
 |
Nick Maclar #3 / 25
|
 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 |
|
 |
Kenneth C Stah #4 / 25
|
 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 |
|
 |
China Blue Light Speci #5 / 25
|
 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 |
|
 |
robe #6 / 25
|
 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 |
|
 |
Colin Walter #7 / 25
|
 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 |
|
 |
Ben Smithur #8 / 25
|
 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 |
|
 |
John Doher #9 / 25
|
 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 |
|
 |
Hon-Chi N #10 / 25
|
 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 |
|
 |
Hon-Chi N #11 / 25
|
 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: Thanks. Hon-Chi Sent via Deja.com http://www.deja.com/ Before you buy.
|
Sun, 30 Jun 2002 03:00:00 GMT |
|
 |
Alan Coopersmi #12 / 25
|
 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 |
|
 |
Nate Eldredg #13 / 25
|
 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 |
|
 |
Dan Merc #14 / 25
|
 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 |
|
 |
Douglas A. Gwy #15 / 25
|
 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 |
|
|
Page 1 of 2
|
[ 25 post ] |
|
Go to page:
[1]
[2] |
|