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