Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 /* 00002 00003 Copyright (C) 2000, 2001, Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2.1 of the GNU Lesser General Public License 00007 as published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided herein, whether implied or 00016 otherwise, applies only to this software file. Patent licenses, if 00017 any, provided herein do not apply to combinations of this program with 00018 other software, or any other product whatsoever. 00019 00020 You should have received a copy of the GNU Lesser General Public 00021 License along with this program; if not, write the Free Software 00022 Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 00023 USA. 00024 00025 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00026 Mountain View, CA 94043, or: 00027 00028 http://www.sgi.com 00029 00030 For further information regarding this notice, see: 00031 00032 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00033 00034 */ 00035 00036 00037 00038 #pragma ident "@(#) libf/fio/unitbksp.c 92.1 06/18/99 18:38:26" 00039 00040 #include <errno.h> 00041 #include <foreign.h> 00042 #include <liberrno.h> 00043 #include "fio.h" 00044 #ifdef __mips 00045 typedef long long _ftelltype; 00046 #define LIBFSEEK fseek64 00047 #define LIBFTELL ftell64 00048 #define FTELLZERO 0LL 00049 #else 00050 typedef long _ftelltype; 00051 #define LIBFSEEK fseek 00052 #define LIBFTELL ftell 00053 #define FTELLZERO 0L 00054 #endif 00055 00056 00057 /* 00058 * _unit_bksp 00059 * 00060 * Perform a backspace operation on a connected unit. 00061 * 00062 * Return value: 00063 * 00064 * 0 on normal completion. Error status if an error is 00065 * encountered. 00066 */ 00067 00068 int 00069 _unit_bksp(unit *cup) 00070 { 00071 int errn; 00072 unsigned char tbuf[TBUFSZB], *tp; 00073 struct ffsw fst; 00074 int first_read; 00075 00076 if (cup->useq == 0) /* If direct access file */ 00077 return(FEBKSPIV); /* BACKSPACE invalid on dir. acc.*/ 00078 00079 /* 00080 * Wait for completion of a preceding asynchronous BUFFER IN/OUT. 00081 */ 00082 00083 WAITIO(cup, return(cup->uffsw.sw_error)); 00084 00085 if (cup->uwrt) { 00086 if (cup->utrunc) { 00087 /* 00088 * Truncate file after last sequential write before 00089 * this BACKSPACE. 00090 */ 00091 errn = _unit_trunc(cup); 00092 if (errn != 0) 00093 return(errn); 00094 } 00095 cup->uwrt = 0; 00096 } 00097 00098 /* 00099 * According to the file structure make the appropriate request to 00100 * backspace one logical record. 00101 */ 00102 switch( cup->ufs ) { 00103 00104 case FS_FDC: 00105 if ((cup->uend != LOGICAL_ENDFILE) || (cup->uspcproc==1)) { 00106 00107 errn = XRCALL(cup->ufp.fdc, backrtn) cup->ufp.fdc, 00108 &fst); 00109 00110 if (errn < 0) 00111 return(fst.sw_error); 00112 } 00113 break; 00114 00115 00116 case FS_TEXT: 00117 case STD: 00118 /* 00119 * Can't backspace pipes. sockets, ttys. 00120 */ 00121 if (!cup->useek) 00122 return(FENOBKPI); /* can't backspace pipe */ 00123 00124 if (!cup->ufmt) /* if not formatted */ 00125 return(FENOBKSP); /* can't backspace unblocked files */ 00126 00127 if (cup->uend) goto ok; 00128 00129 first_read = 1; 00130 00131 for ( ; ; ) { 00132 ssize_t i; 00133 size_t ret; 00134 _ftelltype x, y; 00135 00136 y = LIBFTELL(cup->ufp.std); 00137 x = y; 00138 00139 if (x < TBUFSZB) 00140 x = 0; 00141 else 00142 x -= TBUFSZB; 00143 00144 (void) LIBFSEEK(cup->ufp.std, x, 0); 00145 00146 /* 00147 * starting at the current character position 00148 * minus 2 chars, search backwards for a newline 00149 * character. 00150 */ 00151 00152 ret = fread(tbuf, 1,(size_t)(y - x), cup->ufp.std); 00153 00154 if (ret < (y-x) && ferror(cup->ufp.std)) 00155 return(FEBSPNRD); 00156 00157 /* only the first time fread, we need to skip the 00158 * first 2 chars 00159 */ 00160 if (first_read) i = ret - 2; 00161 else i = ret; 00162 first_read = 0; 00163 00164 tp = tbuf; 00165 00166 for ( ; i >= 0; i--) { 00167 if ( *(tp+i) != '\n') continue; 00168 (void) LIBFSEEK(cup->ufp.std, (_ftelltype)i+1-ret, 1); 00169 goto ok; 00170 } 00171 00172 if (x == 0) { 00173 (void) LIBFSEEK(cup->ufp.std, FTELLZERO, 0); 00174 goto ok; 00175 } 00176 else 00177 if (ret <= 0) /* Should never occur */ 00178 return(FEINTUNK); 00179 00180 (void) LIBFSEEK(cup->ufp.std, x, 0); 00181 } 00182 00183 case FS_BIN: 00184 return(FENOBKSP); 00185 00186 00187 case FS_AUX: 00188 errn = FEMIXAUX; /* BACKSPACE not allowed on a WAIO, 00189 * MSIO, DRIO, or AQIO file. */ 00190 break; 00191 default: 00192 return(FEINTFST); 00193 } 00194 00195 ok: 00196 cup->uend = BEFORE_ENDFILE; 00197 cup->ulastyp = DT_NONE; 00198 cup->urecpos = 0; 00199 00200 return(0); 00201 }