1 /****^ *********************************************************** 2 * * 3 * Copyright, (C) Honeywell Bull Inc., 1987 * 4 * * 5 * Copyright, (C) Honeywell Information Systems Inc., 1985 * 6 * * 7 *********************************************************** */ 8 9 /* format: off */ /* This program was formatted via emacs. */ 10 11 initiate_: 12 initiate: 13 procedure (a_dname, a_ename, a_rname, a_segsw, a_copysw, a_segptr, a_code); 14 15 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 16 /* */ 17 /* History of earlier versions of the program: */ 18 /* Modified on 05/74 by E Stone to call status_$long when copy made */ 19 /* (to get curlen and to cause a branch update) */ 20 /* Modified by Kobziar July 74 to call new entry in access_mode */ 21 /* and to add privileged initate entries */ 22 /* Modified on 03/76 by R. Bratt to check mountedness of LV before okaying */ 23 /* makeknown */ 24 /* Modified on 06/01/76 by R. Bratt to call find_$finished */ 25 /* Modified on 06/02/76 by R. Bratt to cleanup a piece of trash! */ 26 /* Modified 760317 by L. Scheffler to properly call dir_control_error */ 27 /* entries */ 28 /* Modified on 03/29/77 by M. Weaver to set lot fault when segment is first */ 29 /* initiated in ring */ 30 /* Modified on 78/02/21 by M. Weaver to call link_man$grow_lot at proper */ 31 /* boundary */ 32 /* Modified on 79/08/29 by Mike Grady to fix bug handling reserved segno's */ 33 /* and copy sw */ 34 /* Modified on 81/04/06 by J. Bongiovanni to fix max lot size check */ 35 /* Modified May 1981 by C. Hornig to remove references to the copy switch. */ 36 /* Modified 04/30/84 by S. Herbst to add $get_segment_ptr_path */ 37 /* Modified 07/18/84 by Keith Loepere to use the new dc_find. */ 38 /* Modified 10/19/84 by Keith Loepere to do the right thing for initiating */ 39 /* directories. */ 40 /* */ 41 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 42 43 44 /****^ HISTORY COMMENTS: 45 1) change(85-12-10,GDixon), approve(86-08-09,MCR7388), 46 audit(86-09-12,Farley), install(86-09-08,MR12.0-1150): 47 Completely rewritten to: 48 a) improve program structure and reduce number of switches used in code; 49 b) keep directory locked while calling makeknown_, so that the pointer to 50 dir entry remains valid; 51 c) use dc_find$finished for most directory unlocking. 52 END HISTORY COMMENTS */ 53 54 ^L 55 /* Parameters */ 56 57 dcl a_code fixed bin (35) parameter; 58 dcl a_copysw fixed bin (2) parameter; 59 dcl a_dname char (*) parameter; 60 dcl a_dp ptr parameter; 61 dcl a_ename char (*) parameter; 62 dcl a_rname char (*) parameter; 63 dcl a_count fixed bin (17); 64 dcl a_segptr ptr parameter; 65 dcl a_segsw fixed bin (1) parameter; 66 dcl a_uid bit (36) parameter; 67 68 /* Variables */ 69 70 dcl 1 in aligned, /* copies of input parms. */ 71 2 segp ptr, 72 2 dirp ptr, 73 2 dname char(168) unal, 74 2 ename char(32) unal, 75 2 rname char(32) varying; 76 dcl 1 entrypoint aligned, /* per-entrypoint controls */ 77 2 dc_find entry (char(168), char(32), ptr, fixed bin(35)) variable, 78 2 should_call_find_finished bit(1), 79 2 should_unlock_dir bit(1), 80 2 priv bit(1); 81 dcl 1 seg aligned, /* intermediate data for */ 82 2 dirp ptr, /* segment being initiated.*/ 83 2 entp ptr, 84 2 directory bit(1), 85 2 hash_bucket fixed bin(17); 86 dcl 1 out aligned, /* copies of output data. */ 87 2 segp ptr, 88 2 bc fixed bin(24), 89 2 uid bit(36), 90 2 code fixed bin(35); 91 92 /* External */ 93 94 dcl error_table_$dirseg external fixed bin (35); 95 dcl error_table_$invalid_copy external fixed bin (35); 96 dcl error_table_$seg_unknown external fixed bin (35); 97 dcl error_table_$segknown external fixed bin (35); 98 99 /* Entries */ 100 101 dcl kstsrch entry (bit (36) aligned, fixed bin (17), ptr); 102 103 /* Misc */ 104 105 dcl (addr, baseno, baseptr, fixed, null, ptr, rtrim, unspec) builtin; 106 dcl (FALSE init("0"b), 107 TRUE init("1"b)) bit(1) int static options(constant); 108 ^L 109 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 110 /* */ 111 /* NAME: initiate */ 112 /* */ 113 /* This module is a primitive which calls other routines to make a segment */ 114 /* known, i.e., to assign a segment number to the segment or a copy of the */ 115 /* segment. */ 116 /* */ 117 /* ENTRY: initiate */ 118 /* */ 119 /* This is the main entrypoint. Besides making a segment identified by */ 120 /* pathname known (optionally by a given reference name), it allows the */ 121 /* caller to optionally specify the segment number by which the segment */ 122 /* will be known. The copysw argument is obsolete; a value of 2 (always */ 123 /* make a copy of the segment in the pdir) is diagnosed as an error; */ 124 /* otherwise the switch is ignored. */ 125 /* */ 126 /* USAGE: call initiate (a_dname, a_ename, a_rname, a_segsw, a_copysw, */ 127 /* a_segptr, a_code); */ 128 /* */ 129 /* a_dname (char(*)) */ 130 /* pathname of parent directory of the segment to be initiated (Input) */ 131 /* a_ename (char(*)) */ 132 /* entryname of the segment to be initiated (Input) */ 133 /* a_rname (char(*)) */ 134 /* reference name by which the segment is to be made known if this */ 135 /* argument is of zero length, then the segment is made known by a null */ 136 /* name (Input) */ 137 /* a_segsw (fixed bin (1)) */ 138 /* reserve segment switch (Input) */ 139 /* (= 0 if no segment number reserved, */ 140 /* = 1 if segment number reserved) */ 141 /* a_copysw (fixed bin (2)) */ 142 /* formerly copy switch (Input) */ 143 /* (= 0 if default setting of copy switch to be used, */ 144 /* = 1 if segment never to be copied, */ 145 /* = 2 if segment always to be copied into process dir prior to */ 146 /* initiation. This alternative is no longer implemented. It */ 147 /* produces an error.) */ 148 /* a_segptr (pointer) */ 149 /* normally output. If segsw = 1 then input pointer to previously known */ 150 /* segment (used to input reserve segment number) . */ 151 /* a_code (fixed bin (35)) */ 152 /* status code (Output) */ 153 /* */ 154 /* ENTRY: priv_init */ 155 /* */ 156 /* This entry is identical to the initiate entrypoint, except that it */ 157 /* ignores the impact of AIM and ring brackets when determining whether the */ 158 /* user has access to initiate the segment. */ 159 /* */ 160 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 161 ^L 162 /* The real procedure statement is up above. This one is useful documentation. 163 164 initiate_: 165 initiate: 166 proc (a_dname, a_ename, a_rname, a_segsw, a_copysw, a_segptr, a_code); */ 167 168 call setup_args$initiate(); 169 entrypoint.dc_find = dc_find$obj_initiate; 170 go to INITIATE_COMMON; 171 172 /* * * * * * * * * * * * * * * * * * * * * * * * * */ 173 174 175 priv_init: 176 entry (a_dname, a_ename, a_rname, a_segsw, a_copysw, a_segptr, a_code); 177 178 call setup_args$initiate(); 179 entrypoint.dc_find = dc_find$obj_initiate_raw; 180 entrypoint.priv = TRUE; 181 182 INITIATE_COMMON: 183 if out.code = 0 then do; 184 call entrypoint.dc_find (in.dname, in.ename, seg.entp, out.code); 185 if out.code = 0 then do; 186 entrypoint.should_call_find_finished = TRUE; 187 entrypoint.should_unlock_dir = FALSE; 188 call check_entry(); 189 call make_entry_known_and_unlock_dir(); 190 end; 191 end; 192 a_segptr = out.segp; 193 a_code = out.code; 194 return; 195 196 /* * * * * * * * * * * * * * * * * * * * * * * * * */ 197 198 199 200 201 202 setup_args$initiate: 203 proc; 204 205 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 206 /* */ 207 /* Input Args: */ 208 /* a_dname, a_ename, a_rname, */ 209 /* a_segsw, a_copysw, a_seg_ptr */ 210 /* input parameters, to be copied and tested. Meanings of these parms */ 211 /* are given in entrypoint descriptions above. */ 212 /* */ 213 /* Function: */ 214 /* 1) copy a_dname, a_ename, a_rname. */ 215 /* 2) copy, test and apply a_segsw to initial value of in.segp. */ 216 /* 3) initialize out.segp, out.bc out.uid & entrypoint.priv. */ 217 /* 4) copy and test a_copysw. Set out.code according to test results. */ 218 /* */ 219 ^L 220 /* Output Args: */ 221 /* in.dname, in.ename, in.rname */ 222 /* copies of input parameters. */ 223 /* in.segp */ 224 /* copy of a_segptr if a_segsw is on; otherwise set to null. */ 225 /* out.segp */ 226 /* initialized to null (default output value if error occurs). */ 227 /* out.bc */ 228 /* set to 0 (unused return argument). */ 229 /* out.uid */ 230 /* set to "0"b (unused return argument). */ 231 /* out.code */ 232 /* result of test of a_copysw. */ 233 /* entrypoint.priv */ 234 /* set to off, assuming not entered at privileged */ 235 /* */ 236 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 237 238 dcl copysw fixed bin (2); 239 dcl segsw fixed bin (1); 240 241 copysw = a_copysw; 242 segsw = a_segsw; 243 in.dname = a_dname; 244 in.ename = a_ename; 245 in.rname = rtrim(a_rname); 246 247 if segsw = 0 then /* a_segptr can only be */ 248 in.segp = null; /* copied if segsw ^= 0. */ 249 else /* Otherwise, it must not */ 250 in.segp = a_segptr; /* be touched, since its */ 251 /* storage may not be in */ 252 /* ptr format. */ 253 out.segp = null; 254 out.bc = 0; 255 out.uid = "0"b; 256 if copysw = 2 then 257 out.code = error_table_$invalid_copy; 258 else 259 out.code = 0; 260 entrypoint.priv = FALSE; 261 262 end setup_args$initiate; 263 264 /* * * * * * * * * * * * * * * * * * * * * * * * * */ 265 ^L 266 /* * * * * * * * * * * * * * * * * * * * * * * * * */ 267 268 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 269 /* */ 270 /* ENTRY: initiate_count */ 271 /* */ 272 /* This entry is the same as initiate except that a bit count parameter */ 273 /* replaces the a_segsw parm. */ 274 /* */ 275 /* USAGE: call initiate$initiate_count */ 276 /* (a_dname, a_ename, a_rname, a_count, a_copysw, a_segptr, a_code);*/ 277 /* */ 278 /* a_count (fixed bin(24)) */ 279 /* bit count of initiated segment (Output) */ 280 /* */ 281 /* ENTRY: priv_init_count */ 282 /* */ 283 /* This entry is like initiate_count, except that it ignores the impact of */ 284 /* AIM and ring brackets when determining whether the user has access to */ 285 /* initiate the segment. */ 286 /* */ 287 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 288 289 initiate_count: 290 entry (a_dname, a_ename, a_rname, a_count, a_copysw, a_segptr, a_code); 291 292 call setup_args$initiate_count(); 293 entrypoint.dc_find = dc_find$obj_initiate; 294 go to INITIATE_COUNT_COMMON; 295 296 /* * * * * * * * * * * * * * * * * * * * * * * * * */ 297 298 299 priv_init_count: 300 entry (a_dname, a_ename, a_rname, a_count, a_copysw, a_segptr, a_code); 301 302 call setup_args$initiate_count(); 303 entrypoint.dc_find = dc_find$obj_initiate_raw; 304 entrypoint.priv = TRUE; 305 306 INITIATE_COUNT_COMMON: 307 if out.code = 0 then do; 308 call entrypoint.dc_find (in.dname, in.ename, seg.entp, out.code); 309 if out.code = 0 then do; 310 entrypoint.should_call_find_finished = TRUE; 311 entrypoint.should_unlock_dir = FALSE; 312 call check_entry(); 313 call make_entry_known_and_unlock_dir(); 314 end; 315 end; 316 a_count = out.bc; 317 a_segptr = out.segp; 318 a_code = out.code; 319 return; 320 321 /* * * * * * * * * * * * * * * * * * * * * * * * * */ 322 ^L 323 /* * * * * * * * * * * * * * * * * * * * * * * * * */ 324 325 setup_args$initiate_count: 326 proc; 327 328 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 329 /* */ 330 /* Input Args: */ 331 /* a_dname, a_ename, a_rname, a_copysw */ 332 /* input parameters, to be copied and tested. Meanings of these parms */ 333 /* are given in entrypoint descriptions above. */ 334 /* */ 335 /* Function: */ 336 /* 1) copy a_dname, a_ename, a_rname. */ 337 /* 2) initialize in.segp, out.segp, out.bc, out.uid & entrypoint.priv. */ 338 /* 3) copy and test a_copysw. Set out.code according to test results. */ 339 /* */ 340 /* Output Args: */ 341 /* in.dname, in.ename, in.rname */ 342 /* copies of input parameters. */ 343 /* in.segp */ 344 /* set to null (no reserved segment number specified). */ 345 /* out.segp */ 346 /* set to null (default output value if error occurs). */ 347 /* out.bc */ 348 /* set to value for bit count to be output if error occurs (0). */ 349 /* out.uid */ 350 /* set to "0"b (unused output value). */ 351 /* out.code */ 352 /* result of test of a_copysw. */ 353 /* entrypoint.priv */ 354 /* set to off, assuming not entered at privileged entrypoint. */ 355 /* */ 356 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 357 358 dcl copysw fixed bin (2); 359 360 copysw = a_copysw; 361 in.dname = a_dname; 362 in.ename = a_ename; 363 in.rname = rtrim(a_rname); 364 in.segp = null; 365 366 out.segp = null; 367 out.bc = 0; 368 out.uid = "0"b; 369 if copysw = 2 then 370 out.code = error_table_$invalid_copy; 371 else 372 out.code = 0; 373 entrypoint.priv = FALSE; 374 375 end setup_args$initiate_count; 376 377 /* * * * * * * * * * * * * * * * * * * * * * * * * */ 378 ^L 379 /* * * * * * * * * * * * * * * * * * * * * * * * * */ 380 381 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 382 /* */ 383 /* ENTRY: initiate_seg_count */ 384 /* */ 385 /* This entry is the same as initiate_count except that it takes a */ 386 /* directory pointer instead of a directory path name. It is used solely */ 387 /* by fs_search. */ 388 /* */ 389 /* NOTE: a contract has been made that this entry can only be called by */ 390 /* fs_search. dc_find knows this. As such, dc_find does not do its normal */ 391 /* name lookup access check for this routine, and merely returns no_info */ 392 /* if the name doesn't exist or if the user doesn't have access. */ 393 /* */ 394 /* USAGE: call initiate$initiate_seg_count */ 395 /* (a_dp, a_ename, a_rname, a_count, a_copysw, a_segptr, a_code); */ 396 /* */ 397 /* a_dp (ptr) */ 398 /* pointer to directory of entry ename. (Input) */ 399 /* */ 400 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 401 402 initiate_seg_count: 403 entry (a_dp, a_ename, a_rname, a_count, a_copysw, a_segptr, a_code); 404 405 call setup_args$initiate_seg_count(); 406 if out.code = 0 then do; 407 408 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 409 /* */ 410 /* Note that dc_find$obj_initiate_for_linker_dp, knowing it is called only */ 411 /* for fs_search, does not perform its normal name lookup access checks. */ 412 /* If the entry is not found, dc_find will return no_info, as it will (for */ 413 /* this one entry only) if the user lacks access to see the object. */ 414 /* */ 415 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 416 417 call dc_find$obj_initiate_for_linker_dp (in.dirp, in.ename, seg.entp, out.code); 418 if out.code = 0 then do; 419 if in.dirp = null then do; 420 421 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 422 /* */ 423 /* This means ename was a link to an object in another directory besides */ 424 /* that pointed to by in.dirp. Therefore, we cannot unlock the dir but */ 425 /* must instead tell dc_find to do it. */ 426 /* */ 427 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 428 429 entrypoint.should_unlock_dir = FALSE; 430 entrypoint.should_call_find_finished = TRUE; 431 end; 432 433 else do; 434 ^L 435 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 436 /* */ 437 /* This is the normal case, in which we can unlock in.dirp directly without */ 438 /* having to call dc_find. */ 439 /* */ 440 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 441 442 entrypoint.should_call_find_finished = FALSE; 443 entrypoint.should_unlock_dir = TRUE; 444 end; 445 446 call check_entry(); 447 call make_entry_known_and_unlock_dir(); 448 end; 449 end; 450 a_count = out.bc; 451 a_segptr = out.segp; 452 a_code = out.code; 453 return; 454 455 /* * * * * * * * * * * * * * * * * * * * * * * * * */ 456 ^L 457 /* * * * * * * * * * * * * * * * * * * * * * * * * */ 458 459 setup_args$initiate_seg_count: 460 proc; 461 462 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 463 /* */ 464 /* Input Args: */ 465 /* a_dp, a_ename, a_rname, */ 466 /* a_copysw */ 467 /* input parameters, to be copied and tested. Meanings of these parms */ 468 /* are given in entrypoint descriptions above. */ 469 /* */ 470 /* Function: */ 471 /* 1) copy a_dp, a_ename, a_rname. */ 472 /* 2) initialize in.segp, out.segp, out.bc, out.uid & entrypoint.priv. */ 473 /* 3) copy and test a_copysw. Set out.code according to test results. */ 474 /* */ 475 /* Output Args: */ 476 /* in.dirp, in.ename, in.rname */ 477 /* copies of input parameters. */ 478 /* in.segp */ 479 /* set to null (no reserved segment number specified). */ 480 /* out.segp */ 481 /* set to null (default output value if error occurs). */ 482 /* out.bc */ 483 /* set to value for bit count to be output if error occurs (0). */ 484 /* out.uid */ 485 /* set to "0"b (unused output value). */ 486 /* out.code */ 487 /* result of test of a_copysw. */ 488 /* entrypoint.priv */ 489 /* set to off, not a privileged entrypoint. */ 490 /* */ 491 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 492 493 dcl copysw fixed bin (2); 494 495 in.dirp = a_dp; 496 in.ename = a_ename; 497 in.rname = rtrim(a_rname); 498 in.segp = null; 499 500 out.segp = null; 501 out.bc = 0; 502 out.uid = "0"b; 503 copysw = a_copysw; 504 if copysw = 2 then 505 out.code = error_table_$invalid_copy; 506 else 507 out.code = 0; 508 entrypoint.priv = FALSE; 509 510 end setup_args$initiate_seg_count; 511 512 /* * * * * * * * * * * * * * * * * * * * * * * * * */ 513 ^L^L 514 /* * * * * * * * * * * * * * * * * * * * * * * * * */ 515 516 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 517 /* */ 518 /* ENTRY: get_segment_ptr_path */ 519 /* */ 520 /* This entry point returns a ptr and uid if the segment is already */ 521 /* initiated; it returns an error if the segment is not already initiated. */ 522 /* */ 523 /* USAGE: call initiate_$get_segment_ptr_path (a_dname, a_ename, a_segptr, */ 524 /* a_uid, a_code); */ 525 /* */ 526 /* a_dname (char(*)) */ 527 /* parent directory. (Input) */ 528 /* a_ename (char(*)) */ 529 /* entry name. (Input) */ 530 /* a_segptr (ptr) */ 531 /* pointer to the segment, or null. (Output) */ 532 /* a_uid (bit(36)) */ 533 /* file system uid. (Output) */ 534 /* a_code (fixed(35)) */ 535 /* zero or error_table_$seg_unknown. (Output) */ 536 /* */ 537 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 538 539 get_segment_ptr_path: 540 entry (a_dname, a_ename, a_segptr, a_uid, a_code); 541 542 call setup_args$get_segment_ptr_path(); 543 call dc_find$obj_initiate (in.dname, in.ename, seg.entp, out.code); 544 if out.code = 0 then do; 545 entrypoint.should_call_find_finished = TRUE; 546 entrypoint.should_unlock_dir = FALSE; 547 call check_entry(); 548 if seg.directory then do; 549 out.code = error_table_$dirseg; 550 out.uid = "0"b; 551 end; 552 else do; 553 call kstsrch (out.uid, seg.hash_bucket, kstep); 554 if kstep = null then do; 555 out.code = error_table_$seg_unknown; 556 out.uid = "0"b; 557 end; 558 else 559 out.segp = baseptr (kste.segno); 560 end; 561 call unlock_dir(); 562 end; 563 a_uid = out.uid; 564 a_segptr = out.segp; 565 a_code = out.code; 566 return; 567 568 /* * * * * * * * * * * * * * * * * * * * * * * * * */ 569 ^L 570 /* * * * * * * * * * * * * * * * * * * * * * * * * */ 571 572 573 setup_args$get_segment_ptr_path: 574 proc; 575 576 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 577 /* */ 578 /* Input Args: */ 579 /* a_dname, a_ename */ 580 /* input parameters, to be copied. Meanings of these parms are given in */ 581 /* entrypoint descriptions above. */ 582 /* */ 583 /* Function: */ 584 /* 1) copy a_dname and a_ename */ 585 /* 2) initialize in.segp, out.segp, out.bc, out.uid, out.code and */ 586 /* entrypoint.priv. */ 587 /* */ 588 /* Output Args: */ 589 /* in.dname, in.ename */ 590 /* copies of input parameters. */ 591 /* in.segp */ 592 /* set to null (no reserved segment number specified). */ 593 /* out.segp */ 594 /* set to null (default output value if segment not known). */ 595 /* out.bc */ 596 /* set to 0 (unused return argument). */ 597 /* out.uid */ 598 /* set to uid value to output if error occurs (0). */ 599 /* out.code */ 600 /* set to 0. */ 601 /* entrypoint.priv */ 602 /* set to off, not a privileged entrypoint. */ 603 /* */ 604 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 605 606 in.dname = a_dname; 607 in.ename = a_ename; 608 in.segp = null; 609 610 out.segp = null; 611 out.bc = 0; 612 out.uid = "0"b; 613 out.code = 0; 614 entrypoint.priv = FALSE; 615 616 end setup_args$get_segment_ptr_path; 617 618 /* * * * * * * * * * * * * * * * * * * * * * * * * */ 619 ^L 620 /* * * * * * * * * * * * * * * * * * * * * * * * * */ 621 622 check_entry: 623 proc; 624 625 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 626 /* */ 627 /* Input Args: */ 628 /* seg.entp */ 629 /* pointer to the dir branch for the entry to be initiated. */ 630 /* */ 631 /* Function: */ 632 /* 1) Check if target entry being initiated is the root dir. If so */ 633 /* fabricate information. */ 634 /* 2) Otherwise, extract output information from dir branch for the entry. */ 635 /* */ 636 /* Output Args: */ 637 /* seg.dirp */ 638 /* pointer to the containing dir. */ 639 /* seg.directory */ 640 /* on if entry being initiated is a directory. */ 641 /* out.uid */ 642 /* entry's unique ID */ 643 /* out.bc */ 644 /* entry's bit count */ 645 /* entrypoint.should_call_find_finished, */ 646 /* entrypoint.should_unlock_dir */ 647 /* switches controlling whether/how directory is unlocked. These are */ 648 /* turned off if the entry is the root dir. */ 649 /* */ 650 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 651 652 if seg.entp = null then do; /* root */ 653 seg.dirp = null; 654 seg.directory = TRUE; 655 out.uid = "777777777777"b3; 656 out.bc = 0; 657 entrypoint.should_call_find_finished, /* didn't lock anything */ 658 entrypoint.should_unlock_dir = FALSE; 659 end; 660 else do; 661 seg.dirp = ptr (seg.entp, 0); 662 seg.directory = seg.entp -> entry.dirsw; 663 out.uid = seg.entp -> entry.uid; 664 out.bc = seg.entp -> entry.bc; 665 end; 666 end check_entry; 667 668 /* * * * * * * * * * * * * * * * * * * * * * * * * */ 669 ^L 670 /* * * * * * * * * * * * * * * * * * * * * * * * * */ 671 672 make_entry_known_and_unlock_dir: 673 proc; 674 675 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 676 /* */ 677 /* Input Args: */ 678 /* in.segp */ 679 /* reserved segment number to use for initiate_ entrypoint */ 680 /* in.rname */ 681 /* name by which segment is to be referenced (for ref_name_$insert) */ 682 /* seg.dirp */ 683 /* pointer to dir containing entry. */ 684 /* seg.entp */ 685 /* pointer to entry's dir branch. */ 686 /* seg.directory */ 687 /* on if entry being initiated is a directory. */ 688 /* entrypoint.priv */ 689 /* on if calling entrypoint is privileged (for call to makeknown_) */ 690 /* out.uid */ 691 /* entry's unique ID (for call to makeknown_) */ 692 /* */ 693 /* Function: */ 694 /* 1) Ensures disk holding target entry is mounted. */ 695 /* 2) Makes target entry known to process. */ 696 /* 3) Unlocks containing directory. */ 697 /* 4) Adds reference name table (RNT) entry for the known segment. */ 698 /* 5) Sets LOT entry for the segment (in target ring) to lot_fault value. */ 699 /* */ 700 /* Output Args: */ 701 /* out.segp */ 702 /* pointer to initiated segment (remains unchanged if makeknown_ fails). */ 703 /* out.bc */ 704 /* bit count (set to 0 if makeknown_ fails). */ 705 /* out.code */ 706 /* results from call to mountedp, makeknown_ and ref_name_$insert. */ 707 /* */ 708 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 709 710 /* Variables */ 711 dcl ecode fixed bin (35); 712 dcl 1 mk_info aligned like makeknown_info; 713 dcl ring fixed bin (3); 714 dcl segno fixed bin; 715 dcl use_count fixed bin (17); 716 717 /* External */ 718 dcl pds$stacks (0:7) ptr ext; 719 dcl 1 pds$useable_lot aligned ext, 720 2 flags (0:7) bit (1) unal; 721 722 /* Entries */ 723 dcl level$get entry returns (fixed bin (3)); 724 dcl link_man$grow_lot entry (fixed bin (3)); 725 dcl makeknown_ entry (ptr, fixed bin, fixed bin, fixed bin (35)); 726 dcl mountedp entry (bit (36) aligned, fixed bin (35)); 727 dcl ref_name_$insert entry (char (32) varying, fixed bin, fixed bin (35)); 728 ^L 729 if ^seg.directory then do; /* ensure LV is mounted */ 730 call mountedp (seg.dirp -> dir.sons_lvid, out.code); 731 if out.code ^= 0 then do; 732 call unlock_dir(); 733 out.bc = 0; /* Don't return bit count */ 734 return; /* if errors occur. */ 735 end; 736 end; 737 738 unspec (mk_info) = FALSE; 739 mk_info.uid = out.uid; 740 mk_info.entryp = seg.entp; /* dir locked, seg.entp */ 741 /* has been validated by */ 742 /* dc_find. */ 743 mk_info.dirsw = seg.directory; 744 mk_info.priv_init = entrypoint.priv; 745 mk_info.allow_write = TRUE; 746 747 if in.segp ^= null then do; 748 mk_info.rsw = TRUE; 749 segno = fixed (baseno (in.segp), 17); 750 end; 751 else mk_info.rsw = FALSE; 752 753 call makeknown_ (addr (mk_info), segno, use_count, out.code); 754 call unlock_dir(); /* The dir must stay */ 755 /* locked until after */ 756 if out.code = 0 then; /* makeknown_ returns, as */ 757 else if out.code = error_table_$segknown then;/* per interface specs. */ 758 else do; 759 out.bc = 0; /* Don't return bit count */ 760 return; /* if errors occur. */ 761 end; 762 out.segp = baseptr (segno); /* From this point on, */ 763 /* makeknown_ has succeeded*/ 764 765 if in.rname ^= "" then do; /* Add ref name to segment.*/ 766 call ref_name_$insert (in.rname, segno, ecode); 767 if ecode ^= 0 then out.code = ecode; /* Be careful not to zero */ 768 end; /* segknown code needlessly*/ 769 770 if use_count = 1 then do; /* Made known for first */ 771 ring = level$get (); /* time in a ring? */ 772 if pds$useable_lot.flags (ring) then do; /* diddle user ring lot */ 773 if segno >= pds$stacks (ring) -> stack_header.cur_lot_size then 774 if segno < pds$stacks (ring) -> stack_header.max_lot_size then do; 775 call link_man$grow_lot (ring); 776 unspec (pds$stacks (ring) -> stack_header.lot_ptr -> lot.lp (segno)) = lot_fault; 777 /* flag lot entry to tell */ 778 end; /* run unit seg is known. */ 779 else; /* high segno might be OK */ 780 /* if seg not linked to. */ 781 else unspec (pds$stacks (ring) -> stack_header.lot_ptr -> lot.lp (segno)) = lot_fault; 782 end; 783 end; 784 end make_entry_known_and_unlock_dir; 785 786 /* * * * * * * * * * * * * * * * * * * * * * * * * */ 787 ^L 788 /* * * * * * * * * * * * * * * * * * * * * * * * * */ 789 790 unlock_dir: 791 proc; 792 793 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 794 /* */ 795 /* Input Args: */ 796 /* seg.dirp */ 797 /* pointer to dir containing entry. */ 798 /* seg.entp */ 799 /* pointer to entry's dir branch. */ 800 /* entrypoint.should_call_find_finished */ 801 /* on to call dc_find$finished to unlock and unhold dir. */ 802 /* entrypoint.should_unlock_dir */ 803 /* on to call lock$unlock_dir to unlock dir. */ 804 /* */ 805 /* Function: unlock dir containing target entry. Normally, it was locked */ 806 /* by dc_find$obj_initiate, which also holds the directory (by incrementing */ 807 /* its usage count) to keep it from being KST-garbage-collected. So */ 808 /* dc_find$finished must be called to undo this dir holding. */ 809 /* */ 810 /* However, the linker calls $initiate_seg_count, which uses */ 811 /* dc_find$obj_initiate_for_linker_dp, which does NOT hold the containing */ 812 /* dir unless ename matches a link in the containing dir and the link gets */ 813 /* chased. If no links were chased, then the dir is NOT held and */ 814 /* lock$dir_unlock can be called directly. If links were chased, then */ 815 /* dc_find$finished must be called to unhold the dir containing the chased */ 816 /* link target. */ 817 /* */ 818 /* Finally, if the entry being initiated is the root, then there is no */ 819 /* containing directory to unlock. The input flags are set appropriately */ 820 /* by callers to cause the correct operation to occur. */ 821 /* */ 822 /* Output Args: */ 823 /* entrypoint.should_call_find_finished, */ 824 /* entrypoint.should_unlock_dir */ 825 /* turned off on output. */ 826 /* */ 827 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 828 829 /* Entries */ 830 831 dcl lock$dir_unlock entry (pointer); 832 833 if entrypoint.should_call_find_finished then 834 call dc_find$finished (seg.entp, DC_FIND_UNLOCK_DIR); 835 else if entrypoint.should_unlock_dir then 836 call lock$dir_unlock(seg.dirp); 837 entrypoint.should_call_find_finished, entrypoint.should_unlock_dir = FALSE; 838 839 end unlock_dir; 840 841 /* * * * * * * * * * * * * * * * * * * * * * * * * */ 842 ^L 843 %include dc_find_dcls; 844 ^L 845 %include dir_entry; 846 ^L 847 %include dir_header; 848 ^L 849 %include kst; 850 ^L 851 %include lot; 852 ^L 853 %include makeknown_info; 854 ^L 855 %include stack_header; 856 end initiate_;