Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
unitseek.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/unitseek.c 92.1    06/18/99 18:38:26"
00039 
00040 #include <errno.h>
00041 #include <foreign.h>
00042 #include <liberrno.h>
00043 #include <stdio.h>
00044 #include "fio.h"
00045 #if defined(__mips) || (defined(_LITTLE_ENDIAN) && defined(__sv2))
00046 #define LIBFSEEK fseek64
00047 #else
00048 #define LIBFSEEK fseek
00049 #endif
00050 /*
00051  *      _unit_seek 
00052  *              Fortran seek.  This routine exists as a support
00053  *              routine for direct access I/O.  It handles the
00054  *              logical or physical seek to the specified record.
00055  *
00056  *      input:
00057  *              cup     unit pointer
00058  *              recn    record number (1 is the first record)
00059  *              iost    statement state information
00060  *
00061  *      returns:
00062  *               0      for success (cup->udalast is also updated)
00063  *              >0      for error, value is error number
00064  */
00065 
00066 int
00067 _unit_seek(
00068         unit    *cup,   /* Unit pointer */
00069         recn_t  recn,   /* Record number */
00070         int     iost)   /* Statement type */
00071 {
00072         register int    errn;           /* Error number         */
00073         register int    isfmt;          /* 1 if formatted else 0*/
00074         register long   recl;           /* Record length        */
00075         register off_t  pos;            /* File position        */
00076         struct ffsw     fst;            /* FFIO status block    */
00077 
00078         errn    = 0;
00079         recl    = cup->urecl;           /* Get record length */
00080         isfmt   = cup->ufmt ? 1 : 0;    /* Formatted? */
00081 
00082         if (recn <= 0)
00083                 return(FEIVRECN);       /* Invalid record number */
00084 
00085         if ((iost & TF_READ) && (recn > cup->udamax))
00086                 return(FENORECN);       /* Reading a nonexistent record */
00087 
00088         switch (cup->ufs) {
00089 
00090                 case FS_TEXT:
00091                 case STD:
00092 
00093                         /*
00094                          * Seek to the requested record number.  If formatted
00095                          * I/O, then adjust the record length to account for
00096                          * the newline delimiters.
00097                          */
00098 
00099                         assert ( strlen("\n") == 1 );
00100 
00101                         recl    = recl + isfmt;
00102                         pos     = (off_t) (recn - 1) * recl;
00103                         if (LIBFSEEK(cup->ufp.std, pos, SEEK_SET) != 0)
00104                                 errn    = errno;
00105 
00106                         break;
00107 
00108                 case FS_FDC:
00109 
00110                         /*
00111                          * Seek to the requested record number and let
00112                          * the FFIO layer make whatever adjustments are
00113                          * necessary for record delimiters.
00114                          */
00115 
00116                         pos     = (off_t)(recn - 1) * recl;
00117                         if( XRCALL(cup->ufp.fdc, seekrtn)
00118                                         cup->ufp.fdc, pos, 0, &fst) < 0)
00119                                 errn    = fst.sw_error;
00120 #if     PURE_ENABLED
00121                         else
00122                                 if (cup->ufmt == 0)     /* If unformatted */
00123                                         cup->ufbitpos   = offset << 3;
00124 #endif  /* PURE_ENABLED */
00125 
00126                         break;
00127 
00128                 case FS_TAPE:
00129                 case FS_BIN:
00130                 default:
00131                         errn    = FEINTUNK;     /* Deep weeds */
00132                         break;
00133         } /* switch */
00134 
00135         /*
00136          * If successful seek, update last record processed.  Note that
00137          * for formatted I/O, the last record processed will be incremented
00138          * in endrec() processing.
00139          */
00140 
00141         if (errn == 0)
00142                 cup->udalast    = recn - isfmt;
00143 
00144         return(errn);
00145 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines