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
00040
00041
00042 #pragma ident "@(#) libf/fio/open.c 92.3 08/02/99 10:37:16"
00043
00044 #include <sys/param.h>
00045 #include <string.h>
00046 #include <stdlib.h>
00047 #include <errno.h>
00048 #include <liberrno.h>
00049 #include <fcntl.h>
00050 #include <unistd.h>
00051 #include <cray/assign.h>
00052 #include <sys/stat.h>
00053 #include <stdio.h>
00054 #include "fio.h"
00055
00056 #define FERROR(cond, n) { \
00057 if (!cond) \
00058 _ferr(css, n); \
00059 else \
00060 return(n); \
00061 }
00062
00063 #define FERROR1(cond, n, p) { \
00064 if (!cond) \
00065 _ferr(css, n, p); \
00066 else \
00067 return(n); \
00068 }
00069
00070 static void freeit(void *);
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 int
00099 _f_open(
00100 FIOSPTR css,
00101 unit **cup_p,
00102
00103 olist *olptr,
00104 int isf90)
00105 {
00106 register short is_bin;
00107 register short is_fmt;
00108 register short is_seq;
00109 register short is_sys;
00110 register short no_mem;
00111 register int aifound;
00112 register int errn;
00113 register int gamask;
00114 register int oflags;
00115 register int P_value;
00116 register int stdfn;
00117 register int stdfnum;
00118 register int stat_ok;
00119 register int tufs;
00120 register int uscope;
00121 register unum_t unum;
00122 char namebuf[MXUNITSZ];
00123 char *fname;
00124 char *aname;
00125 char *atstr;
00126 unit *cup;
00127 assign_info ai;
00128 struct stat statbuf;
00129
00130 unum = olptr->ounit;
00131
00132 if (! GOOD_UNUM(unum))
00133 FERROR1(olptr->oerr, FEIVUNIT, unum);
00134
00135
00136
00137
00138 if (OPEN_UPTR(*cup_p)) {
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 errn = _unit_close(*cup_p, CLST_UNSPEC, NULL);
00150
00151 if (errn != 0)
00152 FERROR(olptr->oerr, errn);
00153
00154 _release_cup(*cup_p);
00155 }
00156
00157
00158
00159
00160
00161
00162
00163 aname = NULL;
00164 fname = NULL;
00165 stdfn = 0;
00166 no_mem = 0;
00167
00168 if (olptr->ofile == NULL) {
00169
00170 if (olptr->ostatus == OS_SCRATCH) {
00171 int scratchfd;
00172
00173
00174
00175 fname = NULL;
00176 aname = strdup("FXXXXXX");
00177 scratchfd = mkstemp(aname);
00178 close(scratchfd);
00179 }
00180 else if (unum == 0 || unum == 5 || unum == 6 ||
00181 RSVD_UNUM(unum)) {
00182 stdfn = 1;
00183 stdfnum = -1;
00184
00185 switch (unum) {
00186
00187 case 5:
00188 case 100:
00189 stdfnum = STDIN_FILENO;
00190 break;
00191 case 6:
00192 case 101:
00193 stdfnum = STDOUT_FILENO;
00194 break;
00195 case 0:
00196 case 102:
00197 stdfnum = fileno(errfile);
00198 break;
00199 default:
00200 _ferr(css, FEINTUNK);
00201 }
00202 }
00203 else {
00204
00205 (void) _fortname(namebuf, unum);
00206
00207 fname = strdup(namebuf);
00208 aname = strdup(namebuf);
00209 no_mem = (aname == NULL) || (fname == NULL);
00210 }
00211 }
00212 else {
00213 if ((fname = malloc(olptr->ofilelen + 1)) != NULL) {
00214 _copy_n_trim(olptr->ofile, olptr->ofilelen, fname);
00215 aname = strdup(fname);
00216 }
00217
00218 no_mem = (aname == NULL) || (fname == NULL);
00219 }
00220
00221 if (no_mem) {
00222
00223 freeit(aname);
00224 freeit(fname);
00225
00226 FERROR(olptr->oerr, FENOMEMY);
00227 }
00228
00229
00230 is_bin = (olptr->oform == OS_BINARY) ? 1 : 0;
00231 is_fmt = (olptr->oform == OS_FORMATTED) ? 1 : 0;
00232 is_seq = (olptr->oaccess == OS_SEQUENTIAL ? 1 : 0);
00233 is_sys = (olptr->oform == OS_SYSTEM) ? 1 : 0;
00234
00235
00236
00237
00238 switch ((is_seq << 3) | is_fmt) {
00239
00240 case 011:
00241 gamask = ASN_G_SF;
00242 break;
00243
00244 case 010:
00245 gamask = ASN_G_SU;
00246 break;
00247
00248 case 001:
00249 gamask = ASN_G_DF;
00250 break;
00251
00252 case 000:
00253 gamask = ASN_G_DU;
00254 break;
00255 }
00256
00257 gamask = gamask | ASN_G_ALL;
00258 atstr = NULL;
00259 aifound = _assign_asgcmd_info(fname, unum, gamask, &ai, &atstr,
00260 olptr->oerr);
00261 #ifdef KEY
00262
00263
00264
00265
00266
00267
00268 if (!is_seq) {
00269 ai.F_filter_flg = 0;
00270 }
00271 #endif
00272
00273 if (aifound == -1) {
00274 freeit(fname);
00275 freeit(aname);
00276 freeit(atstr);
00277 FERROR(olptr->oerr, errno);
00278 }
00279
00280
00281
00282
00283 uscope = AS_PROCESS;
00284 P_value = AS_PROCESS;
00285
00286 if (aifound == 1 && ai.P_ioscop_flg) {
00287 uscope = ai.P_ioscop;
00288 P_value = ai.P_ioscop;
00289
00290 #ifdef _CRAYMPP
00291 if (ai.P_ioscop == AS_PRIVATE)
00292 uscope = AS_PROCESS;
00293 #else
00294 if (ai.P_ioscop == AS_PRIVATE)
00295 uscope = AS_THREAD;
00296
00297 if (ai.P_ioscop == AS_GLOBAL)
00298 uscope = AS_PROCESS;
00299 #endif
00300 }
00301
00302 #ifdef _CRAYMPP
00303 if (uscope == AS_GLOBAL)
00304 FERROR(olptr->oerr, FENOGLOB);
00305
00306 if (uscope == AS_THREAD)
00307 FERROR(olptr->oerr, FENOTHRD);
00308
00309 if (uscope == AS_TEAM)
00310 FERROR(olptr->oerr, FENOTEAM);
00311 #else
00312 if (uscope == AS_TEAM)
00313 FERROR(olptr->oerr, FENOTEAM);
00314 #endif
00315
00316
00317
00318
00319
00320 #ifdef _CRAYMPP
00321 cup = _alloc_unit(unum, 1);
00322 #else
00323 cup = _alloc_unit(unum, (uscope == AS_THREAD));
00324 #endif
00325 if (cup == NULL)
00326 FERROR1(olptr->oerr, errno, unum);
00327
00328 *cup_p = cup;
00329
00330
00331
00332
00333 cup->ubinary = is_bin;
00334 cup->ufmt = is_fmt;
00335 cup->useq = is_seq;
00336 cup->usystem = is_sys;
00337 cup->ublnk = (olptr->oblank == OS_ZERO ? 1 : 0);
00338 cup->uposition = olptr->oposition;
00339 cup->uaction = olptr->oaction;
00340 cup->udelim = olptr->odelim;
00341 cup->upad = olptr->opad;
00342 cup->urecl = olptr->orecl;
00343
00344
00345
00346
00347 cup->uft90 = isf90;
00348
00349 if (aifound == 1 && ai.a_actfil_flg) {
00350 stdfn = 0;
00351
00352 freeit(aname);
00353 aname = strdup(ai.a_actfil);
00354
00355 if (aname == NULL) {
00356 freeit(atstr);
00357 freeit(fname);
00358 FERROR(olptr->oerr, FENOMEMY);
00359 }
00360 }
00361
00362 if (aifound == 1 && ai.D_fildes_flg) {
00363 stdfn = 1;
00364 stdfnum = ai.D_fildes;
00365
00366 freeit(aname);
00367 aname = NULL;
00368 }
00369
00370
00371
00372
00373
00374 #ifdef _CRAYMPP
00375 if (stdfn && uscope == AS_TEAM) {
00376 freeit(fname);
00377 freeit(aname);
00378 freeit(atstr);
00379 FERROR(olptr->oerr, FENOTEAM);
00380 }
00381 #else
00382 if (stdfn && uscope == AS_THREAD) {
00383 freeit(fname);
00384 freeit(aname);
00385 freeit(atstr);
00386 FERROR(olptr->oerr, (P_value==AS_PRIVATE)? FENOPRIV: FENOTHRD);
00387 }
00388 #endif
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399 if (cup->ufmt) {
00400
00401 if (cup->urecl > 0) {
00402 cup->urecsize = cup->urecl;
00403 cup->uldwsize = cup->urecl;
00404 }
00405 else {
00406 cup->urecsize = _f_rcsz;
00407 cup->uldwsize = _f_ldsz;
00408 }
00409
00410
00411
00412 cup->ulinebuf = (long *) malloc(sizeof(long) *
00413 (cup->urecsize + 1));
00414
00415 if (cup->ulinebuf == NULL) {
00416 freeit(fname);
00417 freeit(aname);
00418 freeit(atstr);
00419 FERROR(olptr->oerr, FENOMEMY);
00420 }
00421 }
00422
00423
00424
00425
00426
00427 errn = 0;
00428 stat_ok = 0;
00429
00430 if (stdfn) {
00431 errn = fstat(stdfnum, &statbuf);
00432 stat_ok = 1;
00433 }
00434 else if (aifound == 0 || ai.F_filter_flg == 0) {
00435 errn = stat(aname, &statbuf);
00436 stat_ok = 1;
00437 }
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450 if (stat_ok && errn == -1) {
00451 register short retry = 0;
00452
00453 while (errn == -1 && errno == EINTR && retry++ < 10) {
00454 if (stdfn)
00455 errn = fstat(stdfnum, &statbuf);
00456 else
00457 errn = stat(aname, &statbuf);
00458 }
00459
00460 if (errn == -1) {
00461
00462 stat_ok = 0;
00463
00464 if (errno != ENOENT) {
00465 freeit(fname);
00466 freeit(aname);
00467 freeit(atstr);
00468 freeit(cup->ulinebuf);
00469 FERROR(olptr->oerr, errno);
00470 }
00471 }
00472 }
00473
00474
00475
00476 if (aifound == 1 && (ai.s_fstrct_flg || ai.F_filter_flg)) {
00477 if (ai.F_filter_flg)
00478 tufs = FS_FDC;
00479 else
00480 tufs = ai.s_fstrct;
00481 }
00482 else {
00483
00484
00485 if ( cup->ufmt )
00486 #if defined(__mips) || defined(_LITTLE_ENDIAN)
00487 tufs = (cup->useq) ? FS_TEXT : FS_UNBLOCKED;
00488 #else
00489 tufs = FS_TEXT;
00490 #endif
00491 else {
00492 #ifdef _UNICOS
00493 tufs = (cup->useq) ? FS_COS : FS_UNBLOCKED;
00494 #else
00495 tufs = (cup->useq) ? FS_F77 : FS_UNBLOCKED;
00496 #endif
00497 if (is_bin || is_sys) {
00498
00499
00500
00501
00502
00503
00504 tufs = FS_UNBLOCKED;
00505 }
00506
00507 }
00508
00509
00510
00511 if (stat_ok && _gsys_qtape(&statbuf) != 0)
00512 tufs = FS_TAPE;
00513 }
00514
00515
00516
00517
00518
00519
00520 if (stdfn) {
00521 FILE *stdf;
00522
00523 #if defined(BUILD_OS_DARWIN)
00524 switch(stdfnum) {
00525 case(STDIN_FILENO):
00526 stdf = stdin;
00527 break;
00528 case(STDOUT_FILENO):
00529 stdf = stdout;
00530 break;
00531 default:
00532 stdf = stderr;
00533 break;
00534 }
00535 #elif defined(_LITTLE_ENDIAN) && !defined(__sv2)
00536
00537
00538
00539 switch(stdfnum) {
00540 case(STDIN_FILENO):
00541 stdf = _IO_stdin;
00542 break;
00543 case(STDOUT_FILENO):
00544 stdf = _IO_stdout;
00545 break;
00546 default:
00547 stdf = _IO_stderr;
00548 break;
00549 }
00550 #else
00551 stdf = &__iob[stdfnum];
00552 #endif
00553
00554 if (!cup->useq || !cup->ufmt ||
00555 (tufs != FS_TEXT && tufs != STD)) {
00556 freeit(fname);
00557 freeit(aname);
00558 freeit(atstr);
00559 freeit(cup->ulinebuf);
00560 FERROR(olptr->oerr, FEOPSTFN);
00561 }
00562
00563 if (stdfnum < STDIN_FILENO || stdfnum > STDERR_FILENO) {
00564
00565
00566 freeit(fname);
00567 freeit(aname);
00568 freeit(atstr);
00569 freeit(cup->ulinebuf);
00570 FERROR(olptr->oerr,FEINTUNK);
00571 }
00572
00573 if (fileno(stdf) != stdfnum) {
00574
00575
00576 freeit(fname);
00577 freeit(aname);
00578 freeit(atstr);
00579 freeit(cup->ulinebuf);
00580 FERROR(olptr->oerr,FEINTUNK);
00581 }
00582
00583 cup->ufp.std = stdf;
00584
00585
00586
00587
00588
00589 switch (stdfnum) {
00590 case STDIN_FILENO:
00591 cup->auxlockp = &_stdin_lock;
00592 break;
00593
00594 case STDOUT_FILENO:
00595 cup->auxlockp = &_stdout_lock;
00596 break;
00597
00598 case STDERR_FILENO:
00599 cup->auxlockp = &_stderr_lock;
00600 break;
00601 }
00602
00603
00604
00605
00606
00607 freeit(aname);
00608 freeit(fname);
00609 aname = NULL;
00610 fname = NULL;
00611 }
00612
00613
00614
00615
00616
00617
00618 cup->ufnm = fname;
00619 cup->alfnm = aname;
00620 cup->uid = unum;
00621
00622
00623
00624 cup->uostatus = olptr->ostatus;
00625
00626 switch (olptr->ostatus) {
00627
00628 case OS_UNKNOWN:
00629 default:
00630 oflags = O_CREAT;
00631 break;
00632
00633 case OS_SCRATCH:
00634 cup->uscrtch = 1;
00635 oflags = O_CREAT;
00636 break;
00637
00638 case OS_OLD:
00639 oflags = 0;
00640 break;
00641
00642 case OS_NEW:
00643
00644
00645 if (stat_ok && !S_ISCHR(statbuf.st_mode) &&
00646 !S_ISFIFO(statbuf.st_mode)) {
00647 freeit(fname);
00648 freeit(aname);
00649 freeit(atstr);
00650 freeit(cup->ulinebuf);
00651 FERROR(olptr->oerr, FEOPFNNX);
00652 }
00653
00654 cup->uostatus = OS_OLD;
00655
00656 oflags = O_EXCL | O_CREAT;
00657 break;
00658
00659 case OS_REPLACE:
00660
00661
00662
00663
00664
00665
00666 cup->uostatus = OS_OLD;
00667
00668 #ifdef KEY
00669
00670
00671
00672
00673
00674
00675 oflags = O_CREAT | O_TRUNC;
00676 #else
00677 oflags = O_CREAT;
00678 #endif
00679 break;
00680
00681 }
00682
00683
00684
00685 errn = _f_opn(aname, cup, css, tufs, aifound, &ai, &statbuf,
00686 stat_ok, olptr->oerr, oflags);
00687
00688 if (errn != OK) {
00689 errn = errno;
00690
00691
00692
00693 if (errn == EEXIST)
00694 errn = FEOPFNNX;
00695
00696 goto open_error;
00697 }
00698
00699 #ifdef _CRAYMPP
00700
00701 if (stdfn)
00702 cup->utrunc = 0;
00703 #endif
00704
00705
00706
00707
00708 _set_device_and_inode(cup->usysfd, &cup->udevice, &cup->uinode);
00709
00710 errn = _uniqinod(cup, (aifound ? &ai : NULL));
00711
00712 if (errn != 0)
00713 goto open_error;
00714
00715
00716
00717
00718
00719 errn = _mixed_scope(cup);
00720
00721 if (errn != 0)
00722 goto open_error;
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733 if (olptr->ostatus == OS_REPLACE) {
00734 errn = _unit_trunc(cup);
00735
00736 if (errn != 0)
00737 goto open_error;
00738
00739
00740
00741
00742
00743
00744
00745 if (cup->ufs == FS_FDC) {
00746 struct ffsw fst;
00747
00748 XRCALL(cup->ufp.fdc, seekrtn) cup->ufp.fdc, 0, 0, &fst);
00749 }
00750
00751 cup->udamax = 0;
00752 }
00753
00754
00755
00756
00757 switch (cup->uposition) {
00758
00759 case OS_REWIND:
00760 case OS_ASIS:
00761 break;
00762
00763 case OS_APPEND:
00764
00765
00766 {
00767 int neg1;
00768
00769
00770
00771 if (cup->useek) {
00772
00773 neg1 = -1;
00774 errn = _setpos(css, cup, &neg1, 1);
00775
00776 if (errn != 0)
00777 goto open_error;
00778
00779 errn = _unit_bksp(cup);
00780
00781 if (errn != 0)
00782 goto open_error;
00783 }
00784 }
00785 break;
00786
00787 }
00788
00789
00790
00791
00792 if (cup->utmpfil) {
00793 errn = _unit_scratch(cup);
00794
00795 if (errn != 0)
00796 goto open_error;
00797 }
00798
00799
00800
00801
00802 _set_ok_flags(cup);
00803
00804 if (FORTSTATS) {
00805
00806
00807
00808 if (_ft_stopen(cup, atstr) == -1) {
00809 errn = errno;
00810 goto open_error;
00811 }
00812 }
00813
00814 freeit(atstr);
00815
00816
00817
00818
00819
00820
00821 if (cup->auxlockp != NULL)
00822 MEM_LOCK(cup->auxlockp);
00823
00824 return(0);
00825
00826
00827
00828 open_error:
00829 freeit(atstr);
00830 (void)_unit_close(cup, CLST_UNSPEC, NULL);
00831
00832 FERROR(olptr->oerr, errn);
00833
00834 return(0);
00835 }
00836
00837
00838
00839
00840 static void
00841 freeit(void *ptr)
00842 {
00843 if (ptr != NULL)
00844 free(ptr);
00845 }
00846
00847
00848
00849
00850
00851
00852
00853
00854 void
00855 _set_ok_flags(unit *cup)
00856 {
00857 cup->ok_wr_seq_fmt = _get_mismatch_error(1, T_WSF, cup, NULL) == 0;
00858 cup->ok_wr_seq_unf = _get_mismatch_error(1, T_WSU, cup, NULL) == 0;
00859 cup->ok_wr_dir_fmt = _get_mismatch_error(1, T_WDF, cup, NULL) == 0;
00860 cup->ok_wr_dir_unf = _get_mismatch_error(1, T_WDU, cup, NULL) == 0;
00861
00862 cup->ok_rd_seq_fmt = _get_mismatch_error(1, T_RSF, cup, NULL) == 0;
00863 cup->ok_rd_seq_unf = _get_mismatch_error(1, T_RSU, cup, NULL) == 0;
00864 cup->ok_rd_dir_fmt = _get_mismatch_error(1, T_RDF, cup, NULL) == 0;
00865 cup->ok_rd_dir_unf = _get_mismatch_error(1, T_RDU, cup, NULL) == 0;
00866
00867 return;
00868 }
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886 int
00887 _get_mismatch_error(
00888 int noabort,
00889 int iost,
00890 unit *cup,
00891 FIOSPTR css)
00892
00893 {
00894 register int errn = 0;
00895
00896 if (cup->ufs == FS_AUX) {
00897 errn = FEMIXAUX;
00898 goto ret;
00899 }
00900
00901
00902
00903 if (iost & TF_WRITE) {
00904 if ((cup->uaction & OS_WRITE) == 0) {
00905 errn = FENOWRIT;
00906 goto ret;
00907 }
00908 }
00909 else {
00910 if ((cup->uaction & OS_READ) == 0) {
00911 errn = FENOREAD;
00912 goto ret;
00913 }
00914 }
00915
00916
00917
00918 if (iost & TF_FMT) {
00919 if (!cup->ufmt) {
00920 errn = FEFMTTIV;
00921 goto ret;
00922 }
00923 }
00924 else {
00925 if (cup->ufmt) {
00926 errn = FEUNFMIV;
00927 goto ret;
00928 }
00929 }
00930
00931
00932
00933 if (iost == T_WDF || iost == T_WDU || iost == T_RDF || iost == T_RDU) {
00934 if (cup->useq) {
00935 errn = FEDIRTIV;
00936 goto ret;
00937 }
00938 } else {
00939 if (cup->useq == 0) {
00940 errn = FESEQTIV;
00941 goto ret;
00942 }
00943 }
00944
00945 ret:
00946 if (noabort)
00947 return(errn);
00948 else {
00949 if (errn == 0)
00950 errn = FEINTUNK;
00951
00952 _ferr(css, errn);
00953 }
00954
00955 return(FEINTUNK);
00956 }
00957
00958 #ifdef _UNICOS
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974 void
00975 __fio_hardrefs()
00976 {
00977 (void) _finit();
00978
00979
00980
00981 #if defined(_CRAY1)
00982 (void) _repriev();
00983
00984
00985
00986 #endif
00987 }
00988
00989 #endif