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