00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <sys/types.h>
00040 #include <sys/stat.h>
00041 #include <stdlib.h>
00042 #include <string.h>
00043 #include <limits.h>
00044 #include <mutex.h>
00045 #include <cmplrs/fio.h>
00046 #include <sys/prctl.h>
00047 #undef uint
00048 #include "iomode.h"
00049 #include "err.h"
00050 #include "util.h"
00051 #include "bcompat.h"
00052
00053 static unsigned long io_lock;
00054
00055 char *_I90_uppercase( char *name, char *uname )
00056 {
00057 int i;
00058
00059 for (i = 0; name[i] && i < PATH_MAX; i++)
00060 uname[i] = (char) ((name[i] >= 'a' && name[i] <= 'z') ? name[i]+'A'-'a' : name[i]);
00061 if (i < PATH_MAX-1) {
00062 uname[i] = '\0';
00063 return(uname);
00064 } else return((char *) 0);
00065 }
00066
00067 int
00068 f77inode (char *a, ino_t *inod)
00069 {
00070 struct stat x;
00071 char uname[PATH_MAX];
00072
00073 if (a[3] == '$' && _I90_uppercase(a, uname) &&
00074 (!strcmp (uname, "SYS$INPUT") || !strcmp (uname, "SYS$OUTPUT") ||
00075 !strcmp (uname, "SYS$ERROR")))
00076 return (0);
00077
00078 #ifdef SHLIB
00079 if ((*_libI77_stat) (a, &x) < 0)
00080 return (-1);
00081 #else
00082 if (stat (a, &x) < 0)
00083 return (-1);
00084 #endif
00085 *inod = x.st_ino;
00086 return (1);
00087 }
00088
00089
00090
00091
00092
00093 unit *
00094 map_luno(ftnint luno)
00095 {
00096 register int i, space_available;
00097 register unit *a;
00098 static unit *f77curunit = 0;
00099 unit *ftnunit;
00100 static unsigned long expand_table_lock = 0;
00101
00102 if (!f77init)
00103 f_init ();
00104
00105
00106
00107
00108 if (f77curunit) {
00109 ftnunit = f77curunit;
00110 if (ftnunit->luno == luno && ftnunit->uconn) {
00111 return (ftnunit);
00112 }
00113 }
00114
00115
00116 for (i = 0, a = f77units; i < space_assigned; i++, a++) {
00117 if (a->luno == luno && a->uconn) {
00118 return (a);
00119 }
00120 }
00121
00122
00123
00124
00125 while (test_and_set( &expand_table_lock, 1L ))
00126 ;
00127
00128
00129
00130
00131
00132 for (i = 0, a = f77units; i < space_assigned; i++, a++)
00133 if (a->uconn == 0) {
00134 space_available = i;
00135 goto unused_slot;
00136 }
00137 if (space_assigned >= mxunit) {
00138 int old_mxunit = mxunit;
00139 int ii, nthreads;
00140
00141
00142
00143
00144
00145
00146
00147 nthreads = prctl( PR_GETNSHARE );
00148 if (nthreads > 1) {
00149
00150
00151
00152 fprintf( stderr, "Exceeding %d opened files while running in MP I/O mode, please set the environment FORTRAN_OPENED_UNITS to a higher number then rerun the program\n", mxunit );
00153 abort();
00154 }
00155 i = mxunit;
00156 f77curunit = f77units = (unit *) realloc (f77units, (mxunit <<= 1) *
00157 (sizeof (unit)));
00158 memset( &f77units[i], 0, (size_t) i*(sizeof (unit)) );
00159 if (f77units == 0) {
00160 expand_table_lock = 0;
00161 return (NULL);
00162 }
00163
00164 for (ii = 0, a = f77units; ii < old_mxunit; ii++, a++)
00165 if (a->luno == -1) {
00166 Internal_File = a;
00167 break;
00168 }
00169 space_assigned = old_mxunit;
00170 }
00171 space_available = space_assigned++;
00172 unused_slot:
00173
00174 a = f77units + space_available;
00175
00176
00177 memset (a, '\0', sizeof (unit));
00178 a->luno = luno;
00179 a->uconn = -1;
00180
00181 a->ualias = a;
00182 f77curunit = a;
00183 expand_table_lock = 0;
00184 return (a);
00185 }
00186
00187
00188
00189 unit *
00190 find_luno(ftnint luno)
00191 {
00192 register int i;
00193 register unit *a;
00194 static unit *f77curunit = 0;
00195 unit *ftnunit;
00196
00197 if (!f77init)
00198 f_init ();
00199 if (f77curunit) {
00200 ftnunit = f77curunit;
00201 if (ftnunit->luno == luno && ftnunit->uconn > 0)
00202 return (ftnunit);
00203 }
00204 for (i = 0, a = f77units; i < space_assigned; i++, a++)
00205
00206 if (a->luno == luno)
00207 return (a);
00208 return (NULL);
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 int
00240 f77nowreading (unit *x)
00241 {
00242 XINT64 loc;
00243 FILE *nfd;
00244
00245 if (x->uacc == KEYED) goto read_mode;
00246 if (!(x->uwrt & WR_OP))
00247 return(0);
00248 if (x->uwrt == WR_OP) {
00249
00250 loc = FTELL (x->ufd);
00251 if (!loc) {
00252
00253 while (test_and_set( &io_lock, 1L ))
00254 ;
00255 nfd = freopen (x->ufnm, "r", x->ufd);
00256 io_lock = 0;
00257 if (!nfd)
00258 return(1);
00259 } else {
00260
00261 while (test_and_set( &io_lock, 1L ))
00262 ;
00263 nfd = freopen (x->ufnm, "r+", x->ufd);
00264 io_lock = 0;
00265 if (!nfd)
00266 return (1);
00267 x->uwrt = WR_READY;
00268 FSEEK (x->ufd, loc, SEEK_SET);
00269 }
00270 }
00271 else
00272 fseek (x->ufd, 0L, SEEK_CUR);
00273 read_mode:
00274 x->uwrt &= ~WR_OP;
00275 return (0);
00276 }
00277
00278 int
00279 f77nowwriting (unit *x)
00280 {
00281 XINT64 loc;
00282 FILE *nfd;
00283
00284 #ifdef I90
00285 if (x->ureadonly || x->uaction == READONLY) {
00286 #else
00287 if (x->ureadonly) {
00288 #endif
00289 x->uwrt |= WR_OP;
00290 return (1);
00291 }
00292 if (x->uacc == KEYED) goto write_mode;
00293 if (x->uwrt & WR_OP)
00294 return(0);
00295 if ((x->uwrt & RW_FILE) == 0) {
00296 loc = FTELL (x->ufd);
00297 if (!loc && x->uacc == SEQUENTIAL) {
00298
00299 while (test_and_set( &io_lock, 1L ))
00300 ;
00301 nfd = freopen (x->ufnm, "w", x->ufd);
00302 io_lock = 0;
00303 if (!nfd)
00304 return(1);
00305 } else {
00306
00307 while (test_and_set( &io_lock, 1L ))
00308 ;
00309 nfd = freopen (x->ufnm, "r+", x->ufd);
00310 io_lock = 0;
00311 if (nfd)
00312 x->uwrt = WR_READY;
00313 else {
00314
00315 while (test_and_set( &io_lock, 1L ))
00316 ;
00317 nfd = freopen (x->ufnm, "w+", x->ufd);
00318 io_lock = 0;
00319 if (!nfd)
00320 return (1);
00321 }
00322 #ifdef I90
00323
00324
00325 if ( x->f90sw == 1 && x->f90nadv == 1 ) {
00326 loc = loc - (long)(x->f77recend + 1) + (long)x->f77recpos;
00327 }
00328 #endif
00329 FSEEK (x->ufd, loc, SEEK_SET);
00330 }
00331 } else {
00332 fseek (x->ufd, 0L, SEEK_CUR);
00333 }
00334
00335 write_mode:
00336 x->uwrt |= WR_OP;
00337 return (0);
00338 }