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 #pragma ident "@(#) libf/pxf/pxfread.c 92.2 06/29/99 11:36:06" 00038 00039 #ifndef BLANK 00040 #define BLANK ((int) ' ') 00041 #endif 00042 00043 /* 00044 * PXFREAD -- Read a File 00045 * (section 6.4.1 of Posix 1003.9-1992) 00046 * 00047 * Synopsis: 00048 * 00049 * SUBROUTINE PXFREAD(ifildes, buf, nbyte, nread, ierror) 00050 * INTEGER ifildes, nbyte, nread, ierror 00051 * CHARACTER BUF(*) 00052 * 00053 * Description: 00054 * 00055 * PXFREAD uses the read() function to read from a file associated 00056 * with ifildes into a buffer. Return the actual number 00057 * of bytes read and return the error status. 00058 * 00059 * The arguments are: 00060 * 00061 * ifildes - default integer input variable containing a file 00062 * descriptor. 00063 * buf - output character variable containing the data read. 00064 * nbyte - default input integer variable specifying the 00065 * number of bytes to be read. 00066 * nread - default output integer variable containing the 00067 * number of bytes actually read. 00068 * ierror - default integer output variable that contains zero 00069 * if the operation was successful or nonzero if the 00070 * operation was not successful. 00071 * 00072 * PXFREAD may return one of the following error values: 00073 * 00074 * EAGAIN Mandatory file and record locking was set, O_NDELAY was 00075 * set, and there was a blocking record lock. 00076 * 00077 * EBADF If ifildes is not a valid file descriptor open for 00078 * reading. 00079 * 00080 * EDEADLK If the read was going to go to sleep and would cause 00081 * a deadlock situation to occur. 00082 * 00083 * EFAULT If buf points outside the allocated process address 00084 * space. 00085 * 00086 * EINTR If read was interrupted by a signal. 00087 * 00088 * EINVAL If the call contains an argument that is not valid. 00089 * 00090 * ENOLCK If the sytem record lock table was full, the read 00091 * could not go to sleep until the block record lock was 00092 * removed. 00093 * 00094 * ENOMEM If PXFREAD is unable to obtain memory to create an 00095 * internal buffer. 00096 * 00097 * ENXIO If the device associated with ifildes is a character 00098 * special file that does not exist or the file pointer 00099 * is out of range. 00100 * 00101 * On IRIX systems, PXFREAD may also return: 00102 * 00103 * EACCES If ifildes is open to a dynamic device and read 00104 * permission is denied. 00105 * 00106 * EBADMSG If the message waiting to be read on a stream is not a 00107 * data message. 00108 * 00109 * EIO If a physical I/O error has occurred, or the read is 00110 * cannot access the device. or If ifildes has O_DIRECT 00111 * or FDIRECT set and nbytes is greater than the number 00112 * of bytes between the current file pointer position 00113 * and the end of file. 00114 * 00115 */ 00116 00117 #include <errno.h> 00118 #include <fortran.h> 00119 #include <liberrno.h> 00120 #include <stdlib.h> 00121 #include <string.h> 00122 #include <sys/errno.h> 00123 #include <sys/types.h> 00124 #include <unistd.h> 00125 00126 #ifdef _UNICOS 00127 void 00128 PXFREAD( 00129 #else /* _UNICOS */ 00130 void 00131 _PXFREAD( 00132 #endif /* _UNICOS */ 00133 _f_int *ifildes, 00134 _fcd buf, 00135 _f_int *nbyte, 00136 _f_int *nread, 00137 _f_int *ierror) 00138 { 00139 char *buffr; 00140 char *strread; 00141 int skipconform = 0; 00142 long string_len; 00143 long copy_len; 00144 size_t errsts = 0; 00145 size_t toberead; 00146 size_t wasread; 00147 *ierror = 0; 00148 *nread = 0; 00149 toberead = (size_t)*nbyte; 00150 string_len = _fcdlen(buf); 00151 if ((int)toberead <= 0) 00152 return; 00153 buffr = (char *) malloc(toberead); 00154 00155 /* 00156 * The PXFREAD_CONFORM environment variable can be set to NO to 00157 * indicate that the check on the size of nbyte compared to the 00158 * size of buf is ignored. The default YES assumes that the 00159 * check is done. 00160 */ 00161 strread = getenv("PXFREAD_CONFORM"); 00162 if (strread != NULL) { 00163 if (strcmp(strread, "NO") == 0) 00164 skipconform = 1; 00165 } 00166 /* return an error if no memory allocated. */ 00167 if (buffr == NULL) 00168 errsts = ENOMEM; 00169 else { 00170 wasread = read(*ifildes, buffr, toberead); 00171 if ((int)wasread < 0) 00172 errsts = errno; 00173 else { 00174 /* In Fortran 77, a variable was not an array. 00175 * Therefore, buf cannot be more than a 00176 * character scalar in the 1003.9 standard. 00177 * Fortran 90 extended the definition of 00178 * variable to include an array. 00179 * 00180 * Extend PXFREAD to allow nbyte to be greater 00181 * than the size of buf to allow buf to be an 00182 * array. A subroutine interface does not pass 00183 * the number of elements in the array and 00184 * overindexing is legal in Fortran. Sections 00185 * will be contiguous when passed. 00186 * 00187 */ 00188 00189 /* Prevent copy from going beyond string. */ 00190 if (skipconform == 0 && (int)wasread > string_len) { 00191 errsts = ETRUNC; 00192 copy_len = (size_t)string_len; 00193 } else 00194 copy_len = wasread; 00195 /* copy input buffer to string and blank fill */ 00196 (void) memcpy(_fcdtocp(buf), buffr, copy_len); 00197 if (string_len > (int)copy_len) { 00198 (void) memset(_fcdtocp(buf) + 00199 sizeof(char) * (int)copy_len, BLANK, 00200 (string_len - (int)copy_len) * sizeof(char)); 00201 } 00202 } 00203 /* return untruncated read size */ 00204 *nread = (_f_int)wasread; 00205 free(buffr); 00206 } 00207 *ierror = (_f_int)errsts; 00208 return; 00209 } 00210 00211 #ifndef _UNICOS 00212 /* assume default integer */ 00213 void 00214 pxfread_( 00215 _f_int *ifildes, 00216 char *buf, 00217 _f_int *nbyte, 00218 _f_int *nread, 00219 _f_int *ierror, 00220 int lenbuf) 00221 { 00222 _PXFREAD(ifildes, _cptofcd(buf, lenbuf), nbyte, nread, ierror); 00223 } 00224 00225 /* assume integer(kind=8) */ 00226 void 00227 pxfread64_( 00228 _f_int8 *ifildes, 00229 char *buf, 00230 _f_int8 *nbyte, 00231 _f_int8 *nread, 00232 _f_int8 *ierror, 00233 int lenbuf) 00234 { 00235 _f_int ifildes4; 00236 _f_int nbyte4; 00237 _f_int nread4; 00238 _f_int ierror4; 00239 ifildes4 = *ifildes; 00240 nbyte4 = *nbyte; 00241 _PXFREAD(&ifildes4, _cptofcd(buf, lenbuf), &nbyte4, 00242 &nread4, &ierror4); 00243 *nread = nread4; 00244 *ierror = ierror4; 00245 } 00246 #elif defined(_UNICOS) && defined(_CRAYMPP) 00247 /* assume integer(kind=4) arguments and default 64-bit integer */ 00248 void 00249 PXFREAD32( 00250 _f_int4 *ifildes, 00251 _fcd buf, 00252 _f_int4 *nbyte, 00253 _f_int4 *nread, 00254 _f_int4 *ierror) 00255 { 00256 _f_int ifildes8; 00257 _f_int nbyte8; 00258 _f_int nread8; 00259 _f_int ierror8; 00260 ifildes8 = *ifildes; 00261 nbyte8 = *nbyte; 00262 PXFREAD(&ifildes8, buf, &nbyte8, &nread8, &ierror8); 00263 *nread = nread8; 00264 *ierror = ierror8; 00265 } 00266 #endif /* end _UNICOS and _CRAYMPP */
1.5.6