1
0
Files
2022-09-29 17:59:04 +03:00

357 lines
6.9 KiB
C

/*
* acctcvt/io.c
* I/O functions for acctcvt
*
* Copyright 1997, Silicon Graphics, Inc.
* ALL RIGHTS RESERVED
*
* UNPUBLISHED -- Rights reserved under the copyright laws of the United
* States. Use of a copyright notice is precautionary only and does not
* imply publication or disclosure.
*
* U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights
* in Technical Data and Computer Software clause at DFARS 252.227-7013 and/or
* in similar or successor clauses in the FAR, or the DOD or NASA FAR
* Supplement. Contractor/manufacturer is Silicon Graphics, Inc.,
* 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311.
*
* THE CONTENT OF THIS WORK CONTAINS CONFIDENTIAL AND PROPRIETARY
* INFORMATION OF SILICON GRAPHICS, INC. ANY DUPLICATION, MODIFICATION,
* DISTRIBUTION, OR DISCLOSURE IN ANY FORM, IN WHOLE, OR IN PART, IS STRICTLY
* PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF SILICON
* GRAPHICS, INC.
*/
#ident "$Revision: 1.1 $"
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/stat.h>
#include "common.h"
/*
* CloseInput
* Close an input_t and release any resources it may be holding
*/
void
CloseInput(input_t *Input)
{
if (Input == NULL) {
InternalError();
return;
}
if (Input->unread != NULL) {
free(Input->unread);
}
fclose(Input->file);
bzero(Input, sizeof(input_t));
}
/*
* CloseOutput
* Close an output_t and release any resources it may be holding
*/
void
CloseOutput(output_t *Output)
{
if (Output == NULL) {
InternalError();
return;
}
fclose(Output->file);
bzero(Output, sizeof(output_t));
}
/*
* InputEOF
* Returns non-zero if the specified input_t is at the end-of-file,
* or 0 if not.
*/
int
InputEOF(input_t *Input)
{
if (Input == NULL) {
return 1;
}
if (Input->unreadlen > 0) {
return 0;
}
return feof(Input->file);
}
/*
* InputError
* Returns non-zero if the specified input_t is in an error state,
* 0 if not.
*/
int
InputError(input_t *Input)
{
if (Input == NULL) {
return 1;
}
return ferror(Input->file);
}
/*
* OpenInput
* Does whatever is necessary to make the specified input_t ready
* for reading. Returns 0 if successful, -1 if not.
*/
int
OpenInput(input_t *Input)
{
/* Proceed according to the type of input source we are using */
switch (Input->source) {
case in_file:
/* Reading from a file */
Input->file = fopen(Input->name, "r");
if (Input->file == NULL) {
fprintf(stderr,
"%s: unable to open input file %s - %s\n",
MyName,
Input->name,
strerror(errno));
return -1;
}
break;
case in_stdin:
/* Reading from stdin */
Input->file = stdin;
break;
default:
/* Unknown input source */
InternalError();
return -1;
}
return 0;
}
/*
* OpenOutput
* Does whatever is necessary to make the specified output_t ready
* for writing. Returns 0 if successful, -1 if not.
*/
int
OpenOutput(output_t *Output)
{
/* Proceed according to the destination type */
switch (Output->dest) {
case out_file:
/* Writing to a file */
Output->file = fopen(Output->name, "w");
if (Output->file == NULL) {
fprintf(stderr,
"%s: unable to open output file %s - %s\n",
MyName,
Output->name,
strerror(errno));
exit(2);
}
break;
case out_cmd:
/* Writing to a child process */
Output->file = StartChildProcess(Output->name);
if (Output->file == NULL) {
return -1;
}
break;
case out_stdout:
/* Writing to stdout */
Output->file = stdout;
break;
default:
/* Unknown output destination */
InternalError();
return -1;
}
return 0;
}
/*
* Print
* Similar to fprintf, but writes to the specified output_t.
* Returns 0 if successful, -1 if not.
*/
int
Print(output_t *Output, const char *Format, ...)
{
va_list Args;
if (Output == NULL) {
InternalError();
return -1;
}
va_start(Args, Format);
vfprintf(Output->file, Format, Args);
va_end(Args);
return 0;
}
/*
* Read
* Reads the specified number of bytes of data from the specified
* input_t into the specified buffer, honoring any previously
* unread data. Always reads exactly the number of bytes that
* is specified. Returns 0 if successful, -1 if not.
*/
int
Read(input_t *Input, void *Buffer, int TotalLength)
{
char *CurrBuf = (char *) Buffer;
int Len = TotalLength;
int NumBytes;
/* Watch for trivial cases */
if (Input == NULL || TotalLength < 1) {
return -1;
}
/* If an unread buffer is present, use data from there first */
if (Input->unreadlen > 0) {
/* Calculate the # of bytes we can unread */
NumBytes = TotalLength;
if (TotalLength > Input->unreadlen) {
NumBytes = Input->unreadlen;
}
/* Copy the unread bytes into the user's buffer */
bcopy(Input->unread, Buffer, NumBytes);
Len -= NumBytes;
CurrBuf += NumBytes;
/* Adjust the unread buffer */
Input->unreadlen -= NumBytes;
if (Input->unreadlen > 0) {
memmove(Input->unread,
Input->unread + NumBytes,
Input->unreadlen);
}
/* If we have completely satisfied the read, we're done */
if (Len == 0) {
return 0;
}
}
/* Satisfy the remainder of the read from the actual file */
if (fread(CurrBuf, Len, 1, Input->file) != 1) {
if (!feof(Input->file)) {
fprintf(stderr,
"%s: error on read - %s\n",
MyName, strerror(errno));
}
return -1;
}
return 0;
}
/*
* Unread
* Pushes the specified data back into the specified input_t.
* Returns 0 if successful, -1 if not.
*/
int
Unread(input_t *Input, void *Buffer, int Length)
{
/* Enlarge the current unread buffer if necessary */
if (Input->unreadlen + Length > Input->unreadbufsize) {
Input->unreadbufsize += (Length + 100);
Input->unread = realloc(Input->unread, Input->unreadbufsize);
if (Input->unread == NULL) {
InternalError();
abort();
}
}
/* Copy the new data to the end of the buffer */
bcopy(Buffer, Input->unread + Input->unreadlen, Length);
Input->unreadlen += Length;
return 0;
}
/*
* Write
* Writes the specified number of bytes of data from the specified
* buffer to the specified output_t. Returns 0 if successful, -1 if not.
*/
int
Write(output_t *Output, void *Buffer, int Length)
{
/* Watch for trivial cases */
if (Output == NULL || Output->file == NULL || Length < 1) {
return 0;
}
/* stdio does most of the hard work */
if (fwrite(Buffer, Length, 1, Output->file) != 1) {
/* An EPIPE isn't fatal: we may be writing to two */
/* output streams, and the second may still be OK */
if (errno == EPIPE) {
if (Debug & DEBUG_INVALID) {
fprintf(stderr,
"%s: warning - broken pipe detected\n",
MyName);
}
fclose(Output->file);
Output->file = NULL;
return 0;
}
/* Any other problem *is* Bad */
fprintf(stderr,
"%s: error on write - %s\n",
MyName,
strerror(errno));
return -1;
}
return 0;
}