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 #pragma ident "@(#) libf/fio/open.c 92.3 08/02/99 10:37:16"
00039
00040 #include <sys/param.h>
00041 #include <string.h>
00042 #ifdef _ABSOFT
00043 #include <stdlib.h>
00044 #else
00045 #include <malloc.h>
00046 #endif
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
00262 if (aifound == -1) {
00263 freeit(fname);
00264 freeit(aname);
00265 freeit(atstr);
00266 FERROR(olptr->oerr, errno);
00267 }
00268
00269
00270
00271
00272 uscope = AS_PROCESS;
00273 P_value = AS_PROCESS;
00274
00275 if (aifound == 1 && ai.P_ioscop_flg) {
00276 uscope = ai.P_ioscop;
00277 P_value = ai.P_ioscop;
00278
00279 #ifdef _CRAYMPP
00280 if (ai.P_ioscop == AS_PRIVATE)
00281 uscope = AS_PROCESS;
00282 #else
00283 if (ai.P_ioscop == AS_PRIVATE)
00284 uscope = AS_THREAD;
00285
00286 if (ai.P_ioscop == AS_GLOBAL)
00287 uscope = AS_PROCESS;
00288 #endif
00289 }
00290
00291 #ifdef _CRAYMPP
00292 if (uscope == AS_GLOBAL)
00293 FERROR(olptr->oerr, FENOGLOB);
00294
00295 if (uscope == AS_THREAD)
00296 FERROR(olptr->oerr, FENOTHRD);
00297
00298 if (uscope == AS_TEAM)
00299 FERROR(olptr->oerr, FENOTEAM);
00300 #else
00301 if (uscope == AS_TEAM)
00302 FERROR(olptr->oerr, FENOTEAM);
00303 #endif
00304
00305
00306
00307
00308
00309 #ifdef _CRAYMPP
00310 cup = _alloc_unit(unum, 1);
00311 #else
00312 cup = _alloc_unit(unum, (uscope == AS_THREAD));
00313 #endif
00314 if (cup == NULL)
00315 FERROR1(olptr->oerr, errno, unum);
00316
00317 *cup_p = cup;
00318
00319
00320
00321
00322 cup->ubinary = is_bin;
00323 cup->ufmt = is_fmt;
00324 cup->useq = is_seq;
00325 cup->usystem = is_sys;
00326 cup->ublnk = (olptr->oblank == OS_ZERO ? 1 : 0);
00327 cup->uposition = olptr->oposition;
00328 cup->uaction = olptr->oaction;
00329 cup->udelim = olptr->odelim;
00330 cup->upad = olptr->opad;
00331 cup->urecl = olptr->orecl;
00332
00333
00334
00335
00336 cup->uft90 = isf90;
00337
00338 if (aifound == 1 && ai.a_actfil_flg) {
00339 stdfn = 0;
00340
00341 freeit(aname);
00342 aname = strdup(ai.a_actfil);
00343
00344 if (aname == NULL) {
00345 freeit(atstr);
00346 freeit(fname);
00347 FERROR(olptr->oerr, FENOMEMY);
00348 }
00349 }
00350
00351 if (aifound == 1 && ai.D_fildes_flg) {
00352 stdfn = 1;
00353 stdfnum = ai.D_fildes;
00354
00355 freeit(aname);
00356 aname = NULL;
00357 }
00358
00359
00360
00361
00362
00363 #ifdef _CRAYMPP
00364 if (stdfn && uscope == AS_TEAM) {
00365 freeit(fname);
00366 freeit(aname);
00367 freeit(atstr);
00368 FERROR(olptr->oerr, FENOTEAM);
00369 }
00370 #else
00371 if (stdfn && uscope == AS_THREAD) {
00372 freeit(fname);
00373 freeit(aname);
00374 freeit(atstr);
00375 FERROR(olptr->oerr, (P_value==AS_PRIVATE)? FENOPRIV: FENOTHRD);
00376 }
00377 #endif
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388 if (cup->ufmt) {
00389
00390 if (cup->urecl > 0) {
00391 cup->urecsize = cup->urecl;
00392 cup->uldwsize = cup->urecl;
00393 }
00394 else {
00395 cup->urecsize = _f_rcsz;
00396 cup->uldwsize = _f_ldsz;
00397 }
00398
00399
00400
00401 cup->ulinebuf = (long *) malloc(sizeof(long) *
00402 (cup->urecsize + 1));
00403
00404 if (cup->ulinebuf == NULL) {
00405 freeit(fname);
00406 freeit(aname);
00407 freeit(atstr);
00408 FERROR(olptr->oerr, FENOMEMY);
00409 }
00410 }
00411
00412
00413
00414
00415
00416 errn = 0;
00417 stat_ok = 0;
00418
00419 if (stdfn) {
00420 errn = fstat(stdfnum, &statbuf);
00421 stat_ok = 1;
00422 }
00423 else if (aifound == 0 || ai.F_filter_flg == 0) {
00424 errn = stat(aname, &statbuf);
00425 stat_ok = 1;
00426 }
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439 if (stat_ok && errn == -1) {
00440 register short retry = 0;
00441
00442 while (errn == -1 && errno == EINTR && retry++ < 10) {
00443 if (stdfn)
00444 errn = fstat(stdfnum, &statbuf);
00445 else
00446 errn = stat(aname, &statbuf);
00447 }
00448
00449 if (errn == -1) {
00450
00451 stat_ok = 0;
00452
00453 if (errno != ENOENT) {
00454 freeit(fname);
00455 freeit(aname);
00456 freeit(atstr);
00457 freeit(cup->ulinebuf);
00458 FERROR(olptr->oerr, errno);
00459 }
00460 }
00461 }
00462
00463
00464
00465 if (aifound == 1 && (ai.s_fstrct_flg || ai.F_filter_flg)) {
00466 if (ai.F_filter_flg)
00467 tufs = FS_FDC;
00468 else
00469 tufs = ai.s_fstrct;
00470 }
00471 else {
00472
00473
00474 if ( cup->ufmt )
00475 #if defined(__mips) || defined(_LITTLE_ENDIAN)
00476 tufs = (cup->useq) ? FS_TEXT : FS_UNBLOCKED;
00477 #else
00478 tufs = FS_TEXT;
00479 #endif
00480 else {
00481 #ifdef _UNICOS
00482 tufs = (cup->useq) ? FS_COS : FS_UNBLOCKED;
00483 #else
00484 tufs = (cup->useq) ? FS_F77 : FS_UNBLOCKED;
00485 #endif
00486 if (is_bin || is_sys) {
00487
00488
00489
00490
00491
00492
00493 tufs = FS_UNBLOCKED;
00494 }
00495
00496 }
00497
00498
00499
00500 if (stat_ok && _gsys_qtape(&statbuf) != 0)
00501 tufs = FS_TAPE;
00502 }
00503
00504
00505
00506
00507
00508
00509 if (stdfn) {
00510 FILE *stdf;
00511
00512 #if defined(_LITTLE_ENDIAN) && !defined(__sv2)
00513
00514
00515
00516 switch(stdfnum) {
00517 case(STDIN_FILENO):
00518 stdf = _IO_stdin;
00519 break;
00520 case(STDOUT_FILENO):
00521 stdf = _IO_stdout;
00522 break;
00523 default:
00524 stdf = _IO_stderr;
00525 break;
00526 }
00527 #else
00528 stdf = &__iob[stdfnum];
00529 #endif
00530
00531 if (!cup->useq || !cup->ufmt ||
00532 (tufs != FS_TEXT && tufs != STD)) {
00533 freeit(fname);
00534 freeit(aname);
00535 freeit(atstr);
00536 freeit(cup->ulinebuf);
00537 FERROR(olptr->oerr, FEOPSTFN);
00538 }
00539
00540 if (stdfnum < STDIN_FILENO || stdfnum > STDERR_FILENO) {
00541
00542
00543 freeit(fname);
00544 freeit(aname);
00545 freeit(atstr);
00546 freeit(cup->ulinebuf);
00547 FERROR(olptr->oerr,FEINTUNK);
00548 }
00549
00550 if (fileno(stdf) != stdfnum) {
00551
00552
00553 freeit(fname);
00554 freeit(aname);
00555 freeit(atstr);
00556 freeit(cup->ulinebuf);
00557 FERROR(olptr->oerr,FEINTUNK);
00558 }
00559
00560 cup->ufp.std = stdf;
00561
00562
00563
00564
00565
00566 switch (stdfnum) {
00567 case STDIN_FILENO:
00568 cup->auxlockp = &_stdin_lock;
00569 break;
00570
00571 case STDOUT_FILENO:
00572 cup->auxlockp = &_stdout_lock;
00573 break;
00574
00575 case STDERR_FILENO:
00576 cup->auxlockp = &_stderr_lock;
00577 break;
00578 }
00579
00580
00581
00582
00583
00584 freeit(aname);
00585 freeit(fname);
00586 aname = NULL;
00587 fname = NULL;
00588 }
00589
00590
00591
00592
00593
00594
00595 cup->ufnm = fname;
00596 cup->alfnm = aname;
00597 cup->uid = unum;
00598
00599
00600
00601 cup->uostatus = olptr->ostatus;
00602
00603 switch (olptr->ostatus) {
00604
00605 case OS_UNKNOWN:
00606 default:
00607 oflags = O_CREAT;
00608 break;
00609
00610 case OS_SCRATCH:
00611 cup->uscrtch = 1;
00612 oflags = O_CREAT;
00613 break;
00614
00615 case OS_OLD:
00616 oflags = 0;
00617 break;
00618
00619 case OS_NEW:
00620
00621
00622 if (stat_ok && !S_ISCHR(statbuf.st_mode) &&
00623 !S_ISFIFO(statbuf.st_mode)) {
00624 freeit(fname);
00625 freeit(aname);
00626 freeit(atstr);
00627 freeit(cup->ulinebuf);
00628 FERROR(olptr->oerr, FEOPFNNX);
00629 }
00630
00631 cup->uostatus = OS_OLD;
00632
00633 oflags = O_EXCL | O_CREAT;
00634 break;
00635
00636 case OS_REPLACE:
00637
00638
00639
00640
00641
00642
00643 cup->uostatus = OS_OLD;
00644
00645 oflags = O_CREAT;
00646 break;
00647
00648 }
00649
00650
00651
00652 errn = _f_opn(aname, cup, css, tufs, aifound, &ai, &statbuf,
00653 stat_ok, olptr->oerr, oflags);
00654
00655 if (errn != OK) {
00656 errn = errno;
00657
00658
00659
00660 if (errn == EEXIST)
00661 errn = FEOPFNNX;
00662
00663 goto open_error;
00664 }
00665
00666 #ifdef _CRAYMPP
00667
00668 if (stdfn)
00669 cup->utrunc = 0;
00670 #endif
00671
00672
00673
00674
00675 _set_device_and_inode(cup->usysfd, &cup->udevice, &cup->uinode);
00676
00677 errn = _uniqinod(cup, (aifound ? &ai : NULL));
00678
00679 if (errn != 0)
00680 goto open_error;
00681
00682
00683
00684
00685
00686 errn = _mixed_scope(cup);
00687
00688 if (errn != 0)
00689 goto open_error;
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700 if (olptr->ostatus == OS_REPLACE) {
00701 errn = _unit_trunc(cup);
00702
00703 if (errn != 0)
00704 goto open_error;
00705
00706
00707
00708
00709
00710
00711
00712 if (cup->ufs == FS_FDC) {
00713 struct ffsw fst;
00714
00715 XRCALL(cup->ufp.fdc, seekrtn) cup->ufp.fdc, 0, 0, &fst);
00716 }
00717
00718 cup->udamax = 0;
00719 }
00720
00721
00722
00723
00724 switch (cup->uposition) {
00725
00726 case OS_REWIND:
00727 case OS_ASIS:
00728 break;
00729
00730 case OS_APPEND:
00731
00732
00733 {
00734 int neg1;
00735
00736 neg1 = -1;
00737 errn = _setpos(css, cup, &neg1, 1);
00738
00739 if (errn != 0)
00740 goto open_error;
00741
00742 errn = _unit_bksp(cup);
00743
00744 if (errn != 0)
00745 goto open_error;
00746 }
00747 break;
00748
00749 }
00750
00751
00752
00753
00754 if (cup->utmpfil) {
00755 errn = _unit_scratch(cup);
00756
00757 if (errn != 0)
00758 goto open_error;
00759 }
00760
00761
00762
00763
00764 _set_ok_flags(cup);
00765
00766 if (FORTSTATS) {
00767
00768
00769
00770 if (_ft_stopen(cup, atstr) == -1) {
00771 errn = errno;
00772 goto open_error;
00773 }
00774 }
00775
00776 freeit(atstr);
00777
00778
00779
00780
00781
00782
00783 if (cup->auxlockp != NULL)
00784 MEM_LOCK(cup->auxlockp);
00785
00786 return(0);
00787
00788
00789
00790 open_error:
00791 freeit(atstr);
00792 (void)_unit_close(cup, CLST_UNSPEC, NULL);
00793
00794 FERROR(olptr->oerr, errn);
00795
00796 return(0);
00797 }
00798
00799
00800
00801
00802 static void
00803 freeit(void *ptr)
00804 {
00805 if (ptr != NULL)
00806 free(ptr);
00807 }
00808
00809
00810
00811
00812
00813
00814
00815
00816 void
00817 _set_ok_flags(unit *cup)
00818 {
00819 cup->ok_wr_seq_fmt = _get_mismatch_error(1, T_WSF, cup, NULL) == 0;
00820 cup->ok_wr_seq_unf = _get_mismatch_error(1, T_WSU, cup, NULL) == 0;
00821 cup->ok_wr_dir_fmt = _get_mismatch_error(1, T_WDF, cup, NULL) == 0;
00822 cup->ok_wr_dir_unf = _get_mismatch_error(1, T_WDU, cup, NULL) == 0;
00823
00824 cup->ok_rd_seq_fmt = _get_mismatch_error(1, T_RSF, cup, NULL) == 0;
00825 cup->ok_rd_seq_unf = _get_mismatch_error(1, T_RSU, cup, NULL) == 0;
00826 cup->ok_rd_dir_fmt = _get_mismatch_error(1, T_RDF, cup, NULL) == 0;
00827 cup->ok_rd_dir_unf = _get_mismatch_error(1, T_RDU, cup, NULL) == 0;
00828
00829 return;
00830 }
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848 int
00849 _get_mismatch_error(
00850 int noabort,
00851 int iost,
00852 unit *cup,
00853 FIOSPTR css)
00854
00855 {
00856 register int errn = 0;
00857
00858 if (cup->ufs == FS_AUX) {
00859 errn = FEMIXAUX;
00860 goto ret;
00861 }
00862
00863
00864
00865 if (iost & TF_WRITE) {
00866 if ((cup->uaction & OS_WRITE) == 0) {
00867 errn = FENOWRIT;
00868 goto ret;
00869 }
00870 }
00871 else {
00872 if ((cup->uaction & OS_READ) == 0) {
00873 errn = FENOREAD;
00874 goto ret;
00875 }
00876 }
00877
00878
00879
00880 if (iost & TF_FMT) {
00881 if (!cup->ufmt) {
00882 errn = FEFMTTIV;
00883 goto ret;
00884 }
00885 }
00886 else {
00887 if (cup->ufmt) {
00888 errn = FEUNFMIV;
00889 goto ret;
00890 }
00891 }
00892
00893
00894
00895 if (iost == T_WDF || iost == T_WDU || iost == T_RDF || iost == T_RDU) {
00896 if (cup->useq) {
00897 errn = FEDIRTIV;
00898 goto ret;
00899 }
00900 } else {
00901 if (cup->useq == 0) {
00902 errn = FESEQTIV;
00903 goto ret;
00904 }
00905 }
00906
00907 ret:
00908 if (noabort)
00909 return(errn);
00910 else {
00911 if (errn == 0)
00912 errn = FEINTUNK;
00913
00914 _ferr(css, errn);
00915 }
00916
00917 return(FEINTUNK);
00918 }
00919
00920 #ifdef _UNICOS
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936 void
00937 __fio_hardrefs()
00938 {
00939 (void) _finit();
00940
00941
00942
00943 #if defined(_CRAY1)
00944 (void) _repriev();
00945
00946
00947
00948 #endif
00949 }
00950
00951 #endif