Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
fseek.c
Go to the documentation of this file.
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/fseek.c    92.1    06/18/99 19:52:04"
00039 
00040 /*
00041  *       Position a file associated with a fortran logical unit with
00042  *       MIPS F77 and MIPS f90.
00043  *
00044  * CALLING SEQUENCE:
00045  *
00046  *      INTEGER ierror, ioff, ifrom, lunit
00047  *      ierror = fseek(lunit, ioff, ifrom)
00048  *
00049  *      INTEGER ierror, ioff, ifrom, lunit
00050  *      INTEGER(KIND=8) lioff
00051  *      ierror = fseek64(lunit, lioff, ifrom)
00052  *
00053  * WHERE:
00054  *
00055  *      lunit   = an open logical unit
00056  *
00057  *      ioff    = an offset in bytes relative to the position
00058  *                specified by ifrom
00059  *
00060  *      lioff   = an offset in bytes relative to the position
00061  *                specified by ifrom
00062  *
00063  *      ifrom   = - 0 means 'beginning of the file'
00064  *              = - 1 means 'the current position'
00065  *              = - 2 means 'the end of the file'
00066  *
00067  *      ierror  = 0 if successful.
00068  *              .NE. 0 a system error code if unsuccessful.
00069  *
00070  * NOTES: fseek64() only exists in the 64 bit library
00071  *
00072  *       __fseek_f90 is called for mips f77 or if there is no
00073  *       compatibility mode from mips f90.
00074  *
00075  *       fseekf90_ is called for mips f90 if there is a
00076  *       compatibility mode.
00077  *
00078  *       __fseek64_f90 is called for mips f77 or if there is no
00079  *       compatibility mode from mips f90.
00080  *
00081  *       fseekf90_8_ is called for mips f90 if there is a
00082  *       compatibility mode.
00083  *
00084  *       fseekf90_4_8_4_ is called for mips f90 if there is a
00085  *       compatibility mode.
00086  *
00087  */
00088 
00089 #include "fio.h"
00090 
00091 extern int __fseek_f90(int *u, int *off, int *from);
00092 extern _f_int fseekf90_(_f_int *u, _f_int *off, _f_int *from);
00093 extern _f_int __fseek64_f90(_f_int *u, _f_int8 *off, int *from);
00094 extern _f_int8 fseekf90_8_(_f_int8 *u, _f_int8 *off, int8 *from);
00095 extern _f_int fseekf90_4_8_4_(_f_int *u, _f_int8 *off, int *from);
00096 
00097 static _f_int __setpos64( unit *cup, _f_int8 ioff,  _f_int whence);
00098 
00099 int
00100 __fseek_f90(int *u, int *off, int *from)
00101 {
00102         return fseekf90_(u, off, from);
00103 }
00104 
00105 _f_int
00106 fseekf90_(_f_int *u, _f_int *off, _f_int *from)
00107 {
00108         unit            *cup;           /* Unit table pointer   */
00109         struct fiostate cfs;
00110         _f_int8         ioff;
00111         unum_t          unum;
00112         _f_int          rtrn;
00113 
00114         unum    = *u;
00115         ioff    = *off;
00116 /*      lock the unit */
00117         STMT_BEGIN( unum, 0, T_SETPOS, NULL, &cfs, cup);
00118 
00119 /*      If not connected, do an implicit open.  Abort if open fails. */
00120         if (cup == NULL)
00121                 cup     = _imp_open(&cfs, SEQ, UNF, unum, 0, NULL);
00122 
00123 /*      if direct access file, error. */
00124         if (cup->useq == 0)
00125                 _ferr(&cfs, FEBIONDA, "SETPOS");
00126 
00127 /*      Do the setpos. */
00128         if (__setpos64(cup, ioff, *from) != 0)
00129                 rtrn    = errno;
00130         else 
00131                 rtrn    = 0;
00132 
00133 /*      unlock the unit. */
00134         STMT_END(cup, T_SETPOS, NULL, &cfs);
00135         return rtrn;
00136 }
00137 
00138 _f_int
00139 __fseek64_f90(_f_int *u, _f_int8 *off, int *from)
00140 {
00141         return fseekf90_4_8_4_(u, off, from);
00142 }
00143 
00144 _f_int
00145 fseekf90_4_8_4_(_f_int *u, _f_int8 *off, int *from)
00146 {
00147         unit            *cup;           /* Unit table pointer   */
00148         struct fiostate cfs;
00149         _f_int8         ioff;
00150         unum_t          unum;
00151         _f_int          rtrn;
00152 
00153         unum    = *u;
00154         ioff    = *off;
00155 
00156 /*      lock the unit. */
00157         STMT_BEGIN( unum, 0, T_SETPOS, NULL, &cfs, cup);
00158 
00159 /*      If not connected, do an implicit open.  Abort if open fails. */
00160         if (cup == NULL)
00161                 cup = _imp_open(&cfs, SEQ, UNF, unum, 0, NULL);
00162 
00163         if (cup->useq == 0)     /* If direct access file */
00164                 _ferr(&cfs, FEBIONDA, "SETPOS");
00165 
00166 /*
00167  *      Do the setpos.
00168  */
00169         if (__setpos64(cup, ioff, *from) != 0)
00170                 rtrn=errno;
00171         else 
00172                 rtrn = 0;
00173         STMT_END(cup, T_SETPOS, NULL, &cfs);    /* unlock the unit */
00174         return rtrn;
00175 }
00176 
00177 _f_int8
00178 fseekf90_8_(_f_int8 *u, _f_int8 *off, int8 *from)
00179 {
00180         unit            *cup;           /* Unit table pointer   */
00181         struct fiostate cfs;
00182         _f_int8         ioff;
00183         unum_t          unum;
00184         _f_int          rtrn;
00185         _f_int          whenc;
00186 
00187         unum    = *u;
00188         ioff    = *off;
00189         whenc   = *from;
00190 
00191 /*      lock the unit. */
00192         STMT_BEGIN( unum, 0, T_SETPOS, NULL, &cfs, cup);
00193 
00194 /*      If not connected, do an implicit open.  Abort if open fails. */
00195         if (cup == NULL)
00196                 cup = _imp_open(&cfs, SEQ, UNF, unum, 0, NULL);
00197 
00198         if (cup->useq == 0)     /* If direct access file */
00199                 _ferr(&cfs, FEBIONDA, "SETPOS");
00200 
00201 /*
00202  *      Do the setpos.
00203  */
00204         if (__setpos64(cup, ioff, *from) != 0)
00205                 rtrn=errno;
00206         else 
00207                 rtrn = 0;
00208         STMT_END(cup, T_SETPOS, NULL, &cfs);    /* unlock the unit */
00209         return rtrn;
00210 }
00211 
00212 /* 
00213  * __setpos64 is a 64-bit version of _setpos where user specifies a
00214  * "whence" parameter like the unix version of fseek().  Note: this
00215  * is NOT a general replacement for _setpos for MIPS.
00216  */
00217 
00218 _f_int
00219 __setpos64(
00220         unit    *cup,           /* unit pointer */
00221         _f_int8 ioff,           /* offset */
00222         _f_int  whence)         /* 0 - from beginning of file
00223                                  * 1 - from the current position
00224                                  * 2 - from the end of the file
00225                                  */
00226 {
00227         _f_int          ret;
00228         _f_int          retstat;
00229         struct fdinfo *fio;
00230         int             fp_parm[2];
00231 
00232         retstat = 0;
00233 
00234 /*      Wait for completion of a preceding asynchronous BUFFER IN/OUT. */
00235         WAITIO(cup, return(cup->uffsw.sw_error));
00236 
00237         cup->urecpos    = 0;
00238         if (cup->uwrt) {
00239                 if (cup->utrunc) {
00240                         ret = _unit_trunc(cup);
00241                         if (ret != 0)
00242                                 return(ret);
00243                 }
00244                 cup->uwrt = 0;
00245         }
00246 /*
00247  *      Make appropriate call to set file position according to the file
00248  *      structure.  Positioning routines are file-structure dependent.
00249  */
00250         switch( cup->ufs ) {
00251 
00252         case  FS_TEXT:
00253         case  STD:
00254 /*
00255  *              If unformatted file, then positioning is done to a word
00256  *              boundary.  Converto to bytes
00257  */
00258                 if ( cup->ufmt == NO )
00259                         ioff <<= 3;
00260 
00261                 ret     = fseek64(cup->ufp.std, ioff, whence);
00262                 if (ret != 0)
00263                         return(errno);
00264 
00265                 break;
00266 
00267         case  FS_FDC:
00268                 fio     = cup->ufp.fdc;
00269 
00270                 if ((cup->uflagword & FFC_SEEKA) ||
00271                    (whence==2 && (cup->uflagword & FFC_SEEKE))){
00272 
00273                         if (whence==2) {
00274 
00275                                 ret = XRCALL(fio, seekrtn) fio, ioff, 2,
00276                                    &cup->uffsw);
00277                                 if (ret < 0)
00278                                         return(cup->uffsw.sw_error);
00279 
00280                                 /* bit position in file */
00281                                 ret <<= 3;
00282                         } else {
00283         /* A couple of problems will need to be solved before we can */
00284         /* use the ffio posrtn on MIPS. That routine is currently */
00285         /* documented as expecting longs in the 3rd parameter for */
00286         /* FP_BSEEK . But more importantly, FP_BSEEK isn't supported */
00287         /* yet for MIPS, because  longs are not sufficiently large */
00288         /* to contain all possible file positions. */
00289                                 return(FDC_ERR_NOSUP);
00290                         }
00291                 }
00292                 else {
00293 /*
00294  *              Assume that positioning is done via a 'magic cookie'.
00295  *              Just pass it through.
00296  */
00297                         ret = XRCALL(fio, posrtn)
00298                            fio, FP_SETPOS, &ioff, 1, &cup->uffsw);
00299                 }
00300 
00301                 if (ret < 0)
00302                         return(cup->uffsw.sw_error);
00303                 ret = 0;
00304                 break;
00305 
00306         case FS_AUX:
00307                 return(FEMIXAUX);
00308         default:
00309                 return(FEINTFST);
00310         }
00311 
00312 /*      Set the end flag if going to EOD, else clear it. */
00313         if ((ioff==0 && whence==2) ) {
00314                 if (cup->ufs != FS_FDC)
00315                         cup->uend = LOGICAL_ENDFILE;
00316                 else {
00317                         /*
00318                          * This is after terminal endfile record of the
00319                          * file, but we must decide if it's a logical or
00320                          * physical endfile record.
00321                          */
00322                         if ((cup->uflagword & FFC_WEOF) == 0)
00323                                 cup->uend = LOGICAL_ENDFILE;
00324                         else {
00325                                 /* byte offset within file */
00326                                 int fbytepos;
00327 
00328                                 switch (fio->class) {
00329 
00330                                 case CLASS_COS:
00331                                         /*
00332                                          * Since seekrtn for a cos layer
00333                                          * when called with 0,2 does NOT
00334                                          * return a resulting byte offset,
00335                                          * query the position with this
00336                                          * seekrtn call.  The only case
00337                                          * where 0 might be returned is
00338                                          * when the file is empty.
00339                                          */
00340                                         fbytepos = XRCALL(fio, seekrtn) fio, 0,
00341                                            1, &cup->uffsw);
00342                                         if (fbytepos > 0)
00343                                                 cup->uend = PHYSICAL_ENDFILE;
00344                                         else
00345                                                 cup->uend = LOGICAL_ENDFILE;
00346                                         break;
00347                                 default:
00348                                         return(FEBIOSNT);
00349                                 }
00350                         }
00351                 }
00352         } else
00353                 /*
00354                  * Sadly, we may be positioned after an endfile record,
00355                  * and not know it.   This should be fixed.
00356                  */
00357                 cup->uend = BEFORE_ENDFILE;
00358         return(OK);
00359 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines