/* @(#)osa.c 17.1.1.1 (ESO-DMD) 01/25/02 17:35:07 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, MA 02139, USA. Corresponding concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .TYPE Module .NAME osa .LANGUAGE C .AUTHOR IPG-ESO Garching .CATEGORY Host operating system interfaces. Files in ASCII (text files) .COMMENTS Handling of ascii files (using buffered I/O). These routines convert text data from the host format into internal format and viceversa. Text files are accessed sequentially in a synchronous form. Text files are referenced by the physical name in the open function. A file identifier is returned by this function to be used in later i/o operations. Associated to each file there is a pointer to locate the current file position (hidden in the file descriptor). The routines return always a non-negative integer number on successful return. Otherwise, a value of -1 is set to indicate an error condition and the variable ``oserror'' contains the symbolic error code. Symbolic error codes for each function to be defined. .VERSION 0.0 25-Aug-1986 Definition J. D. Ponz .VERSION 1.0 04-Nov-1986 Programmation B. Pirenne .VERSION 1.1 14-Apr-1987 Improve performance B. Pirenne .VERSION 1.5 20-Jul-1987 ost* -> osa* ; use "fileno()" to get the file #in osaopen() ; upgrade osaread(). B. Pirenne. .VERSION 1.6 31-May-1988 Cosmetic changes. C. Guirao .VERSION 1.7 04-Oct-1988 osaread modified: ensure the rest of a too long record is ignored (F. Ochsenbein) .VERSION 1.8 26-Jun-1989 Modified osaread (was detroying last byte) .VERSION 1.9 07-Nov-1989 Simplified osaopen .VERSION 1.10 08-Feb-1990 Corrected bug in osaread (error reported) .VERSION 1.11 04-May-1990 Be sure that stdin (0), stdout(1) ansd stderr(2) are understood... .VERSION 1.12 19-Dec-1990 Not checking FNAME_LEN any more CG. ------------------------------------------------------------*/ #include /* ANSI-C prototyping */ #include #include #include /* array to contain up to _NFILE_ file pointers. * This will be used to allow a the use of a transparent and * integer file identifier */ static FILE *fptr[_NFILE_]; #ifdef __STDC__ static FILE *get(int fid) #else static FILE *get(fid) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Convert fileno into file pointer. .RETURNS File pointer. NULL if error. .REMARKS Ensures a correct check. ------------------------------------------------------------*/ int fid; /* IN : file identifier */ #endif { FILE *fd; fd = NULL; oserror = 0; if (fid >= _NFILE_) oserror = EINVAL; else { switch(fid){ case 0: fd = stdin; break; case 1: fd = stdout; break; case 2: fd = stderr; break; default: fd = fptr[fid]; } if (fd == NULL) oserror = EINVAL; } return(fd); } int osaopen(phname, mode) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Opens text file for read or write. The variable mode defines the way of opening the file as READ, WRITE, READ_WRITE and APPEND. (see midas/osparms.h). The file pointer is set to the beginning of the file. .RETURNS Upon successful completion a file descriptor is returned. -1 is returned on error. .REMARKS System dependencies: -- UNIX: fopen(3S), fileno(macro in stdio.h) ------------------------------------------------------------*/ char *phname; /* IN : physical filename */ int mode; /* IN : open mode */ { FILE *fid, *fopen(); static char *fmode[4] = { "r", "w", "r+", "a" }; char *t; int ret; #if 0 /* Old code */ switch (mode) { case READ: /* open for read only */ t = fmode[0]; break; case WRITE: /* open for write only */ t = fmode[1]; break; case READ_WRITE: /* open for read-write */ t = fmode[2]; break; case APPEND: /* open for append */ t = fmode[3]; break; default: oserror = EINVAL; return(-1); } #else /* New Code */ t = fmode[mode&3]; #endif if ((fid = fopen(phname,t)) == NULL) { oserror = errno; return(-1); } ret = fileno(fid); /* indice of the file table is */ if (ret >= _NFILE_) { oserror = EINVAL; return(-2); } fptr[ret] = fid; /* the _file of struct FILE and */ /* this number becomes the file ptr */ return(ret); } int osaclose(fid) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Closes a text file. The argument fid is the file identification obtained from osaopen. .RETURNS Value 0 on normal return, -1 on error. .REMARKS System dependencies: -- VAX VMS: -- UNIX: fclose(3S) -- MIDAS VMS Equivalence: Not available. ------------------------------------------------------------*/ int fid; /* IN : file identifier */ { FILE *fd; int ret; if ( (fd = get(fid)) == NULL) return(-1); if ((ret = fclose(fd)) < 0) oserror = errno; fptr[fid] = NULL; /* File Closed: reset File Pointer */ return(ret); } int osaread(fid, pbuf, nochar) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Synchronous read from text file. The argument fid is the file identification obtained from osaopen. The routine reads 1 record from the current file position and stores up to nochar characters into the buffer pointed by pbuf. It the record is larger than the buffer size, the remainder is ignored. The carriage return character is never returned. The buffer returned is always null terminated. .RETURNS Number of characters of the record. (may be less than nochar if the EOF or a carriage return is encountered, larger if record truncated). Returns 0 if the record only contained the line feed char. Returns -1 if an error is encountered or if the end of file is reached. (In these last cases, oserror is set to the relevant error number). .REMARKS System dependencies: fgets / fgetc ------------------------------------------------------------*/ int fid; /* IN : file identifier */ char *pbuf; /* IN : pointer to i/o buffer */ int nochar; /* IN : number of i/o characters */ { FILE *fd; char *pc, *pe; int c; if ( (fd = get(fid)) == NULL) return(-1); errno = 0; /* MUST BE INITIALIZED... Feb-1990 */ if (fgets(pbuf, nochar, fd) == NULL) { oserror = errno; return(-1); } pe = pbuf + nochar - 1; /* Last Available Byte */ /* Continue to read if the end-of-record not found */ for (pc = pbuf; (pc <= pe) && (*pc != '\n') && (*pc != '\0'); pc++ ) ; if (pc > pe) /* Not Found */ *pe = '\0', pc = pe; if (*pc == '\n') /* Replace the newline + carriage-return */ { while ( (--pc >= pbuf) && (*pc == '\r')) ; *++pc = '\0'; } else for (c = 0, --pc; (c != EOF) && (c != '\n'); pc++) c = getc(fd); return((pc - pbuf)); } int osawrite(fid, pbuf, nochar) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Synchronous RECORD write into a text file. The argument fid is the file identification obtained from osaopen. The routine writes nochar characters from the buffer pointed by pbuf into the current file position. Upon return the file pointer is incremented by the number of characters actually written. .RETURNS Number of characters actually written. (possibly 0 on error) .REMARKS System dependencies: -- UNIX: fwrite(3S) ------------------------------------------------------------*/ int fid; /* IN : file identifier */ char *pbuf; /* IN : pointer to i/o buffer */ int nochar; /* IN : number of i/o characters */ { FILE *fd; int ret, add_newline; if ( (fd = get(fid)) == NULL) return(-1); add_newline = 0; ret = 0; if (nochar) /* There are bytes to write... */ { ret = fwrite(pbuf, sizeof(char), nochar, fd); if (ret == 0) ; /* Error */ else if (*(pbuf+nochar-1) != '\n') add_newline = 1; } else add_newline = 1; if (add_newline) ret += fwrite("\n", 1, 1, fd); if (ret == 0) oserror = errno; return(ret); } long osaseek(fid, address, mode) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE moves read/write pointer to text file. The address defines the pointer position in characters relative to: start of the file, current position or end of the file as defined by the variable mode (FILE_START, FILE_CURRENT, FILE_END). The argument fid is the file identification obtained from osaopen. .RETURNS Upon successful completion, the resulting pointer position .RETURNS measured in characters is returned or -1 on error. .REMARKS System dependencies: -- UNIX: fseek(3S), ftell(3S) ------------------------------------------------------------*/ int fid; /* IN : file identifier */ long address; /* IN : file pointer */ int mode; /* IN : mode of addressing */ { long ftell(); FILE *fd; if ( (fd = get(fid)) == NULL) return(-1L); if (fseek(fd, address, mode) < 0) { oserror = errno; return(-1L); } return(ftell(fd)); } int osawait(fid) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Flushes the input/output streams. .RETURNS The function returns 0 for success, and -1 if any error was detected (such as trying to write to a file that has not been opened for writing) was detected. .REMARKS System dependencies: --UNIX: fflush(3) ------------------------------------------------------------*/ int fid; /* file identification */ { FILE *fd; if ( (fd = get(fid)) == NULL) return(-1); return(fflush(fd)); } long osasize(fid) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Retrieve the current size of an opened file. .RETURNS The size of the file, -1 in case of error (oserror explains) .REMARKS ------------------------------------------------------------*/ int fid; /* IN: file identification */ { FILE *fd; long ret, pos, ftell(); if ( (fd = get(fid)) == NULL) return(-1L); pos = ftell(fd); /* Current position */ ret = -1; if (pos != -1) { (void)fseek(fd, 0L, 2); /* end of file */ ret = ftell(fd); (void)fseek(fd, pos, 0); } else oserror = errno; return(ret); } int osaunix(/*fid*/) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Tells if a file is Unix-like .RETURNS Always 1 .REMARKS For VMS compatibility ------------------------------------------------------------*/ /*int fid;*/ /* IN: file identification */ { return(1); }