COMPILATION LISTING OF SEGMENT mu_temp_segments Compiled by: Multics PL/I Compiler, Release 29, of July 28, 1986 Compiled at: Honeywell Multics Op. - System M Compiled on: 10/16/86 1335.6 mst Thu Options: optimize map 1 /****^ *********************************************************** 2* * * 3* * Copyright, (C) Honeywell Information Systems Inc., 1981 * 4* * * 5* * Copyright (c) 1972 by Massachusetts Institute of * 6* * Technology and Honeywell Information Systems, Inc. * 7* * * 8* *********************************************************** */ 9 10 11 /****^ HISTORY COMMENTS: 12* 1) change(86-02-14,Spitzer), approve(86-02-14,MCR7311), 13* audit(86-09-02,Blair), install(86-10-16,MR12.0-1187): 14* add free_temp_segments, get_temp_segment_path, cleanup_temp_dir 15* and get_temp_segments_path entry points. 16* END HISTORY COMMENTS */ 17 18 19 /* HISTORY: 20* 21* 11/21/75 by S. Webber (Initial coding) 22* 11/15/76 by Larry Johnson to add arguments to list_temp_segments 23* 08/29/77 by Melanie Weaver to add entry list_segnos 24* 11/2/77 by Richard A. Barnes to add get_temp_segment_ & release_temp_segment_ 25* 08/25/80 by E Brunelle, renamed mu* to be used by the MRDS system 26* . to allow 'temp' segments to be put into the mrds temp dir 27* . and to add entry free_temp_segment_, which does not truncate 28* . temp seg, to improve performance 29* 10/20/80 by Jim Gray, to use mrds_dsl_resultant_storage$get_opening_temp_dir, so that 30* . proper temp dir for a databse opening is used, 31* . this required adding the database index parameter to 32* . "get" entries. 33* 10/20/80 by Jim Gray, to change naming conventions for entries 34* . to those used by mdbm_util_, this meant removing 35* . trailing "_", having an unused main procedure, and entry 36* . names as would be seen in calls to mdbm_util_$get_temp_segment, etc. 37* 10/20/80 by Jim Gray, to add delete_all_temp_segments 38* . entry, so that dsl_$close can remove temp segs from the temp dir. 39* 10/20/80 by Jim Gray, to remove code that wiped out the caller when releasing, 40* . so that the delete entry could work properly, since the logic 41* . for the "used" bit always masks anyone from seeing it anyway. 42* 10/21/80 by Jim Gray, to change ".temp." suffix of temp seg names 43* . to ".MRDS.", in order to identify mrds temp segs. 44* 10/21/80 by Jim Gray, to insure that only temp segs belonging 45* . to the current caller, of those that are free, are actually used by the caller. 46* . this avoids one database opening using temp segs in another 47* . opeings temp dir, which can be removed by that opening being closed. 48* 10/21/80 by Jim Gray, to add free_all_temp_segments entry, 49* . that will be used by mrds_dsl_delete_se instead of 50* . the entry release_all_temp_segments. 51* . this is a tradeoff of capacity against performance. 52* 53* 81-09-16 Davids: changed the declarations of ename to char (32) 54* from char (20) and block.name to char (32) from char (25) so that 55* stringsize errors would not result when compiling with a prefix 56* of stringsize. 57* 58* 83-03-10 Davids: added the delete_temp_segment entry point. 59* 60* 83-05-03 Davids: Modified so that the uid of the directory the temp seg is 61* in is recorded in the block structure (dir_uid element). When a call to 62* get a temp segment is made the uid of the opening_temp_dir is obtained and 63* a free temp segment in the same temp dir is looked for. The old check that 64* assigned a temp segment only if the caller names were equal was removed - 65* as long as the temp seg is currently free who cares who originally created 66* it. For segments that are freed or released the caller name is changed to 67* FREE so that a call to (free release delete)_all which acts only on the 68* caller name will work correctly, i.e. not delete anything its not supposed 69* to. Adding the dbi onto the caller name does not help since the database 70* index is reused. 71* 72* 83-05-04 Davids: Modified to set the a_code parameter to 0 in the 73* delete_temp_segment entry so that if the segment is deleted it will return 74* 0 and not what ever happened to be input. 75**/ 76 77 mu_temp_segments: 78 proc (); 79 return; /* not valid entry */ 80 81 /* description and parameters on next page */ 82 83 /* DESCRIPTION: 84* 85* this program was originally the system get_temp_segment_ manager routines. 86* It was adopted for the MRDS subsystem utility interface. 87* This allowed the storage for the temp segments to be other than the process dir. 88* It added the entries free_temp_segment, and delete_all_temp_segments 89* to the existing entries of get_temp_segments(s), release_temp_segment(s), 90* list_temp_segments, list_segnos, release_all_temp_segments. 91* The free_temp_segment(s) does not do truncation on the temp segment, 92* in order to improve performance (the existing space is just reused) 93* The delete_all_temp_segments is used by dsl_$close to actually remove 94* all temp segments associated with a particular database opening. 95* The segments are named {unique_name}.MRDS.[seg_no] 96* The storage of the temp segments can be changed via the set_mrds_temp_dir command. 97* Each database opening will have it's own independent set of temp segs, 98* that are managed in a pool, unaffected by other db openings. 99* Currently mrds_dsl_search uses the temp segments for tid_array storage 100* in processing internal mrds intersection/union/difference of tuple id sets. 101* 102**/ 103 104 /* Parameters */ 105 106 dcl a_caller char (*); /* INPUT: calling program identifier */ 107 dcl a_path char (*); /* INPUT: directory to create temp segs in */ 108 dcl a_ptrs (*) ptr; /* pointers to temp segments INPUT/OUTPUT */ 109 dcl a_code fixed bin (35); /* OUTPUT: error status encoding */ 110 declare a_db_index fixed bin (35); /* INPUT: database opening index */ 111 112 /* Automatic */ 113 114 dcl new_block_ptr ptr; 115 dcl array_ptr ptr; 116 declare temp_dir char (168); /* path of mrds temp dir for this opening */ 117 dcl j fixed bin; 118 dcl n_segs fixed bin; 119 dcl new_blocks fixed bin; 120 dcl i fixed bin; 121 dcl n_found fixed bin; 122 declare n_deleted fixed bin; 123 dcl old_blocks fixed bin; 124 dcl code fixed bin (35); 125 dcl ename char (32); /* CHANGE 81-09-16 */ 126 dcl ename2 char (32); 127 dcl segno (4) char (1) defined (ename2) pos (22); 128 dcl segment_number fixed bin; 129 dcl found_it bit (1); 130 dcl arg_count fixed bin; 131 dcl arg_list_ptr ptr; 132 dcl arg_ptr ptr; 133 dcl arg_len fixed bin; 134 dcl release_called bit (1); 135 dcl containing_temp_dir char (168); 136 dcl entry_temp_dir char (32); 137 dcl temp_dir_uid bit (36); 138 dcl 01 local_status like status_branch; 139 140 /* Based */ 141 142 dcl ptrs (n_segs) ptr based (array_ptr); 143 dcl arg char (arg_len) based (arg_ptr); 144 dcl 1 octal_digits aligned based (addr (segment_number)), 145 2 filler bit (24) unal, 146 2 digit (4) bit (3) unal; 147 dcl 1 new_block (new_blocks) aligned based (new_block_ptr) like block; 148 dcl 1 block (n_blocks) aligned based (block_ptr), 149 2 dir_uid bit (36), 150 2 caller char (32), 151 2 segptr ptr, 152 2 name char (32), /* CHANGE 81-09-16 */ 153 2 used bit (1); 154 dcl area area based (areap); 155 156 /* Static */ 157 158 dcl block_ptr ptr static init (null); 159 dcl areap ptr static init (null); 160 dcl n_blocks fixed bin static init (0); 161 162 /* Builtin */ 163 164 dcl (addr, baseno, bin, dim, max, null, substr) builtin; 165 166 /* Entries */ 167 168 dcl hcs_$chname_seg entry (ptr, char (*), char (*), fixed bin (35)); 169 dcl get_system_free_area_ entry returns (ptr); 170 dcl hcs_$delentry_seg entry (ptr, fixed bin (35)); 171 dcl unique_chars_ entry (bit (*)) returns (char (15)); 172 dcl unique_bits_ entry returns (bit (70)); 173 dcl hcs_$truncate_seg entry (ptr, fixed bin, fixed bin (35)); 174 dcl hcs_$status_long entry (char (*), char (*), fixed bin (1), ptr, ptr, fixed bin (35)); 175 dcl expand_pathname_ entry (char (*), char (*), char (*), fixed bin (35)); 176 dcl hcs_$make_seg 177 entry (char (*), char (*), char (*), fixed bin (5), ptr, fixed bin (35)) 178 ; 179 dcl ioa_ entry options (variable); 180 dcl cu_$arg_count entry (fixed bin); 181 dcl cu_$arg_list_ptr entry (ptr); 182 dcl cu_$arg_ptr_rel entry (fixed bin, ptr, fixed bin, fixed bin (35), ptr); 183 dcl mrds_dsl_resultant_storage$get_opening_temp_dir 184 entry (fixed bin (35), fixed bin (35)) returns (char (168)); 185 186 /* External */ 187 188 dcl error_table_$argerr fixed bin (35) ext; 189 dcl error_table_$no_s_permission fixed bin (35) ext; 190 191 192 /* Includes */ 193 1 1 /* --------------- BEGIN include file status_structures.incl.pl1 --------------- */ 1 2 1 3 /* Revised from existing include files 09/26/78 by C. D. Tavares */ 1 4 1 5 /* This include file contains branch and link structures returned by 1 6* hcs_$status_ and hcs_$status_long. */ 1 7 1 8 dcl 1 status_branch aligned based (status_ptr), 1 9 2 short aligned, 1 10 3 type fixed bin (2) unaligned unsigned, /* seg, dir, or link */ 1 11 3 nnames fixed bin (16) unaligned unsigned, /* number of names */ 1 12 3 names_relp bit (18) unaligned, /* see entry_names dcl */ 1 13 3 dtcm bit (36) unaligned, /* date/time contents last modified */ 1 14 3 dtu bit (36) unaligned, /* date/time last used */ 1 15 3 mode bit (5) unaligned, /* caller's effective access */ 1 16 3 raw_mode bit (5) unaligned, /* caller's raw "rew" modes */ 1 17 3 pad1 bit (8) unaligned, 1 18 3 records_used fixed bin (18) unaligned unsigned, /* number of NONZERO pages used */ 1 19 1 20 /* Limit of information returned by hcs_$status_ */ 1 21 1 22 2 long aligned, 1 23 3 dtd bit (36) unaligned, /* date/time last dumped */ 1 24 3 dtem bit (36) unaligned, /* date/time branch last modified */ 1 25 3 lvid bit (36) unaligned, /* logical volume ID */ 1 26 3 current_length fixed bin (12) unaligned unsigned, /* number of last page used */ 1 27 3 bit_count fixed bin (24) unaligned unsigned, /* reported length in bits */ 1 28 3 pad2 bit (8) unaligned, 1 29 3 copy_switch bit (1) unaligned, /* copy switch */ 1 30 3 tpd_switch bit (1) unaligned, /* transparent to paging device switch */ 1 31 3 mdir_switch bit (1) unaligned, /* is a master dir */ 1 32 3 damaged_switch bit (1) unaligned, /* salvager warned of possible damage */ 1 33 3 synchronized_switch bit (1) unaligned, /* DM synchronized file */ 1 34 3 pad3 bit (5) unaligned, 1 35 3 ring_brackets (0:2) fixed bin (6) unaligned unsigned, 1 36 3 uid bit (36) unaligned; /* unique ID */ 1 37 1 38 dcl 1 status_link aligned based (status_ptr), 1 39 2 type fixed bin (2) unaligned unsigned, /* as above */ 1 40 2 nnames fixed bin (16) unaligned unsigned, 1 41 2 names_relp bit (18) unaligned, 1 42 2 dtem bit (36) unaligned, 1 43 2 dtd bit (36) unaligned, 1 44 2 pathname_length fixed bin (17) unaligned, /* see pathname */ 1 45 2 pathname_relp bit (18) unaligned; /* see pathname */ 1 46 1 47 dcl status_entry_names (status_branch.nnames) character (32) aligned 1 48 based (pointer (status_area_ptr, status_branch.names_relp)), 1 49 /* array of names returned */ 1 50 status_pathname character (status_link.pathname_length) aligned 1 51 based (pointer (status_area_ptr, status_link.pathname_relp)), 1 52 /* link target path */ 1 53 status_area_ptr pointer, 1 54 status_ptr pointer; 1 55 1 56 dcl (Link initial (0), 1 57 Segment initial (1), 1 58 Directory initial (2)) fixed bin internal static options (constant); 1 59 /* values for type fields declared above */ 1 60 1 61 /* ---------------- END include file status_structures.incl.pl1 ---------------- */ 194 195 196 /* Execution of mu_get_temp_segments_ begins here */ 197 198 get_temp_segments: 199 entry (a_db_index, a_caller, a_ptrs, a_code); 200 201 n_segs = dim (a_ptrs, 1); /* get number of segments wanted */ 202 array_ptr = addr (a_ptrs); /* get ptr to the array of ptrs */ 203 goto gts_join; 204 205 get_temp_segments_path: 206 entry (a_path, a_caller, a_ptrs, a_code); 207 208 temp_dir = a_path; 209 n_segs = dim (a_ptrs, 1); 210 array_ptr = addr (a_ptrs); 211 goto gts_join_have_path; 212 213 gts_join: 214 temp_dir = 215 mrds_dsl_resultant_storage$get_opening_temp_dir (a_db_index, code); 216 if code ^= 0 then do; 217 a_code = code; 218 return; 219 end; 220 221 gts_join_have_path: 222 a_code = 0; 223 n_found = 0; /* initialize indicating we've found no free entries */ 224 call expand_pathname_ (temp_dir, containing_temp_dir, entry_temp_dir, code); 225 if code ^= 0 then do; 226 a_code = code; 227 return; 228 end; 229 status_ptr = addr (local_status); 230 call hcs_$status_long (containing_temp_dir, entry_temp_dir, 0, status_ptr, null (), code); 231 if code ^= 0 & code ^= error_table_$no_s_permission then do; 232 a_code = code; 233 return; 234 end; 235 temp_dir_uid = status_ptr -> status_branch.long.uid; 236 237 if block_ptr = null then do; /* we haven't yet gotten any segments */ 238 n_blocks = n_segs; /* so get the exact amount requested */ 239 areap = get_system_free_area_ (); /* get pointer to standard area to use */ 240 allocate block in (area) set (block_ptr); /* get the needed storage */ 241 old_blocks = 0; /* needed by get_new_segments routine */ 242 call get_new_segments; /* do the work in this subr */ 243 return; 244 end; 245 246 do i = 1 to n_blocks while (n_found < n_segs); /* search for the necessary free segments */ 247 if ^block (i).used & (block (i).dir_uid = temp_dir_uid) then do; 248 /* we found another free one */ 249 250 /* we have found an unused temp seg in the appropriate temp dir */ 251 252 block (i).used = "1"b; /* mark entry as being used */ 253 block (i).caller = a_caller; /* update the caller name */ 254 n_found = n_found + 1; 255 ptrs (n_found) = block (i).segptr; 256 end; 257 end; 258 if n_found < n_segs then do; /* there weren't enough free ones */ 259 new_blocks = n_blocks + n_segs - n_found; /* get more storage, just large enough */ 260 old_blocks = n_blocks; 261 if areap = null then 262 areap = get_system_free_area_ (); /* get pointer to area */ 263 allocate new_block in (area) set (new_block_ptr); /* get the needed storage */ 264 new_block_ptr -> block = block; /* copy the current structure */ 265 free block in (area); 266 n_blocks = new_blocks; 267 block_ptr = new_block_ptr; 268 call get_new_segments; /* get the needed segments */ 269 end; 270 271 return; 272 273 get_new_segments: 274 proc; 275 276 dcl (i, j) fixed bin; 277 278 do i = old_blocks + 1 to n_blocks; /* initialize the new entries */ 279 block (i).used = "1"b; /* the caller will use these blocks */ 280 block (i).caller = a_caller; /* ditto */ 281 block (i).dir_uid = temp_dir_uid; 282 ename2 = unique_chars_ (unique_bits_ ()) || ".MRDS."; 283 ename = ename2; 284 call 285 hcs_$make_seg (temp_dir, ename, "", 01110b, block (i).segptr, code); 286 if code ^= 0 then do; 287 call undo; 288 return; 289 end; 290 segment_number = bin (baseno (block (i).segptr), 18); 291 do j = 1 to 4; 292 segno (j) = substr ("01234567", bin (digit (j), 3) + 1, 1); 293 end; 294 call hcs_$chname_seg (block (i).segptr, ename, ename2, code); 295 if code ^= 0 then do; 296 call undo; 297 return; 298 end; 299 block (i).name = ename2; 300 n_found = n_found + 1; 301 ptrs (n_found) = block (i).segptr; 302 end; 303 304 undo: 305 proc; 306 307 a_code = code; 308 n_blocks = old_blocks; /* reset to the way things were */ 309 do j = old_blocks + 1 to i - 1; /* clean up the segments we already got */ 310 call hcs_$delentry_seg (block (j).segptr, code); 311 end; 312 313 end; 314 end; 315 316 get_temp_segment: 317 entry (a_db_index, a_caller, a_ptr, a_code); 318 319 dcl a_ptr ptr parameter; 320 321 n_segs = 1; /* only 1 segment is being processed */ 322 array_ptr = addr (a_ptr); 323 go to gts_join; 324 325 get_temp_segment_path: 326 entry (a_path, a_caller, a_ptr, a_code); 327 328 temp_dir = a_path; 329 n_segs = 1; 330 array_ptr = addr (a_ptr); 331 goto gts_join_have_path; 332 333 release_temp_segments: 334 entry (a_caller, a_ptrs, a_code); 335 336 n_segs = dim (a_ptrs, 1); /* get number of segments wanted */ 337 array_ptr = addr (a_ptrs); /* get ptr to the array of ptrs */ 338 release_called = "1"b; /* need to truncate also */ 339 rts_join: 340 a_code = 0; 341 do i = 1 to n_segs; /* release each segment passed in */ 342 if ptrs (i) ^= null then do; 343 found_it = "0"b; /* flag says we've not yet found this segment */ 344 do j = 1 to n_blocks while (^found_it); /* search for segment in array */ 345 if block (j).used then do; /* candidate, see if right one */ 346 if ptrs (i) = block (j).segptr then do; /* we found the given segment */ 347 if block (j).caller ^= a_caller then 348 a_code = error_table_$argerr; 349 else do; /* the right guy (as far as we care) */ 350 if release_called then do; /* wants to truncate it also */ 351 call hcs_$truncate_seg (block (j).segptr, 0, code); 352 /* truncate now */ 353 if code ^= 0 then 354 a_code = code; /* accumulate error */ 355 end; 356 block (j).used = "0"b; /* ditto */ 357 block (j).caller = "FREE"; 358 ptrs (i) = null; 359 found_it = "1"b; 360 end; 361 end; 362 end; 363 end; 364 if ^found_it then 365 a_code = error_table_$argerr; 366 end; 367 end; 368 return; 369 370 release_temp_segment: 371 entry (a_caller, a_ptr, a_code); 372 373 n_segs = 1; /* only 1 segment is being processed */ 374 array_ptr = addr (a_ptr); 375 release_called = "1"b; /* truncate the seg also */ 376 goto rts_join; 377 378 free_temp_segments: 379 entry (a_caller, a_ptrs, a_code); 380 381 n_segs = dim (a_ptrs, 1); 382 array_ptr = addr (a_ptrs); 383 release_called = "0"b; 384 goto rts_join; 385 386 387 388 free_temp_segment: 389 entry (a_caller, a_ptr, a_code); 390 391 /* this entry will just free the segment and not truncate it */ 392 /* this is a performance hack */ 393 394 n_segs = 1; /* only 1 segment is being processed */ 395 array_ptr = addr (a_ptr); 396 release_called = "0"b; /* just free the seg */ 397 goto rts_join; 398 399 release_all_temp_segments: 400 entry (a_caller, a_code); 401 402 /* entry to release all temp segments for a_caller */ 403 404 release_called = "1"b; 405 406 rats_join: 407 a_code = 0; 408 found_it = "0"b; /* flag says we've not yet found this segment */ 409 do j = 1 to n_blocks; /* search for segment in array */ 410 if block (j).used then /* candidate, see if right one */ 411 if block (j).caller = a_caller then do; /* the right guy (as far as we care) */ 412 if release_called then do; 413 call hcs_$truncate_seg (block (j).segptr, 0, code); 414 /* truncate now */ 415 if code ^= 0 then 416 a_code = code; /* accumulate error */ 417 end; 418 block (j).used = "0"b; /* ditto */ 419 block (j).caller = "FREE"; 420 found_it = "1"b; 421 end; 422 end; 423 if ^found_it then 424 a_code = error_table_$argerr; 425 return; 426 427 428 429 430 431 432 433 434 435 436 free_all_temp_segments: 437 entry (a_caller, a_code); 438 439 /* entry to set temp segs for caller to un-unused, 440* without doing a truncation of the segments. 441* this saves time, but allows the temp segs to grow to that 442* size which the largest selection expression would use */ 443 444 release_called = "0"b; 445 goto rats_join; 446 447 delete_all_temp_segments: 448 entry (a_caller, a_code); 449 450 /* entry to delete all temp segments for a_caller */ 451 452 a_code = 0; 453 found_it = "0"b; /* flag says we've not yet found this segment */ 454 n_deleted = 0; 455 do j = 1 to n_blocks; /* search for segment in array */ 456 if block (j).caller = a_caller then do; /* the right guy (as far as we care) */ 457 call hcs_$delentry_seg (block (j).segptr, code); 458 if code ^= 0 then 459 a_code = code; /* accumulate error */ 460 n_deleted = n_deleted + 1; 461 found_it = "1"b; 462 end; 463 end; 464 465 /* shrink list of temp segments, removing current callers 466* temp segments from the list of all temp segs */ 467 468 469 if ^found_it then 470 a_code = error_table_$argerr; /* no segs for caller */ 471 else do; 472 new_blocks = n_blocks - n_deleted; 473 old_blocks = n_blocks; 474 if areap = null then 475 areap = get_system_free_area_ (); 476 allocate new_block in (area) set (new_block_ptr); 477 478 i = 1; 479 do j = 1 to old_blocks; 480 if block (j).caller = a_caller then 481 ; 482 else do; /* save everyone elses temp segs */ 483 new_block (i) = block (j); 484 i = i + 1; 485 end; 486 487 end; 488 489 free block in (area); 490 n_blocks = new_blocks; 491 block_ptr = new_block_ptr; 492 493 end; 494 495 return; 496 497 /* this entry is mainly called by restructure_mrds_db to delete all the temp 498* segments in some directory. this is because rmdb creates a temp dir in the 499* temp dir specified, then deletes the created dir to get rid of all segments 500* at once. the saved static pointers in this program are invalid and may point 501* to other initiated segments. */ 502 503 cleanup_temp_dir: 504 entry (a_path, a_code); 505 506 a_code = 0; 507 found_it = "0"b; 508 n_deleted = 0; 509 call expand_pathname_ (a_path, containing_temp_dir, entry_temp_dir, code); 510 if code ^= 0 then do; 511 a_code = code; 512 goto end_cleanup_temp_dir; 513 end; 514 515 status_ptr = addr (local_status); 516 call hcs_$status_long (containing_temp_dir, entry_temp_dir, 0, status_ptr, null (), code); 517 if code ^= 0 & code ^= error_table_$no_s_permission then do; 518 a_code = code; 519 goto end_cleanup_temp_dir; 520 end; 521 temp_dir_uid = status_ptr -> status_branch.long.uid; 522 523 /* delete all segments with the same containing directory uid */ 524 do j = 1 to n_blocks; 525 if block (j).dir_uid = temp_dir_uid then do; 526 call hcs_$delentry_seg (block (j).segptr, code); 527 if code ^= 0 then a_code = code; 528 529 n_deleted = n_deleted + 1; 530 found_it = "1"b; 531 end; 532 end; /* do j */ 533 534 /* shrink the list of temp segments. */ 535 if ^found_it then 536 a_code = error_table_$argerr; 537 else do; 538 new_blocks = n_blocks - n_deleted; 539 old_blocks = n_blocks; 540 if areap = null then 541 areap = get_system_free_area_ (); 542 allocate new_block in (area) set (new_block_ptr); 543 544 i = 1; 545 do j = 1 to old_blocks; 546 if block (j).dir_uid = temp_dir_uid then 547 ; /* ignore this directories entries */ 548 else do; 549 new_block (i) = block (j); 550 i = i + 1; 551 end; 552 end; /* do j */ 553 554 free block in (area); 555 n_blocks = new_blocks; 556 block_ptr = new_block_ptr; 557 558 end; 559 560 end_cleanup_temp_dir: 561 return; 562 563 delete_temp_segment: entry (a_caller, a_ptr, a_code); 564 565 /* this entry will delete the segment with the given name and pointer */ 566 567 n_segs = 1; 568 array_ptr = addr (a_ptr); 569 a_code = 0; 570 571 found_it = "0"b; 572 do i = 1 to n_blocks while (^found_it); 573 if block (i).segptr = ptrs (1) & block (i).caller = a_caller 574 then found_it = "1"b; 575 end; 576 577 if ^found_it 578 then do; 579 a_code = error_table_$argerr; 580 goto exit_delete_temp_segment; 581 end; 582 583 i = i - 1; /* search loop increments i before checking found_it */ 584 call hcs_$delentry_seg (block (i).segptr, code); 585 if code ^= 0 586 then do; 587 a_code = code; 588 goto exit_delete_temp_segment; 589 end; 590 591 new_blocks = n_blocks - 1; 592 old_blocks = n_blocks; 593 if areap = null 594 then areap = get_system_free_area_ (); 595 allocate new_block in (area) set (new_block_ptr); 596 do j = 1 to i - 1; 597 new_block (j) = block (j); 598 end; 599 do j = i + 1 to old_blocks; 600 new_block (j - 1) = block (j); 601 end; 602 free block in (area); 603 n_blocks = new_blocks; 604 block_ptr = new_block_ptr; 605 606 exit_delete_temp_segment: 607 return; 608 609 list_temp_segments: 610 entry; 611 612 if n_blocks = 0 then do; /* nothing ever allocated */ 613 call ioa_ ("No temporary segments."); 614 return; 615 end; 616 call cu_$arg_count (arg_count); 617 call cu_$arg_list_ptr (arg_list_ptr); 618 619 begin; /* to allocate storage */ 620 621 dcl treq char (32); 622 dcl req (max (1, arg_count)) char (32); 623 dcl nreq fixed bin; /* number of names requested */ 624 dcl all_sw bit (1); /* set if -all given */ 625 dcl (i, j, cnt) fixed bin; 626 dcl dup_sw bit (1); 627 628 nreq = 0; 629 all_sw = "0"b; 630 do i = 1 to arg_count; /* get table of requests */ 631 call cu_$arg_ptr_rel (i, arg_ptr, arg_len, code, arg_list_ptr); 632 if arg = "-all" | arg = "-a" then 633 all_sw = "1"b; 634 else do; 635 dup_sw = "0"b; /* be sure not given dup args */ 636 treq = arg; 637 do j = 1 to nreq; 638 if req (j) = treq then 639 dup_sw = "1"b; 640 end; 641 if ^dup_sw then do; /* new one */ 642 nreq = nreq + 1; 643 req (nreq) = treq; 644 end; 645 end; 646 end; 647 if all_sw then 648 nreq = 0; 649 650 if nreq = 0 then do; /* if no special requests */ 651 cnt = 0; 652 do i = 1 to n_blocks; /* count free segs */ 653 if ^block.used (i) then 654 cnt = cnt + 1; 655 end; 656 call 657 ioa_ ("^/^-^d Segment^[s^], ^d Free^/", n_blocks, 658 (n_blocks ^= 1), cnt); 659 end; 660 else do; /* count segments that match requests */ 661 cnt = 0; 662 do i = 1 to n_blocks; 663 if block.used (i) then 664 do j = 1 to nreq; 665 if block.caller (i) = req (j) then 666 cnt = cnt + 1; 667 end; 668 end; 669 call ioa_ ("^/^-^d Segment^[s^] used.^/", cnt, (cnt ^= 1)); 670 end; 671 672 do i = 1 to n_blocks; /* now print them */ 673 if all_sw then 674 go to print_it; 675 else if block.used (i) then do; 676 if nreq = 0 then 677 go to print_it; 678 else 679 do j = 1 to nreq; 680 if block.caller (i) = req (j) then 681 go to print_it; 682 end; 683 end; 684 go to next_block; 685 print_it: 686 call 687 ioa_ ("^a ^[^a^;(free)^]", block.name (i), block.used (i), 688 block.caller (i)); 689 next_block: 690 end; 691 call ioa_ (""); 692 end; 693 return; 694 695 list_segnos: 696 entry (struc_ptr); 697 698 dcl struc_ptr ptr; 699 dcl 1 segno_struc aligned based (struc_ptr), 700 2 num_segs fixed bin, 701 2 segno (n_blocks) fixed bin; 702 703 704 if (block_ptr = null) | (areap = null) then do; 705 struc_ptr = null; 706 return; 707 end; 708 709 allocate segno_struc in (area) set (struc_ptr); 710 segno_struc.num_segs = n_blocks; 711 do i = 1 to n_blocks; 712 segno_struc.segno (i) = bin (baseno (block (i).segptr), 15); 713 end; 714 715 return; 716 717 718 end; SOURCE FILES USED IN THIS COMPILATION. LINE NUMBER DATE MODIFIED NAME PATHNAME 0 10/16/86 1144.3 mu_temp_segments.pl1 >special_ldd>install>MR12.0-1187>mu_temp_segments.pl1 194 1 11/22/82 0955.7 status_structures.incl.pl1 >ldd>include>status_structures.incl.pl1 NAMES DECLARED IN THIS COMPILATION. IDENTIFIER OFFSET LOC STORAGE CLASS DATA TYPE ATTRIBUTES AND REFERENCES (* indicates a set context) NAMES DECLARED BY DECLARE STATEMENT. a_caller parameter char unaligned dcl 106 ref 198 205 253 280 316 325 333 347 370 378 388 399 410 436 447 456 480 563 573 a_code parameter fixed bin(35,0) dcl 109 set ref 198 205 217* 221* 226* 232* 307* 316 325 333 339* 347* 353* 364* 370 378 388 399 406* 415* 423* 436 447 452* 458* 469* 503 506* 511* 518* 527* 535* 563 569* 579* 587* a_db_index parameter fixed bin(35,0) dcl 110 set ref 198 213* 316 a_path parameter char unaligned dcl 107 set ref 205 208 325 328 503 509* a_ptr parameter pointer dcl 319 set ref 316 322 325 330 370 374 388 395 563 568 a_ptrs parameter pointer array dcl 108 set ref 198 201 202 205 209 210 333 336 337 378 381 382 addr builtin function dcl 164 ref 202 210 229 292 322 330 337 374 382 395 515 568 all_sw 000111 automatic bit(1) unaligned dcl 624 set ref 629* 632* 647 673 area based area(1024) dcl 154 ref 240 263 265 476 489 542 554 595 602 709 areap 000012 internal static pointer initial dcl 159 set ref 239* 240 261 261* 263 265 474 474* 476 489 540 540* 542 554 593 593* 595 602 704 709 arg based char unaligned dcl 143 ref 632 632 636 arg_count 000210 automatic fixed bin(17,0) dcl 130 set ref 616* 622 630 arg_len 000216 automatic fixed bin(17,0) dcl 133 set ref 631* 632 632 636 arg_list_ptr 000212 automatic pointer dcl 131 set ref 617* 631* arg_ptr 000214 automatic pointer dcl 132 set ref 631* 632 632 636 array_ptr 000102 automatic pointer dcl 115 set ref 202* 210* 255 301 322* 330* 337* 342 346 358 374* 382* 395* 568* 573 baseno builtin function dcl 164 ref 290 712 bin builtin function dcl 164 ref 290 292 712 block based structure array level 1 dcl 148 set ref 240 264* 264 265 483 489 549 554 597 600 602 block_ptr 000010 internal static pointer initial dcl 158 set ref 237 240* 247 247 252 253 255 264 265 267* 279 280 281 284 290 294 299 301 310 345 346 347 351 356 357 410 410 413 418 419 456 457 480 483 489 491* 525 526 546 549 554 556* 573 573 584 597 600 602 604* 653 663 665 675 680 685 685 685 704 712 caller 1 based char(32) array level 2 dcl 148 set ref 253* 280* 347 357* 410 419* 456 480 573 665 680 685* cnt 000114 automatic fixed bin(17,0) dcl 625 set ref 651* 653* 653 656* 661* 665* 665 669* 669 code 000165 automatic fixed bin(35,0) dcl 124 set ref 213* 216 217 224* 225 226 230* 231 231 232 284* 286 294* 295 307 310* 351* 353 353 413* 415 415 457* 458 458 509* 510 511 516* 517 517 518 526* 527 527 584* 585 587 631* containing_temp_dir 000220 automatic char(168) unaligned dcl 135 set ref 224* 230* 509* 516* cu_$arg_count 000042 constant entry external dcl 180 ref 616 cu_$arg_list_ptr 000044 constant entry external dcl 181 ref 617 cu_$arg_ptr_rel 000046 constant entry external dcl 182 ref 631 digit 0(24) based bit(3) array level 2 packed unaligned dcl 144 ref 292 dim builtin function dcl 164 ref 201 209 336 381 dir_uid based bit(36) array level 2 dcl 148 set ref 247 281* 525 546 dup_sw 000115 automatic bit(1) unaligned dcl 626 set ref 635* 638* 641 ename 000166 automatic char(32) unaligned dcl 125 set ref 283* 284* 294* ename2 000176 automatic char(32) unaligned dcl 126 set ref 282* 283 292* 292 294* 299 entry_temp_dir 000272 automatic char(32) unaligned dcl 136 set ref 224* 230* 509* 516* error_table_$argerr 000052 external static fixed bin(35,0) dcl 188 ref 347 364 423 469 535 579 error_table_$no_s_permission 000054 external static fixed bin(35,0) dcl 189 ref 231 517 expand_pathname_ 000034 constant entry external dcl 175 ref 224 509 found_it 000207 automatic bit(1) unaligned dcl 129 set ref 343* 344 359* 364 408* 420* 423 453* 461* 469 507* 530* 535 571* 572 573* 577 get_system_free_area_ 000020 constant entry external dcl 169 ref 239 261 474 540 593 hcs_$chname_seg 000016 constant entry external dcl 168 ref 294 hcs_$delentry_seg 000022 constant entry external dcl 170 ref 310 457 526 584 hcs_$make_seg 000036 constant entry external dcl 176 ref 284 hcs_$status_long 000032 constant entry external dcl 174 ref 230 516 hcs_$truncate_seg 000030 constant entry external dcl 173 ref 351 413 i 000161 automatic fixed bin(17,0) dcl 120 in procedure "mu_temp_segments" set ref 246* 247 247 252 253 255* 341* 342 346 358* 478* 483 484* 484 544* 549 550* 550 572* 573 573* 583* 583 584 596 599 711* 712 712* i 000356 automatic fixed bin(17,0) dcl 276 in procedure "get_new_segments" set ref 278* 279 280 281 284 290 294 299 301* 309 i 000112 automatic fixed bin(17,0) dcl 625 in begin block on line 619 set ref 630* 631* 652* 653* 662* 663 665* 672* 675 680 685 685 685* ioa_ 000040 constant entry external dcl 179 ref 613 656 669 685 691 j 000357 automatic fixed bin(17,0) dcl 276 in procedure "get_new_segments" set ref 291* 292 292* 309* 310* j 000156 automatic fixed bin(17,0) dcl 117 in procedure "mu_temp_segments" set ref 344* 345 346 347 351 356 357* 409* 410 410 413 418 419* 455* 456 457* 479* 480 483* 524* 525 526* 545* 546 549* 596* 597 597* 599* 600 600* j 000113 automatic fixed bin(17,0) dcl 625 in begin block on line 619 set ref 637* 638* 663* 665* 678* 680* local_status 000303 automatic structure level 1 unaligned dcl 138 set ref 229 515 long 4 based structure level 2 dcl 1-8 max builtin function dcl 164 ref 622 mrds_dsl_resultant_storage$get_opening_temp_dir 000050 constant entry external dcl 183 ref 213 n_blocks 000014 internal static fixed bin(17,0) initial dcl 160 set ref 238* 240 246 259 260 264 265 266* 278 308* 344 409 455 472 473 489 490* 524 538 539 554 555* 572 591 592 602 603* 612 652 656* 656 662 672 709 710 711 n_deleted 000163 automatic fixed bin(17,0) dcl 122 set ref 454* 460* 460 472 508* 529* 529 538 n_found 000162 automatic fixed bin(17,0) dcl 121 set ref 223* 246 254* 254 255 258 259 300* 300 301 n_segs 000157 automatic fixed bin(17,0) dcl 118 set ref 201* 209* 238 246 258 259 321* 329* 336* 341 373* 381* 394* 567* name 14 based char(32) array level 2 dcl 148 set ref 299* 685* new_block based structure array level 1 dcl 147 set ref 263 476 483* 542 549* 595 597* 600* new_block_ptr 000100 automatic pointer dcl 114 set ref 263* 264 267 476* 483 491 542* 549 556 595* 597 600 604 new_blocks 000160 automatic fixed bin(17,0) dcl 119 set ref 259* 263 266 472* 476 490 538* 542 555 591* 595 603 nreq 000110 automatic fixed bin(17,0) dcl 623 set ref 628* 637 642* 642 643 647* 650 663 676 678 null builtin function dcl 164 ref 230 230 237 261 342 358 474 516 516 540 593 704 704 705 num_segs based fixed bin(17,0) level 2 dcl 699 set ref 710* octal_digits based structure level 1 dcl 144 old_blocks 000164 automatic fixed bin(17,0) dcl 123 set ref 241* 260* 278 308 309 473* 479 539* 545 592* 599 ptrs based pointer array dcl 142 set ref 255* 301* 342 346 358* 573 release_called 000217 automatic bit(1) unaligned dcl 134 set ref 338* 350 375* 383* 396* 404* 412 444* req 000110 automatic char(32) array unaligned dcl 622 set ref 638 643* 665 680 segment_number 000206 automatic fixed bin(17,0) dcl 128 set ref 290* 292 segno defined char(1) array unaligned dcl 127 in procedure "mu_temp_segments" set ref 292* segno 1 based fixed bin(17,0) array level 2 in structure "segno_struc" dcl 699 in procedure "mu_temp_segments" set ref 712* segno_struc based structure level 1 dcl 699 set ref 709 segptr 12 based pointer array level 2 dcl 148 set ref 255 284* 290 294* 301 310* 346 351* 413* 457* 526* 573 584* 712 status_branch based structure level 1 dcl 1-8 status_ptr 000316 automatic pointer dcl 1-47 set ref 229* 230* 235 515* 516* 521 struc_ptr parameter pointer dcl 698 set ref 695 705* 709* 710 712 substr builtin function dcl 164 ref 292 temp_dir 000104 automatic char(168) unaligned dcl 116 set ref 208* 213* 224* 284* 328* temp_dir_uid 000302 automatic bit(36) unaligned dcl 137 set ref 235* 247 281 521* 525 546 treq 000100 automatic char(32) unaligned dcl 621 set ref 636* 638 643 uid 11 based bit(36) level 3 packed unaligned dcl 1-8 ref 235 521 unique_bits_ 000026 constant entry external dcl 172 ref 282 282 unique_chars_ 000024 constant entry external dcl 171 ref 282 used 24 based bit(1) array level 2 dcl 148 set ref 247 252* 279* 345 356* 410 418* 653 663 675 685* NAMES DECLARED BY DECLARE STATEMENT AND NEVER REFERENCED. Directory internal static fixed bin(17,0) initial dcl 1-56 Link internal static fixed bin(17,0) initial dcl 1-56 Segment internal static fixed bin(17,0) initial dcl 1-56 status_area_ptr automatic pointer dcl 1-47 status_entry_names based char(32) array dcl 1-47 status_link based structure level 1 dcl 1-38 status_pathname based char dcl 1-47 NAMES DECLARED BY EXPLICIT CONTEXT. cleanup_temp_dir 001512 constant entry external dcl 503 delete_all_temp_segments 001302 constant entry external dcl 447 delete_temp_segment 002010 constant entry external dcl 563 end_cleanup_temp_dir 002005 constant label dcl 560 ref 512 519 exit_delete_temp_segment 002236 constant label dcl 606 ref 580 588 free_all_temp_segments 001261 constant entry external dcl 436 free_temp_segment 001111 constant entry external dcl 388 free_temp_segments 001052 constant entry external dcl 378 get_new_segments 003036 constant entry internal dcl 273 ref 242 268 get_temp_segment 000525 constant entry external dcl 316 get_temp_segment_path 000556 constant entry external dcl 325 get_temp_segments 000104 constant entry external dcl 198 get_temp_segments_path 000145 constant entry external dcl 205 gts_join 000214 constant label dcl 213 ref 203 323 gts_join_have_path 000234 constant label dcl 221 ref 211 331 list_segnos 002754 constant entry external dcl 695 list_temp_segments 002240 constant entry external dcl 609 mu_temp_segments 000071 constant entry external dcl 77 next_block 002734 constant label dcl 689 ref 684 print_it 002670 constant label dcl 685 ref 673 676 680 rats_join 001161 constant label dcl 406 ref 445 release_all_temp_segments 001142 constant entry external dcl 399 release_temp_segment 001022 constant entry external dcl 370 release_temp_segments 000621 constant entry external dcl 333 rts_join 000656 constant label dcl 339 ref 376 384 397 undo 003314 constant entry internal dcl 304 ref 287 296 THERE WERE NO NAMES DECLARED BY CONTEXT OR IMPLICATION. STORAGE REQUIREMENTS FOR THIS PROGRAM. Object Text Link Symbol Defs Static Start 0 0 3772 4050 3352 4002 Length 4400 3352 56 314 417 6 BLOCK NAME STACK SIZE TYPE WHY NONQUICK/WHO SHARES STACK FRAME mu_temp_segments 360 external procedure is an external procedure. get_new_segments internal procedure shares stack frame of external procedure mu_temp_segments. undo internal procedure shares stack frame of external procedure mu_temp_segments. begin block on line 619 122 begin block uses auto adjustable storage. STORAGE FOR INTERNAL STATIC VARIABLES. LOC IDENTIFIER BLOCK NAME 000010 block_ptr mu_temp_segments 000012 areap mu_temp_segments 000014 n_blocks mu_temp_segments STORAGE FOR AUTOMATIC VARIABLES. STACK FRAME LOC IDENTIFIER BLOCK NAME begin block on line 619 000100 treq begin block on line 619 000110 nreq begin block on line 619 000110 req begin block on line 619 000111 all_sw begin block on line 619 000112 i begin block on line 619 000113 j begin block on line 619 000114 cnt begin block on line 619 000115 dup_sw begin block on line 619 mu_temp_segments 000100 new_block_ptr mu_temp_segments 000102 array_ptr mu_temp_segments 000104 temp_dir mu_temp_segments 000156 j mu_temp_segments 000157 n_segs mu_temp_segments 000160 new_blocks mu_temp_segments 000161 i mu_temp_segments 000162 n_found mu_temp_segments 000163 n_deleted mu_temp_segments 000164 old_blocks mu_temp_segments 000165 code mu_temp_segments 000166 ename mu_temp_segments 000176 ename2 mu_temp_segments 000206 segment_number mu_temp_segments 000207 found_it mu_temp_segments 000210 arg_count mu_temp_segments 000212 arg_list_ptr mu_temp_segments 000214 arg_ptr mu_temp_segments 000216 arg_len mu_temp_segments 000217 release_called mu_temp_segments 000220 containing_temp_dir mu_temp_segments 000272 entry_temp_dir mu_temp_segments 000302 temp_dir_uid mu_temp_segments 000303 local_status mu_temp_segments 000316 status_ptr mu_temp_segments 000356 i get_new_segments 000357 j get_new_segments THE FOLLOWING EXTERNAL OPERATORS ARE USED BY THIS PROGRAM. r_ne_as alloc_char_temp enter_begin_block leave_begin_block call_ext_out_desc call_ext_out return_mac alloc_auto_adj shorten_stack ext_entry ext_entry_desc op_alloc_ op_freen_ THE FOLLOWING EXTERNAL ENTRIES ARE CALLED BY THIS PROGRAM. cu_$arg_count cu_$arg_list_ptr cu_$arg_ptr_rel expand_pathname_ get_system_free_area_ hcs_$chname_seg hcs_$delentry_seg hcs_$make_seg hcs_$status_long hcs_$truncate_seg ioa_ mrds_dsl_resultant_storage$get_opening_temp_dir unique_bits_ unique_chars_ THE FOLLOWING EXTERNAL VARIABLES ARE USED BY THIS PROGRAM. error_table_$argerr error_table_$no_s_permission LINE LOC LINE LOC LINE LOC LINE LOC LINE LOC LINE LOC LINE LOC 77 000070 79 000076 198 000077 201 000125 202 000135 203 000137 205 000140 208 000173 209 000201 210 000211 211 000213 213 000214 216 000230 217 000232 218 000233 221 000234 223 000235 224 000236 225 000262 226 000264 227 000265 229 000266 230 000270 231 000327 232 000334 233 000335 235 000336 237 000341 238 000346 239 000350 240 000356 241 000366 242 000367 243 000370 246 000371 247 000404 252 000417 253 000421 254 000433 255 000434 257 000441 258 000443 259 000446 260 000453 261 000455 263 000467 264 000476 265 000507 266 000511 267 000514 268 000516 271 000517 316 000520 321 000544 322 000546 323 000550 325 000551 328 000602 329 000610 330 000612 331 000614 333 000615 336 000642 337 000652 338 000654 339 000656 341 000657 342 000667 343 000675 344 000676 345 000711 346 000720 347 000731 350 000746 351 000750 353 000763 356 000766 357 000772 358 000776 359 001002 363 001004 364 001006 367 001013 368 001015 370 001016 373 001041 374 001043 375 001045 376 001047 378 001050 381 001073 382 001103 383 001105 384 001106 388 001107 394 001130 395 001132 396 001134 397 001135 399 001136 404 001157 406 001161 408 001162 409 001163 410 001173 412 001215 413 001217 415 001232 418 001235 419 001241 420 001245 422 001247 423 001251 425 001256 436 001257 444 001276 445 001277 447 001300 452 001317 453 001320 454 001321 455 001322 456 001333 457 001352 458 001363 460 001366 461 001367 463 001371 469 001373 472 001401 473 001405 474 001407 476 001421 478 001430 479 001432 480 001441 483 001461 484 001472 487 001473 489 001475 490 001502 491 001505 495 001507 503 001510 506 001530 507 001531 508 001532 509 001533 510 001562 511 001564 512 001565 515 001566 516 001570 517 001627 518 001634 519 001635 521 001636 524 001641 525 001651 526 001660 527 001670 529 001673 530 001674 532 001676 535 001700 538 001706 539 001712 540 001714 542 001726 544 001735 545 001737 546 001747 549 001757 550 001770 552 001771 554 001773 555 002000 556 002003 560 002005 563 002006 567 002027 568 002031 569 002033 571 002034 572 002035 573 002047 575 002074 577 002076 579 002100 580 002103 583 002104 584 002106 585 002122 587 002124 588 002125 591 002126 592 002132 593 002134 595 002146 596 002155 597 002165 598 002176 599 002200 600 002211 601 002222 602 002224 603 002231 604 002234 606 002236 609 002237 612 002245 613 002250 614 002263 616 002264 617 002272 619 002301 622 002304 628 002316 629 002317 630 002320 631 002327 632 002347 635 002365 636 002366 637 002371 638 002401 640 002412 641 002414 642 002416 643 002417 646 002426 647 002430 650 002433 651 002435 652 002436 653 002447 655 002456 656 002460 659 002513 661 002514 662 002515 663 002525 665 002543 667 002562 668 002564 669 002566 672 002616 673 002627 675 002631 676 002637 678 002641 680 002647 682 002665 684 002667 685 002670 689 002734 691 002736 692 002747 693 002750 695 002751 704 002761 705 002772 706 002775 709 002776 710 003006 711 003011 712 003021 713 003033 715 003035 273 003036 278 003037 279 003051 280 003056 281 003070 282 003072 283 003131 284 003135 286 003200 287 003202 288 003203 290 003204 291 003213 292 003221 293 003233 294 003235 295 003267 296 003271 297 003272 299 003273 300 003302 301 003303 302 003311 314 003313 304 003314 307 003315 308 003317 309 003322 310 003333 311 003346 313 003350 ----------------------------------------------------------- Historical Background This edition of the Multics software materials and documentation is provided and donated to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. as a contribution to computer science knowledge. This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL and BULL HN Information Systems Inc. to the development of this operating system. Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture for managing computer hardware properly and for executing programs. Many subsequent operating systems incorporated Multics principles. Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . ----------------------------------------------------------- Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without fee is hereby granted,provided that the below copyright notice and historical background appear in all copies and that both the copyright notice and historical background and this permission notice appear in supporting documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining to distribution of the programs without specific prior written permission. Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. Copyright 2006 by BULL HN Information Systems Inc. Copyright 2006 by Bull SAS All Rights Reserved