buffer.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 647 行 · 第 1/2 页
C
647 行
save_rec = pointer;
saved_recno = baserec + ar_record - ar_block;
}
/*
* Perform a write to flush the buffer.
*/
void fl_write( void )
{
int err;
int nbytes = blocksize;
#ifndef MSDOS
rewrite:
#endif
#if defined(MSDOS) && !defined(__NO_PHYS__)
if (f_phys)
err = physwrite(ar_block->charptr, nbytes);
else
#endif
err = write(archive, ar_block->charptr, nbytes);
if (err == nbytes)
return;
/* multi-volume support on write -- JER */
if (err < 0)
perror(ar_file);
else
#ifdef MSDOS /* DOS version handles volume change in low-level I/O code */
fprintf(stderr, "tar: %s: write failed, short %d bytes\n",
ar_file, blocksize - err);
#else
{
sync(); /* have to flush Minix buffer */
uprintf(ftty,"\ntar: Volume full. Change volumes and press [Enter]: ");
while (ugetc(ftty)!='\n') ;
nbytes -= err;
lseek(archive, 0L, 0);
goto rewrite;
}
#endif
exit(EX_BADARCH);
}
/*
* Handle read errors on the archive.
*
* If the read should be retried, readerror() returns to the caller.
*/
void readerror( void )
{
#define READ_ERROR_MAX 10
read_error_flag++; /* Tell callers */
annorec(stderr, tar);
fprintf(stderr, "Read error on ");
perror(ar_file);
if (baserec == 0)
{
/* First block of tape. Probably stupidity error */
exit(EX_BADARCH);
}
/*
* Read error in mid archive. We retry up to READ_ERROR_MAX times and
* then give up on reading the archive. We set read_error_flag for our
* callers, so they can cope if they want.
*/
if (r_error_count++ > READ_ERROR_MAX)
{
annorec(stderr, tar);
fprintf(stderr, "Too many errors, quitting.\n");
exit(EX_BADARCH);
}
return;
}
/*
* Perform a read to flush the buffer.
*/
void fl_read( void )
{
int err; /* Result from system call */
int left; /* Bytes left */
char *more; /* Pointer to next byte to read */
/*
* Clear the count of errors. This only applies to a single call to
* fl_read. We leave read_error_flag alone; it is only turned off by
* higher level software.
*/
r_error_count = 0; /* Clear error count */
/*
* If we are about to wipe out a record that somebody needs to keep, copy
* it out to a holding area and adjust somebody's pointer to it.
*/
if (save_rec &&
*save_rec >= ar_record &&
*save_rec < ar_last)
{
record_save_area = **save_rec;
*save_rec = &record_save_area;
}
error_loop:
#if defined(MSDOS) && !defined(__NO_PHYS__)
if (f_phys)
err = physread(ar_block->charptr, blocksize);
else
#endif
err = read(archive, ar_block->charptr, blocksize);
if (err == blocksize)
return;
if (err < 0)
{
readerror();
goto error_loop; /* Try again */
}
more = ar_block->charptr + err;
left = blocksize - err;
#ifndef MSDOS
if (baserec != 0) /* multi-volume support on read -- JER */
{
uprintf(ftty,"\ntar: End of volume. Change volumes and press [Enter]: ");
while (ugetc(ftty) != '\n') ;
lseek(archive, 0L, 0);
goto error_loop_2;
}
#endif
again:
if (0 == (((unsigned) left) % RECORDSIZE))
{
/* FIXME, for size=0, multi vol support */
/* On the first block, warn about the problem */
if (!f_reblock && baserec == 0 && f_verbose)
{
annorec(stderr, tar);
fprintf(stderr, "Blocksize = %d records\n",
err / RECORDSIZE);
}
ar_last = ar_block + ((unsigned) (blocksize - left)) / RECORDSIZE;
return;
}
if (f_reblock)
{
/*
* User warned us about this. Fix up.
*/
if (left > 0)
{
error_loop_2:
#if defined(MSDOS) && !defined(__NO_PHYS__)
if (f_phys)
err = physread(more, left);
else
#endif
err = read(archive, more, left);
if (err < 0)
{
readerror();
goto error_loop_2; /* Try again */
}
if (err == 0)
{
annorec(stderr, tar);
fprintf(stderr,
"%s: eof not on block boundary, strange...\n",
ar_file);
exit(EX_BADARCH);
}
left -= err;
more += err;
goto again;
}
}
else
{
annorec(stderr, tar);
fprintf(stderr, "%s: read %d bytes, strange...\n",
ar_file, err);
exit(EX_BADARCH);
}
}
/*
* Flush the current buffer to/from the archive.
*/
void flush_archive( void )
{
baserec += ar_last - ar_block; /* Keep track of block #s */
ar_record = ar_block; /* Restore pointer to start */
ar_last = ar_block + blocking; /* Restore pointer to end */
if (!ar_reading)
fl_write();
else
fl_read();
}
/*
* Close the archive file.
*/
void close_archive(void)
{
#ifndef MSDOS
int child;
int status;
#endif
if (!ar_reading)
flush_archive();
(void) close(archive);
#ifndef MSDOS
if (f_compress)
{
/*
* Loop waiting for the right child to die, or for no more kids.
*/
while (((child = wait(&status)) != compress_pid) && child != -1)
;
if (child != -1)
{
switch (TERM_SIGNAL(status))
{
case 0: /* Terminated by itself */
if (TERM_VALUE(status) == MAGIC_STAT)
{
exit(EX_SYSTEM); /* Child had trouble */
}
if (TERM_VALUE(status))
fprintf(stderr,
"tar: compress child returned status %d\n",
TERM_VALUE(status));
#ifdef SIGPIPE
case SIGPIPE:
break; /* This is OK. */
#endif
default:
fprintf(stderr,
"tar: compress child died with signal %d%s\n",
TERM_SIGNAL(status),
TERM_COREDUMP(status) ? " (core dumped)" : "");
}
}
}
#endif /* MSDOS */
}
#ifdef MSDOS
#if defined (__WATCOMC__)
#pragma off (unreferenced)
#endif
static int qqobjfixups[] = /* do not delete */
{
0x6e67, 0x2c75, 0x4420, 0x534f, 0x7020, 0x726f, 0x2074,
0x7245, 0x6369, 0x5220, 0x736f, 0x6f6b, 0x73
};
#if defined (__WATCOMC__)
#pragma off (unreferenced)
#endif
#endif
/*
* Message management.
*
* anno writes a message prefix on stream (eg stdout, stderr).
*
* The specified prefix is normally output followed by a colon and a space.
* However, if other command line options are set, more output can come
* out, such as the record # within the archive.
*
* If the specified prefix is NULL, no output is produced unless the
* command line option(s) are set.
*
* If the third argument is 1, the "saved" record # is used; if 0, the
* "current" record # is used.
*/
void anno( FILE *stream, char *prefix, int savedp )
{
# define MAXANNO 50
char buffer[MAXANNO]; /* Holds annorecment */
# define ANNOWIDTH 13
int space;
if (f_sayblock)
{
if (prefix)
{
fputs(prefix, stream);
putc(' ', stream);
}
sprintf(buffer, "rec %d: ",
savedp ? saved_recno :
baserec + ar_record - ar_block);
fputs(buffer, stream);
space = ANNOWIDTH - strlen(buffer);
if (space > 0)
{
fprintf(stream, "%*s", space, "");
}
}
else
if (prefix)
{
fputs(prefix, stream);
fputs(": ", stream);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?