00001 /* 00002 * Copyright 2004, 2005, 2006 PathScale, Inc. All Rights Reserved. 00003 */ 00004 00005 /* 00006 00007 Copyright (C) 2000, 2001, Silicon Graphics, Inc. All Rights Reserved. 00008 00009 This program is free software; you can redistribute it and/or modify it 00010 under the terms of version 2.1 of the GNU Lesser General Public License 00011 as published by the Free Software Foundation. 00012 00013 This program is distributed in the hope that it would be useful, but 00014 WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00016 00017 Further, this software is distributed without any warranty that it is 00018 free of the rightful claim of any third person regarding infringement 00019 or the like. Any license provided herein, whether implied or 00020 otherwise, applies only to this software file. Patent licenses, if 00021 any, provided herein do not apply to combinations of this program with 00022 other software, or any other product whatsoever. 00023 00024 You should have received a copy of the GNU Lesser General Public 00025 License along with this program; if not, write the Free Software 00026 Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 00027 USA. 00028 00029 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00030 Mountain View, CA 94043, or: 00031 00032 http://www.sgi.com 00033 00034 For further information regarding this notice, see: 00035 00036 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00037 00038 */ 00039 00040 00041 00042 #pragma ident "@(#) libf/fio/unitseek.c 92.1 06/18/99 18:38:26" 00043 00044 #include <errno.h> 00045 #include <foreign.h> 00046 #include <liberrno.h> 00047 #include <stdio.h> 00048 #include <string.h> 00049 #include "fio.h" 00050 #if defined(__mips) || (defined(_LITTLE_ENDIAN) && defined(__sv2)) 00051 #define LIBFSEEK fseek64 00052 #else 00053 #ifdef KEY /* Bug 1678 */ 00054 /* Need 64 bit position to support large files */ 00055 #define LIBFSEEK fseeko 00056 #else /* KEY Bug 1678 */ 00057 #define LIBFSEEK fseek 00058 #endif /* KEY Bug 1678 */ 00059 #endif 00060 /* 00061 * _unit_seek 00062 * Fortran seek. This routine exists as a support 00063 * routine for direct access I/O. It handles the 00064 * logical or physical seek to the specified record. 00065 * 00066 * input: 00067 * cup unit pointer 00068 * recn record number (1 is the first record) 00069 * iost statement state information 00070 * 00071 * returns: 00072 * 0 for success (cup->udalast is also updated) 00073 * >0 for error, value is error number 00074 */ 00075 00076 int 00077 _unit_seek( 00078 unit *cup, /* Unit pointer */ 00079 recn_t recn, /* Record number */ 00080 int iost) /* Statement type */ 00081 { 00082 register int errn; /* Error number */ 00083 register int isfmt; /* 1 if formatted else 0*/ 00084 register long recl; /* Record length */ 00085 register off_t pos; /* File position */ 00086 struct ffsw fst; /* FFIO status block */ 00087 00088 errn = 0; 00089 recl = cup->urecl; /* Get record length */ 00090 isfmt = cup->ufmt ? 1 : 0; /* Formatted? */ 00091 00092 if (recn <= 0) 00093 return(FEIVRECN); /* Invalid record number */ 00094 00095 if ((iost & TF_READ) && (recn > cup->udamax)) 00096 return(FENORECN); /* Reading a nonexistent record */ 00097 00098 switch (cup->ufs) { 00099 00100 case FS_TEXT: 00101 case STD: 00102 00103 /* 00104 * Seek to the requested record number. If formatted 00105 * I/O, then adjust the record length to account for 00106 * the newline delimiters. 00107 */ 00108 00109 assert ( strlen("\n") == 1 ); 00110 00111 recl = recl + isfmt; 00112 pos = (off_t) (recn - 1) * recl; 00113 if (LIBFSEEK(cup->ufp.std, pos, SEEK_SET) != 0) 00114 errn = errno; 00115 00116 break; 00117 00118 case FS_FDC: 00119 00120 /* 00121 * Seek to the requested record number and let 00122 * the FFIO layer make whatever adjustments are 00123 * necessary for record delimiters. 00124 */ 00125 00126 pos = (off_t)(recn - 1) * recl; 00127 if( XRCALL(cup->ufp.fdc, seekrtn) 00128 cup->ufp.fdc, pos, 0, &fst) < 0) 00129 errn = fst.sw_error; 00130 #if PURE_ENABLED 00131 else 00132 if (cup->ufmt == 0) /* If unformatted */ 00133 cup->ufbitpos = offset << 3; 00134 #endif /* PURE_ENABLED */ 00135 00136 break; 00137 00138 case FS_TAPE: 00139 case FS_BIN: 00140 default: 00141 errn = FEINTUNK; /* Deep weeds */ 00142 break; 00143 } /* switch */ 00144 00145 /* 00146 * If successful seek, update last record processed. Note that 00147 * for formatted I/O, the last record processed will be incremented 00148 * in endrec() processing. 00149 */ 00150 00151 if (errn == 0) 00152 cup->udalast = recn - isfmt; 00153 00154 return(errn); 00155 }
1.5.6