how can i be certain that a file has copied exactly?
Gary Kline
kline at thought.org
Sat Dec 27 21:36:00 UTC 2008
On Sat, Dec 27, 2008 at 02:58:06PM +0200, Giorgos Keramidas wrote:
> On Sat, 27 Dec 2008 01:40:13 -0800, Gary Kline <kline at thought.org> wrote:
> > howdy,
> >
> > in a word, YES, /usr/bin/cmp saved the save before i unlinked the
> > oldfile. here is the strangeness. maybe you know, giorgos, or
> > somebody else on-list. At first--before i got smart and used your
> > snprintf to simply /bin/cp and then unlink---yes, or /bin/mv, or
> > simply rename()--- Before, while i creating via fgets/fputs a new
> > file, everything went fine until i ran out of buffer space. i
> > increased to buf[4096] to buf[65535]. more files were successfully
> > copied from dos\;5 to .dos/*.htm, actually. suddenly, cmp caught a
> > mismatch and the program exited. a careful diff showed the err a
> > something like line 3751. my copy was missing a byte near the EOF:
> >
> > </body></html
> >
> > minus the closing ">"
Your code copies flawlessly. I noticed late last night that
cmp uses the same byte-by-byte cp and IIRC checks each to
make certain they bytes are identical. My copyFile()
function simply used fopen, fgets, and fputs. I yanked it
from a program that copied files from ~/Mail where the lines
were around 80 bytes rather than in the thousands. With few
newlines. The gotcha got me, in other words! Thanks much
for the function!
gary
>
> There should be no problem when you copy a file using read() and write()
> with _any_ buffer size. Even a simple routine that reads byte by byte
> and copies the file should work (a bit more of error checking is needed
> wherever I have used a (void) cast but you get the idea):
>
> #include <stdio.h>
> #include <unistd.h>
>
> /*-
> * \brief copy a file, using stdio byte-level read and writes
> *
> * Copy the `fromname' file to the `toname' file, using only fgetc()
> * and fputc() operations from stdio. The internals of stdio are
> * free, of course, to use larger read() and write() buffers but all
> * this should be "hidden" from the code of copyfile().
> *
> * \param fromname The name of the source file to copy.
> * \param toname The name of the destination file where
> * `fromname' will be copied to.
> *
> * \return Upon successful completion 0 is
> * returned. Otherwise, EOF is returned
> * and the global variable errno is set to
> * indicate the error.
> */
>
> int
> copyfile(const char *fromname, const char *toname)
> {
> FILE *ifp;
> FILE *ofp;
> int ch;
>
> if ((ifp = fopen(fromname, "rb")) == NULL)
> return -1;
> if ((ofp = fopen(toname, "wb")) == NULL) {
> (void)fclose(ifp);
> return -1;
> }
>
> while ((ch = fgetc(ifp)) != EOF) {
> if (fputc(ch, ofp) == EOF)
> break;
> }
> if (ferror(ifp) != 0 || ferror(ofp) != 0) {
> (void)unlink(toname);
> (void)fclose(ofp);
> (void)fclose(ifp);
> return -1;
> }
>
> if (fclose(ofp) == EOF) {
> (void)fclose(ifp);
> return -1;
> }
> if (fclose(ifp) == EOF) {
> return -1;
> }
>
> return 0;
> }
>
> So if you are seeing copy errors when you change the buffer size, you
> are doing something odd with your buffers. We would have to see the
> actual code if you want more detailed help about possible buffer
> handling bugs :)
I'll grep -r thru /usr/src to see if any utility actually
does use my shortcut! ...Somehow I doubt it.
gary
>
> _______________________________________________
> freebsd-questions at freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-questions
> To unsubscribe, send any mail to "freebsd-questions-unsubscribe at freebsd.org"
--
Gary Kline kline at thought.org http://www.thought.org Public Service Unix
http://jottings.thought.org http://transfinite.thought.org
The 2.17a release of Jottings: http://jottings.thought.org/index.php
More information about the freebsd-questions
mailing list