1% BEGIN LICENSE BLOCK 2% Version: CMPL 1.1 3% 4% The contents of this file are subject to the Cisco-style Mozilla Public 5% License Version 1.1 (the "License"); you may not use this file except 6% in compliance with the License. You may obtain a copy of the License 7% at www.eclipse-clp.org/license. 8% 9% Software distributed under the License is distributed on an "AS IS" 10% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 11% the License for the specific language governing rights and limitations 12% under the License. 13% 14% The Original Code is The ECLiPSe Constraint Logic Programming System. 15% The Initial Developer of the Original Code is Cisco Systems, Inc. 16% Portions created by the Initial Developer are 17% Copyright (C) 2006 Cisco Systems, Inc. All Rights Reserved. 18% 19% Contributor(s): 20% 21% END LICENSE BLOCK 22 23:- comment(alias, "Operating System"). 24:- comment(summary, "Built-ins to access operating-system services"). 25:- comment(categories, ["Built-In Predicates","Interfacing"]). 26 27:- comment(alarm / 1, [ 28 summary:"The operating system will send the signal 14 to the ECLiPSe system Clock 29seconds after the command was entered. 30 31", 32 amode:(alarm(+) is det), 33 desc:html(" Used to send the signal 14 (SIGALRM) to the ECLiPSe system Clock seconds 34 after the alarm/1 command is entered. If there is already a pending 35 alarm, its clock is merely reset, i.e. there cannot be multiple alarm 36 requests. 37 38<P> 39 If Clock is 0, any pending alarm is cancelled. If Clock is negative, it 40 is nevertheless interpreted as an unsigned integer. 41 42<P> 43"), 44 args:["Clock" : "Integer"], 45 exceptions:[4 : "Clock is not instantiated.", 5 : "Clock is not an integer."], 46 eg:" 47Success: 48 [eclipse]: alarm(1). 49 yes. 50 [eclipse]: Signal 14 % 1 second later 51 52Error: 53 alarm(I). (Error 4). 54 alarm(2.0). (Error 5). 55 56 57 58", 59 see_also:[sleep / 1]]). 60 61:- comment(argc / 1, [ 62 summary:"Succeeds if Number is the number of arguments given on the command line to 63invoke ECLiPSe . 64 65", 66 amode:(argc(-) is det), 67 desc:html(" Used to find the number of arguments used when invoking ECLiPSe at the 68 operating system prompt, including eclipse itself. 69 70<P> 71"), 72 args:["Number" : "Variable or integer."], 73 exceptions:[5 : "Number is instantiated, but not to an integer."], 74 eg:" 75Success: 76 % eclipse -g 10000 77 [eclipse]: argc(N). 78 N = 3 79 yes. 80 81Fail: 82 % eclipse -g 10000 83 [eclipse]: argc(2). 84 no. 85 86Error: 87 argc('3'). (Error 5). 88 89 90 91", 92 see_also:[argv / 2]]). 93 94:- comment(argv / 2, [ 95 summary:"Succeeds if the Nth argument given on the command line when invoking 96ECLiPSe is the string Argument. 97 98", 99 amode:(argv(+,-) is det), 100 desc:html(" Used to find any argument used when invoking ECLiPSe at the operating 101 system prompt. The zero'th argument is the name of the eclipse binary. 102 When N is the atom all, then a list of all arguments is returned instead 103 of a single argument. When the command line contains the special 104 argument --, then all arguments before and including that one are 105 suppressed. 106 107<P> 108"), 109 args:["N" : "Integer or the atom all.", "Argument" : "String, List or variable."], 110 exceptions:[4 : "N is not instantiated.", 5 : "N is not an integer or an atom.", 6 : "N is an atom different from all.", 6 : "There was not N arguments when calling ECLiPSe ."], 111 eg:" 112Success: 113 % eclipse hello world 114 [eclipse]: argv(0,A0), argv(1,A1), argv(2,A2). 115 A0 = \"/usr/local/eclipse/bin/sun4/eclipse.exe\" 116 A1 = \"hello\" 117 A2 = \"world\" 118 yes. 119 [eclipse]: argv(all, [_A0|Args]). 120 Args = [\"hello\", \"world\"] 121 yes. 122 % eclipse -e \"argv(all,[_|A]),writeq(A),nl\" -- hello world 123 [\"hello\", \"world\"] 124Error: 125 argv(N,A). (Error 4). 126 argv(1.0,A). (Error 5). 127 argv(-1,A). (Error 6). 128 129 130 131", 132 see_also:[argc / 1]]). 133 134:- comment(cd / 1, [ 135 summary:"Directory is made the current working directory. Equivalent to 136set_flag(cwd, Directory). 137 138", 139 amode:(cd(+) is det), 140 desc:html(" Changes the current working directory to Directory. Directory may be an 141 absolute or relative pathname. 142 143<P> 144"), 145 args:["Directory" : "Atom or string of any form acceptable to the operating system."], 146 exceptions:[4 : "Directory is not instantiated.", 5 : "Directory is neither an atom nor a string.", 170 : "Directory doesn't exist."], 147 eg:" 148Success: 149 cd(workdir). 150 cd(\"workdir\"). 151 cd('/home/lp/user/workdir'). 152 cd('..'). 153 cd('../workdir'). 154 155Error: 156 cd(Dir). (Error 4). 157 cd(20). (Error 5). 158 cd('nonexist'). (Error 170). 159 160 161 162", 163 see_also:[getcwd / 1, set_flag / 2]]). 164 165:- comment(delete / 1, [ 166 summary:"The file File (with absolute or relative pathname) is deleted. 167 168", 169 amode:(delete(+) is det), 170 desc:html(" Used to delete the file or directory File. File may be an absolute or 171 relative filename. 172 173<P> 174"), 175 args:["File" : "An atom or a string of a form acceptable to the operating system."], 176 exceptions:[4 : "File is not instantiated.", 5 : "File is neither an atom nor a string.", 170 : "File does not exist."], 177 eg:" 178Success: 179 [eclipse]: sh('ls file.pl'). 180 file.pl 181 yes. 182 [eclipse]: delete('file.pl'). 183 yes. 184 [eclipse]: sh('ls file.pl'). 185 file.pl not found 186 yes. 187 188Error: 189 delete(File). (Error 4). 190 delete([file]). (Error 5). 191 delete(nofile). (Error 170). 192 193 194 195", 196 see_also:[sh / 1, system / 1, exists / 1, mkdir / 1]]). 197 198:- comment(getcwd / 1, [ 199 summary:"Unifies the current working directory with Cwd. 200 201", 202 amode:(getcwd(-) is det), 203 desc:html(" Cwd is unified with the current working directory including the final 204 \"/\". 205 206<P> 207 Equivalent to get_flag(cwd, Cwd). To set the current working directory, 208 use set_flag(cwd, Directory) or cd(Directory). 209 210<P> 211"), 212 args:["Cwd" : "String or Variable."], 213 exceptions:[5 : "Cwd is instantiated but not to a string."], 214 eg:" 215Success: 216 [eclipse]: sh(pwd). 217 /home/user/test 218 yes. 219 [eclipse]: getcwd(Cwd). 220 Cwd = \"/home/user/test/\" 221 yes. 222 223Fail: 224 getcwd(\"nodirectory\"). 225 226Error: 227 getcwd(1). (Error 5). 228 getcwd(atom). (Error 5). 229 230 231 232", 233 see_also:[cd / 1, get_flag / 2, set_flag / 2, mkdir / 1]]). 234 235:- comment(getenv / 2, [ 236 summary:"Succeeds if Name is the name of an environment variable or registry entry, and returns the corresponding value.", 237 amode:(getenv(+,-) is semidet), 238 index:[registry,'environment variables'], 239 desc:html("\ 240 The first argument must be a string or an atom. The predicate looks 241 up a value which the operating system has stored under this key. 242<P> 243 <B>UNIX</B>: If Name is the name of a UNIX environment variable, this 244 variable's value is returned. As an additional feature, if there 245 exists an environment variable whose name is the concatenation of 246 the value of Name and the ECLiPSe version number (e.g. 247 \"ECLIPSEDIR_4_9\" if Name is \"ECLIPSEDIR\" and the version 248 is 4.9), then this variable's value is returned instead. 249<P> 250 <B>WINDOWS</B>: The name Name is looked up in the registry under the key 251 HKEY_LOCAL_MACHINE\\SOFTWARE\\IC-Parc\\ECLiPSe\\<version>. If there is 252 such an entry, its value is returned. Otherwise, Name is taken as 253 the name of an environment variable, whose value is returned if it 254 exists. 255<P> 256 If the lookup operation is unsuccessful, the predicate fails. 257"), 258 args:["Name" : "String or atom.", "Value" : "String or variable."], 259 fail_if:"Fails if none of the lookup methods yielded any result for the given name", 260 exceptions:[4 : "Name is not instantiated.", 5 : "Name is instantiated, but not to a string or an atom.", 5 : "Value is instantiated, but not to a string."], 261 eg:" 262Success: 263 getenv('HOME',V). (gives V=\"/home/username\"). 264 getenv(\"SHELL\",V). (gives V=\"/bin/csh\"). 265 getenv('TERM',V). (gives V=\"sun-cmd\"). 266 getenv('USER',V). (gives V=\"username\"). 267 268Fail: 269 getenv('HOEM',V). 270 271Error: 272 getenv(TERM,V). (Error 4). 273 getenv('TERM',atom). (Error 5). 274 getenv(1,V). (Error 5). 275 276 277 278", 279 see_also:[setenv/2, sh / 1, argv / 2, argc / 1]]). 280 281:- comment(setenv / 2, [ 282 summary:"Sets the environment variable Name to the given value", 283 amode:(setenv(+,+) is det), 284 index:['environment variables'], 285 desc:html("\ 286 The first argument must be a string or an atom and is taken as the 287 name of an operating system environment variable. The value of this 288 environment variable is set, or changed to, the new value Value. 289<P> 290 When Value is an atom or number, it is first converted to a string, 291 and the environment variable is set to the resulting string value. 292<P> 293 The mechanism can be used to pass information from an eclipse-process 294 to its sub-processes. Note however, that due to operating system 295 limitations, environment strings cannot contain null characters 296 (unlike ECLiPSe strings). Also, the strings used as arguments to 297 setenv/2 cannot be garbage collected and will accumulate. 298<P> 299 Operating system dependencies: Because of portability issues, on UNIX 300 there is currently no facility to unset an environment variable 301 completely, but it can set to an empty string. On Windows on the other 302 hand, an environment variable's value cannot be the empty string: 303 setting an environment variable to the empty string makes it 304 indistinguishable from an unset or nonexisting one. 305"), 306 args:["Name" : "String or atom.", 307 "Value" : "String, atom or number."], 308 exceptions:[4 : "Name or Value is not instantiated.", 309 5 : "Name is instantiated, but not to a string or an atom.", 310 5 : "Value is instantiated, but not to a string, atom or number.", 311 170 : "The environment could not be changed"], 312 eg:" 313 ?- setenv(abc, hello), getenv(abc, X). 314 X = \"hello\" 315 Yes (0.00s cpu) 316 317 ?- setenv(\"abc\", \"world\"), getenv(abc, X). 318 X = \"world\" 319 Yes (0.00s cpu) 320 321 ?- setenv(abc, 999), getenv(abc, X). 322 X = \"999\" 323 Yes (0.00s cpu) 324 325 ?- setenv(abc, data), sh(\"echo $abc\"). 326 data 327 Yes (0.00s cpu) 328 329 ?- setenv(abc, data), exec([sh,\"-c\",\"echo $abc\"], []). 330 data 331 Yes (0.00s cpu) 332 333 ?- setenv(abc, data), exec([eclipse,\"-e\",\"getenv(abc,X),writeln(X)\"], []). 334 data 335 Yes (0.00s cpu) 336 337 ?- setenv(abc, \"\"), getenv(abc, X). % on UNIX 338 X = \"\" 339 Yes (0.00s cpu) 340 341 ?- setenv(abc, \"\"), getenv(abc, X). % on Windows 342 No (0.00s cpu) 343", 344 see_also:[exec/2, exec/3, getenv/2, sh/1]]). 345 346:- comment(pause / 0, [ 347 summary:"The ECLiPSe session is suspended (the same as Control-Z at the top-level 348loop). 349 350", 351 amode:(pause is det), 352 desc:html(" Used to suspend the ECLiPSe session. 353 354<P> 355"), 356 args:[], 357 eg:" 358Success: 359 [eclipse]: [user]. 360 w(X) :- write(X). 361 user compiled 92 bytes in 0.02 seconds 362 yes. 363 [eclipse]: w(bird). 364 bird 365 yes. 366 [eclipse]: pause. 367 Stopped (signal) 368 % fg % foreground command 369 eclipse 370 yes. 371 [eclipse]: w(duck). 372 duck 373 yes. 374 [eclipse]: ^D 375 bye 376 % eclipse 377 [eclipse]: w(cow). 378 calling an undefined procedure 379 380 381 382", 383 see_also:[halt / 0]]). 384 385:- comment(rename / 2, [ 386 summary:"Renames the file OldName to NewName. 387 388", 389 amode:(rename(+,+) is det), 390 desc:html(" OldName and NewName are absolute or relative pathnames of files. Used 391 to rename the file OldName with the name NewName. 392 393<P> 394"), 395 args:["OldName" : "String or atom.", "NewName" : "String or atom."], 396 exceptions:[4 : "Either OldName or NewName are not instantiated.", 5 : "Either OldName or NewName are neither a string nor an atom.", 190 : "File OldName does not exist."], 397 eg:" 398Success: 399 [eclipse]: sh('ls file1'). 400 file1 401 [eclipse]: rename(file1, file2). 402 yes. 403 [eclipse]: sh('ls file1 file2'). 404 file1 not found 405 file2 406 yes. 407 408Error: 409 rename(Old, any). (Error 4). 410 rename(any, New). (Error 4). 411 rename(1, any). (Error 5). 412 rename(notfile, newfile). (Error 190). 413 414 415 416", 417 see_also:[exists / 1, delete / 1, mkdir / 1]]). 418 419:- comment(sleep / 1, [ 420 summary:"The execution of ECLiPSe is suspended for Seconds number of seconds. 421 422", 423 amode:(sleep(+) is det), 424 desc:html(" sleep/1 causes the the suspension of execution of ECLiPSe for Seconds 425 number of seconds. 426 427<P> 428 However, ECLiPSe will respond to interrupts while asleep. On most 429 operating systems, interrupts will terminate the sleep prematurely. 430 431<P> 432"), 433 args:["Seconds" : "Positive number (integer or float)."], 434 exceptions:[4 : "Seconds is uninstantiated.", 5 : "Seconds is not an integer or float."], 435 eg:" 436Success: 437 [eclipse]: sleep(0.3). 438 % short sleep 439 yes. % \"yes\" appears after 0.3 seconds. 440 441 [eclipse]: sleep(63072000). 442 % long sleep 443 yes. % \"yes\" appears after 2 years. 444 445 446 447", 448 see_also:[alarm / 1, pause / 0]]). 449 450:- comment(canonical_path_name / 2, [ 451 summary: "Expand a path name into the full `canonical' form.", 452 amode:(canonical_path_name(+,-) is det), 453 args: ["Path": "A pathname (atom or string)", 454 "CanonicalPath": "Canonical pathname for Path" 455 ], 456 desc: html("\ 457 This predicate expands a given pathname, and converts it into the 458 `canonical' form of the pathname. The following are done to the path: 459 460<UL> 461 <LI> An absolute path is returned. If a relative path is supplied, the 462 path is prefixed with the current working directory. On Windows, a 463 drive name is prefixed, if necessary. 464 465 <LI> Leading '~' and environment variables (such as '$HOME') are 466 substituted by the appropriate value. If this substitution is not 467 possible (e.g. if the environment variable does not exist), nothing 468 is changed. 469 470 <LI> Special sequences such as '.', '..', extra '/' are appropriately 471 removed/replaced. 472 473 <LI> The non-aliased path is returned, i.e. any symbolic links are 474 replaced by the non-symbolic linked version of the path. 475 476 <LI> On Windows and Mac OS X, where different cases of letters in 477 path names are allowed but ignored (so e.g. \"foo\" and \"Foo\" are 478 aliases), the `normalised' version of the name, using the letter 479 cases when each file/directory was created, is returned 480 (not supported in older versions of Windows before 2000). 481 482 <LI> If the path denotes an existing directory, the canonical path 483 is terminated with a '/'. 484</UL> 485 486<P> 487 Not all components of Path need to exist. The removal of aliasing 488 is performed only on the part of the path that does exist. 489 490<P> 491 The type of the returned CanonicalPath is the same as the type of 492 Path (string or atom). If Path is empty, it is replaced by the 493 current working directory. 494 495<P> 496 The predicates canonical_path_name/2 and existing_file/4 are intended 497 as replacement for absolute_file_name/2 in previous releases. The 498 functionality of completing an incomplete name and returning an 499 absolute path of absolute_file_name/2 has been separated. The following 500 approximately implements the old absolute_file_name/2: 501 502<PRE> 503 absolute_file_name(Rel, Abs) :- 504 (Rel == user -> 505 Abs == user % treat user specially 506 ; get_flag(prolog_suffix, Sufs), 507 (existing_file(Rel, Sufs, [], ExtRel) -> true ; ExtRel = Rel), 508 canonical_path_name(ExtRel, Abs) 509 ). 510</PRE> 511 512 513"), 514 see_also: [existing_file/4, os_file_name/2, pathname/4], 515 eg:"\ 516 [eclipse]: canonical_path_name(\"file\", Full). %cwd is /homes/tom 517 Full = \"/homes/tom/file\" 518 yes 519 520 [eclipse]: canonical_path_name(file, Full). 521 Full = '/homes/tom/file' 522 yes 523 524 [eclipse]: canonical_path_name(\"~/file\", Full). 525 Full = \"/homes/tom/file\" 526 yes 527 528 [eclipse]: canonical_path_name('file/..', Full). 529 Full = '/homes/tom/' 530 531 [eclipse]: canonical_path_name('/users/tom', Full). 532 % /users/tom is a symbolic link for /homes/tom 533 Full = '/homes/tom/' 534", 535 exceptions: [5: "Path is not a string or atom."] 536]). 537 538:- comment(existing_file/4, [ 539 amode:(existing_file(++,++,++,-) is nondet), 540 args: ["Base": "The start of a file or path name (atom or string, possibly with a library/1 wrapper)", 541 "Completions": "Possible completions for Base (list of atomic elements)", 542 "Permissions": "Permissions (list of readable,writable,executable)", 543 "MatchedFile": "An existing file that matches the specification." 544 ], 545 summary: "Finds any existing file subject to the specified conditions.", 546 fail_if: "MatchedFile cannot be found.", 547 resat: "Succeeds once for every matching file", 548 exceptions: [5: "Base, Completions, Permissions not of right type.", 549 6: "Base is an empty atom or string." 550 ], 551 see_also: [canonical_path_name/2, get_flag/2, os_file_name/2, pathname/4], 552 eg: " 553Success: 554 555 % Trying different file extensions, including the empty one: 556 ?- existing_file(\"hello\", [\".ecl\",\".txt\",\"\"], [], File). 557 File = \"hello.txt\" More? (;) 558 No (0.00s cpu) % assuming hello.ecl and hello do not exist 559 560 % Looking for one of several files in the parent directory: 561 ?- existing_file(\"../\", [\"a.txt\",\"b.txt\",\"c.txt\"], [readable], File). 562 File = \"../a.txt\" More? (;) 563 File = \"../c.txt\" More? (;) 564 No (0.00s cpu) % assuming b.txt does not exist or is not readable 565 566 % Looking for a precompiled library: 567 ?- existing_file(library(fd), [\".eco\"], [readable], File). 568 File = '/homes/ks15/Eclipse/lib/fd.eco' More? (;) 569 No (0.00s cpu) 570 571 % Looking for source files: 572 ?- get_flag(prolog_suffix, Exts), 573 existing_file(\"hello\", Exts, [readable], File). 574 File = \"hello.ecl\" More? (;) 575 No (0.00s cpu) 576 577 % Looking for different file names: 578 [eclipse 1]: existing_file(test, [1,2,3], [], File). 579 File = test1 More? (;) 580 File = test3 More? (;) 581 No (0.00s cpu) 582 583Failure: 584 585 [eclipse 1]: existing_file(library(fd), [], [readable], File). 586 % no Completions at all; will always fail 587 588 [eclipse 1]: existing_file(library(fd), [\"\"], [readable], File). 589 % no library file with just 'fd' as the name (file has a suffix) 590", 591 592 desc: html("\ 593 This predicate will search for any existing files that match the 594 specifications given in the first three arguments: the file starts with 595 Base, which is an absolute or relative partial file name. Possible 596 completions (usually file extensions) given in Completions are appended 597 to Base, in the order they are given, to give a complete name. 598 If a proper file (i.e. non-directory) with this name exists, the 599 ECLiPSe process's permission for this file are checked against the 600 Permissions list (readable, writable, executable). If the 601 permissions match, then the filename is returned in MatchedFile. 602 603<P> 604 Base may have a library/1 wrapper around the name. If this is 605 used, the file is searched for in the directories specified in 606 library path (including any subdirectory with the same name as 607 given in the library/1 wrapper, i.e. we check for both lib/foo.eco 608 and lib/foo/foo.eco). The search order is the order in which the 609 library directories appear in the library_path flag of get_flag/2, 610 and for each directory, the completions are tried in the order in 611 which they appear in the list Completions. 612 613 All matching files are returned via backtracking. If only the 614 first one is required, use once/1. 615 616<P> 617 MatchedFile is the same type as Base (atom or string). Also, if 618 Base is a relative (absolute) pathname, then so is MatchedFile. 619 If Base starts with '~' or enviroment variables (specified with a 620 leading '$'), these are substituted. If the library(...) wrapper 621 is used, the proper library path is substituted. 622 623 Note that the executable permission for Windows may be approximate, 624 because Windows (especially Vista) has a different system for 625 dealing with execute permission. 626 627<P> 628 The predicates canonical_path_name/2 and existing_file/4 are intended 629 as replacement for absolute_file_name/2 in previous releases. The 630 functionality of completing an incomplete name and returning an 631 absolute path of absolute_file_name/2 has been separated. The following 632 approximately implements the old absolute_file_name/2: 633 634<PRE> 635 absolute_file_name(Rel, Abs) :- 636 (Rel == user -> 637 Abs == user 638 ; get_flag(prolog_suffix, Sufs), 639 (existing_file(Rel, Sufs, [], ExtRel) -> true ; ExtRel = Rel), 640 canonical_path_name(ExtRel, Abs) 641 ). 642</PRE> 643 644")]). 645 646:- comment(errno_id / 1, [ 647 summary:"Message is bound to the message string that corresponds to most recent 648operating system error that occurred during the execution. 649 650", 651 amode:(errno_id(-) is det), 652 desc:html(" This predicate unifies Message with the string that corresponds to the 653 most recent operating system error that occurred during the execution. 654 These messages differ between different operating systems. 655 Operating system interface errors which occur within built-in predicates 656 are normally indicated by the predicate raising event 170 657 \"system interface error\". The event handler then retrieves the 658 error message using errno_id/1. The system remembers the last error 659 message until a new error occurs. 660 661<P> 662"), 663 args:["Message" : "Variable."], 664 exceptions:[5 : "Message is neither variable nor string."], 665 eg:" 666[eclipse 3]: delete(nofile). 667system interface error: No such file or directory in delete(nofile) 668 669[eclipse 4]: errno_id(Msg). 670Msg = \"No such file or directory\" 671yes. 672 673 674 675", 676 see_also:[set_event_handler / 2]]). 677 678:- comment(mkdir / 1, [ 679 summary:"Create a directory/folder with the given name. 680 681", 682 amode:(mkdir(+) is det), 683 desc:html(" Used to create directories (folders) in the filesystem. 684 Path may be an absolute or relative name. 685 686<P> 687"), 688 args:["Path" : "An atom or a string."], 689 exceptions:[4 : "Path is not instantiated.", 5 : "Path is neither an atom nor a string."], 690 eg:" 691 [eclipse 1]: mkdir(tmpdir). 692 693 yes. 694 [eclipse 1]: mkdir(tmpdir). 695 system interface error: File exists in mkdir(tmpdir) 696 697 698 699", 700 see_also:[sh / 1, system / 1, exists / 1, delete / 1]]). 701 702:- comment(os_file_name / 2, [ 703 summary:"Conversion between internal ECLiPSe file name and Operating 704System file name syntax. 705 706", 707 amode:(os_file_name(+,-) is det), 708 amode:(os_file_name(-,+) is det), 709 desc:html(" This predicate converts between internal (ECLiPSe) and external 710 (operating system) file names. It works in both directions. 711 712<P> 713 714 715<P> 716"), 717 args:["InternalName" : "String, atom or variable.", "ExternalName" : "String, atom or variable."], 718 exceptions:[4 : "Neither InternalName nor ExternalName are instantiated.", 5 : "InternalName or ExternalName are instantiated to something other than string or atom.", 5 : "InternalName or ExternalName are instantiated to different types."], 719 eg:" 720Success: 721 On UNIX: 722 [eclipse]: os_file_name(\"//a/b/c.def\", OS). 723 OS = \"//a/b/c.def\" 724 yes 725 726 On Windows: 727 [eclipse]: os_file_name(\"//a/b/c.def\", OS), write(OS). 728 a:\\b\\c.def 729 OS = \"a:\\\\b\\\\c.def\" 730 yes 731 732 [eclipse]: os_file_name(File, \"a:\\\\b\\\\c.def\"). 733 File = \"//a/b/c.def\" 734 yes 735 736Error: 737 os_file_name(X, Y). (Error 4). 738 os_file_name(4, X). (Error 5). 739 os_file_name(\"/home/file\", '/home/file'). (Error 5). 740 741 742 743", 744 see_also:[existing_file / 4, pathname / 4]]). 745 746:- comment(cputime / 1, [ 747 summary:"Succeeds if Time is the elapsed user cpu time in seconds. 748 749", 750 amode:(cputime(-) is det), 751 desc:html(" Used to find the elapsed user cpu time in seconds, it is equivalent to 752 statistics(times, [Time|_]). 753 754<P> 755 The cpu time is the `user' time i.e. the CPU time used while executing 756 instructions in the user space of the calling process. 757 758<P> 759 Note that the granularity of the system clock is usually 1/60 or 1/50 of 760 a second. Hence if you use cputime/1 to measure runtimes make sure that 761 the measured intervals are long enough. 762 763<P> 764 The time given by the ps command gives the sum of `user' time and 765 `system' time, which is the CPU time used by the system on behalf of the 766 calling process. 767 768<P> 769 Note that (like all predicates that return a number as their last 770 argument), this predicate can be used as a function inside arithmetic 771 expressions. 772"), 773 args:["Time" : "Float number or variable."], 774 exceptions:[5 : "Time is instantiated, but not to a float."], 775 eg:" 776Success: 777 [eclipse]: cputime(T). 778 T = 0.0333333 779 yes. 780 781Fail: 782 cputime(0.000001). 783Error: 784 cputime(2). (Error 5). 785 786 787 788", 789 see_also:[statistics / 0, statistics / 2, date / 1, get_flag / 2]]). 790 791:- comment(date / 1, [ 792 summary:"Date is bound to the string giving the date and time. 793 794", 795 amode:(date(-) is det), 796 desc:html(" Unifies Date with the current date and time. 797 798<P> 799"), 800 args:["Date" : "Variable or string."], 801 exceptions:[5 : "Date is instantiated, but not to a string."], 802 eg:" 803Success: 804 [eclipse]: date(Date). 805 Date = \"Fri Aug 25 12:00:00 1989\\n\" 806 yes. 807 808Fail: 809 date(\"Fri Aug 24 12:00:00 1989\\n\"). 810 811Error: 812 date(thursday). (Error 5). 813 814 815 816", 817 see_also:[get_flag/2, local_time/8, local_time_string/3, library(calendar)]]). 818 819:- comment(exec / 2, [ 820 summary:"A child process Command is forked, its standard streams are connected to 821Streams and the ECLiPSe process waits until it terminates. 822 823", 824 amode:(exec(++,++) is det), 825 desc:html(" This predicate is used to fork a child process and to set up pipes to 826 its standard streams. After the process is forked, ECLiPSe blocks, i.e. 827 it waits until the child process terminates. 828 829<P> 830 Command should be a list with at least one element: The first list element 831 (a path name in ECLiPSe path name syntax, atom or string) specifies the 832 program to be executed, and the subsequent list elements are its arguments. 833 The arguments can be atoms, strings or numbers. They are passed to the 834 executed program literally (in particular, no path name syntax conversion 835 is applied). 836 837<P> 838 For backward compatibility, Command can be a simple atom or string, in 839 which case the first word in Command specifies the program to be executed, 840 and the following words are its command-line arguments. 841 This form is deprecated since it creates problems with argument quoting 842 and operating system dependent path name syntax. 843 844<P> 845 By specifying the Streams argument it is possible to control which of 846 the process' standard streams are connected to ECLiPSe streams. The 847 form of Streams is [Stdin, Stdout, Stderr]. If some of these streams 848 are specified and not null, a pipe is opened which connects the standard 849 stream of the child process with the specified ECLiPSe stream, e.g. 850 Stdin must be an output stream because it is connected to the standard 851 input of the child process. If the list Streams is shorter, only the 852 specified streams are connected with a pipe. The streams can be 853 specified like for open/3. If the stream is a variable, it is bound to 854 the physical stream number, if it is an atom different from null, that 855 symbolic stream is used. Specifying a null stream means that no pipe is 856 set up for this stream. 857 858<P> 859 Each stream can also be specified as sigio(Stream) (UNIX systems only). 860 In this case a pipe is set up to the stream Stream and in addition the 861 pipe is instructed to send the signal io each time new data appears in 862 it. In this way the two processes can communicate in a truly 863 asynchronous way. When one process sends data to the other one, the 864 interrupt handler is invoked and it can read and process the data. When 865 it finishes, it can continue where it was interrupted. 866 867<P> 868 exec(Command, Streams) is equivalent to 869 870<P> 871 exec(Command, Streams, Pid), wait(Pid, _) 872 873<P> 874 exec(Command, []) is very similar to system(Command). 875 876<P> 877"), 878 args:["Command" : "String, atom or list of atomic terms.", "Streams" : "List of stream ids."], 879 exceptions:[4 : "Command is not instantiated.", 5 : "Command is instantiated, but not to a string or an atom.", 5 : "Streams is instantiated, but not to a list.", 5 : "A stream in Streams is instantiated, but not to an atom.", 170 : "System error, it was not possible to fork the child or the exec system call in the child failed.", 192 : "The specified stream is not open in the appropriate mode."], 880 eg:" 881Success: 882 % exec/2 wait for the child process 883 [eclipse]: exec(ls, []), write(end_exec). 884 aux.o coroutine.pl kegi.pl sepia.o 885 bsi.pl cprolog.pl lint.pl sorts.pl 886 cio.pl history.pl lists.pl strings.pl 887 cn.pl k_env.pl quintus.pl t_all.pl 888 end_exec 889 yes. 890 891 % exec/3 return immediately 892 [eclipse]: exec(ls, [], Pid), write(end_exec). 893 end_exec 894 Pid = 16054 895 yes. 896 [eclipse]: aux.o coroutine.pl kegi.pl sepia.o 897 bsi.pl cprolog.pl lint.pl sorts.pl 898 cio.pl history.pl lists.pl strings.pl 899 cn.pl k_env.pl quintus.pl t_all.pl 900 901Error: 902 exec(S, [output]). (Error 4). 903 exec(ls, null). (Error 5). 904 exec(chipc, [f(output)]). (Error 5). 905 exec(date, [input]). (Error 192). 906", 907 see_also:[call_c / 2, exec / 3, exec_group / 3, setenv/2, wait / 2, kill / 2, sh / 1, system / 1, open / 3]]). 908 909:- comment(exec / 3, [ 910 summary:"A child process Command is forked, its standard streams are connected to 911Streams and its process ID is Pid. 912 913", 914 amode:(exec(++,++,-) is det), 915 desc:html(" This predicate is used to fork a child process and to set up pipes 916 to its standard streams. After the process is forked, ECLiPSe 917 continues normally, without waiting for the child to terminate. 918 919<P> 920 Command should be a list with at least one element: The first list element 921 (a path name in ECLiPSe path name syntax, atom or string) specifies the 922 program to be executed, and the subsequent list elements are its arguments. 923 The arguments can be atoms, strings or numbers. They are passed to the 924 executed program literally (in particular, no path name syntax conversion 925 is applied). 926 927<P> 928 For backward compatibility, Command can be a simple atom or string, in 929 which case the first word in Command specifies the program to be executed, 930 and the following words (separated by blank space) are its command-line 931 arguments. This form is deprecated since it creates problems with argument 932 quoting and operating system dependent path name syntax. 933 934<P> 935 By specifying the Streams argument it is possible to control which of 936 the process' standard streams are connected to ECLiPSe streams. The 937 form of Streams is [Stdin, Stdout, Stderr]. If some of these streams 938 are specified and not null, a pipe is opened which connects the standard 939 stream of the child process with the specified ECLiPSe stream, e.g. 940 Stdin must be an output stream because it is connected to the standard 941 input of the child process. If the list Streams is shorter, only the 942 specified streams are connected with a pipe. The streams can be 943 specified like for open/3. If the stream is a variable, it is bound to 944 the physical stream number, if it is an atom different from null, that 945 symbolic stream is used. Specifying a null stream means that no pipe is 946 set up for this stream. 947 948<P> 949 Each stream can also be specified as sigio(Stream) (UNIX systems only). 950 In this case a pipe is set up to the stream Stream and in addition the 951 pipe is instructed to send the signal io each time new data appears in 952 it. In this way the two processes can communicate in a truly 953 asynchronous way. When one process sends data to the other one, the 954 interrupt handler is invoked and it can read and process the data. When 955 it finishes, it can continue where it was interrupted. 956 957<P> 958 After forking the process, Pid is unified with its process ID, which can 959 be used e.g. in wait/2 or kill/2. If the exec system call in the child 960 process failed, the child exits with status 128 + errno (Unix). 961 962<P> 963"), 964 args:["Command" : "String, atom or list of atomic terms.", "Streams" : "List of stream ids.", "Pid" : "Integer or a variable."], 965 exceptions:[4 : "Command is not instantiated.", 5 : "Command is instantiated, but not to a string or an atom.",5 : "Streams is instantiated, but not to a list.", 5 : "A stream in Streams is instantiated, but not to an atom or a sigio structure.", 5 : "Pid is instantiated.", 170 : "System error, it was not possible to fork the child.", 192 : "The specified stream is not open in the appropriate mode."], 966 eg:" 967% execute an ls-command 968 969 ?- exec([ls,\"-C\"], [null, out], Pid). 970 Pid = 10885 971 yes. 972 973 ?- read_string(out, end_of_file, _, S), write(S). 974 aux.o coroutine.pl kegi.pl sepia.o 975 bsi.pl cprolog.pl lint.pl sorts.pl 976 cio.pl history.pl lists.pl strings.pl 977 cn.pl k_env.pl quintus.pl t_all.pl 978 979 S = \"...\" 980 981 ?- close(out), wait(Pid, S). 982 Pid = 10885 983 S = 0 984 yes. 985 986 987% execute another eclipse 988 989 ?- argv(0,Ecl), % get name of the eclipse executable 990 exec([Ecl,\"-e\",\"read(X),Y is X*X,printf('%w. %b',[Y])\"], [in,out], P). 991 992 E = \"/usr/local/eclipse/bin/sparc_sunos5/eclipse.exe\" 993 P = 10741 994 yes. 995 996 [eclipse 2]: printf(in, '%w. %b', [12]), read(out, Result). 997 Result = 144 998 yes. 999 1000 [eclipse 3]: close(in), close(out), wait(10741, S). 1001 S = 0 1002 yes. 1003 1004 1005Error: 1006 exec(S, [], Pid). (Error 4). 1007 exec([ls], null, Pid). (Error 5). 1008 exec([chipc], [1], P). (Error 5). 1009 exec([date], [input], P). (Error 192). 1010", 1011 see_also:[exec / 2, exec_group / 3, setenv/2, wait / 2, kill / 2, sh / 1, system / 1, open / 3]]). 1012 1013:- comment(exec_group / 3, [ 1014 summary:"A child process Command is forked in a new process group, its standard 1015streams are connected to Streams and its process ID is Pid. 1016 1017", 1018 amode:(exec_group(++,++,-) is det), 1019 desc:html("\ 1020 UNIX: This predicate is used to fork a child process in its own 1021 process group and to set up pipes to its standard streams. After 1022 the process is forked, ECLiPSe continues normally, without waiting 1023 for the child to terminate. 1024 1025<P> 1026 Command should be a list with at least one element: The first list element 1027 (a path name in ECLiPSe path name syntax, atom or string) specifies the 1028 program to be executed, and the subsequent list elements are its arguments. 1029 The arguments can be atoms, strings or numbers. They are passed to the 1030 executed program literally (in particular, no path name syntax conversion 1031 is applied). 1032 1033<P> 1034 For backward compatibility, Command can be a simple atom or string, in 1035 which case the first word in Command specifies the program to be executed, 1036 and the following words are its command-line arguments. 1037 This form is deprecated since it creates problems with argument quoting 1038 and operating system dependent path name syntax. 1039 1040<P> 1041 By specifying the Streams argument it is possible to control which of 1042 the process' standard streams are connected to ECLiPSe streams. The 1043 form of Streams is [Stdin, Stdout, Stderr]. If some of these streams 1044 are specified and not null, a pipe is opened which connects the standard 1045 stream of the child process with the specified ECLiPSe stream, e.g. 1046 Stdin must be an output stream because it is connected to the standard 1047 input of the child process. If the list Streams is shorter, only the 1048 specified streams are connected with a pipe. The streams can be 1049 specified like for open/3. If the stream is a variable, it is bound to 1050 the physical stream number, if it is an atom different from null, that 1051 symbolic stream is used. Specifying a null stream means that no pipe is 1052 set up for this stream. 1053 1054<P> 1055 Each stream can also be specified as sigio(Stream) (UNIX systems only). 1056 In this case a pipe is set up to the stream Stream and in addition the 1057 pipe is instructed to send the signal io each time new data appears in 1058 it. In this way the two processes can communicate in a truly 1059 asynchronous way. When one process sends data to the other one, the 1060 interrupt handler is invoked and it can read and process the data. When 1061 it finishes, it can continue where it was interrupted. 1062 1063<P> 1064 After forking the process, Pid is unified with its process ID, which can 1065 be used e.g. in wait/2 or kill/2. If the exec system call in the child 1066 process failed, the child exits with status 128 + errno. 1067 1068<P> 1069 As oppsed to exec/3, the child process is created in a new process group 1070 (UNIX), and as a consequence does not get the interrupt, hangup and kill 1071 signals sent to the parent. This feature might be needed if e.g. a 1072 separate ECLiPSe process is forked which should not be influenced when 1073 the user types Ctrl-C to the main ECLiPSe process. 1074"), 1075 args:["Command" : "String, atom or list of atomic terms.", "Streams" : "List of stream ids.", "Pid" : "Integer or a variable."], 1076 exceptions:[4 : "Command is not instantiated.", 5 : "Command is instantiated, but not to a string or an atom.", 5 : "Streams is instantiated, but not to a list.", 5 : "A stream in Streams is instantiated, but not to an atom or a sigio structure.", 5 : "Pid is instantiated, but not to an integer.", 170 : "System error, it was not possible to fork the child.", 192 : "The specified stream is not open in the appropriate mode."], 1077 eg:" 1078Success: 1079 % the child process does not get the signal if ^C is typed 1080 [eclipse]: exec_group(eclipse, [output], Pid). 1081 1082 Pid = 11459 1083 yes. 1084 [eclipse]: 1085 ECLiPSe Constraint Logic Programming System [kernel] 1086 Kernel and basic libraries copyright Cisco Technology Inc 1087 Academic licensing through Imperial College London, see legal/licence_acad.txt 1088 GMP library copyright Free Software Foundation, see legal/lgpl.txt 1089 For other libraries see their individual copyright notices 1090 Version 5.8 #72, Fri Nov 26 00:12 2004 1091 [eclipse]: ^C 1092 interruption: type a, b, c, e, or h for help : ? 1093 1094 % when exec/3 is used, both processes get the signal 1095 [eclipse]: exec(eclipse, [output], Pid). 1096 1097 Pid = 11440 1098 yes. 1099 [eclipse]: 1100 ECLiPSe Constraint Logic Programming System [kernel] 1101 Kernel and basic libraries copyright Cisco Technology Inc 1102 Academic licensing through Imperial College London, see legal/licence_acad.txt 1103 GMP library copyright Free Software Foundation, see legal/lgpl.txt 1104 For other libraries see their individual copyright notices 1105 Version 5.8 #72, Fri Nov 26 00:12 2004 1106 [eclipse]: ^C 1107 1108 interruption: type a, b, c, e, or h for help : ? 1109 interruption: type a, b, c, e, or h for help : ? 1110Error: 1111 exec_group(S, [], Pid). (Error 4). 1112 exec_group(ls, null, Pid). (Error 5). 1113 exec_group(chipc, [1], P). (Error 5). 1114 exec_group(date, [input], P). (Error 192). 1115 1116 1117 1118", 1119 see_also:[exec / 2, exec / 3, setenv/2, kill / 2, sh / 1, system / 1, open / 3, wait / 2]]). 1120 1121:- comment(exists / 1, [ 1122 summary:"Succeeds if the file File (with absolute or relative pathname) exists. 1123File can be a directory. 1124 1125", 1126 amode:(exists(+) is semidet), 1127 desc:html(" Used to see if the file File exists. File can be a directory. 1128 exists(File) is equivalent to get_file_info(File, mode, _). 1129 1130<P> 1131"), 1132 args:["File" : "Atom or string."], 1133 fail_if:"Fails if the file File (with absolute or relative pathname) does not exist", 1134 exceptions:[4 : "File is not instantiated.", 5 : "File is neither an atom nor a string."], 1135 eg:" 1136Success: 1137 [eclipse]: sh('ls myfile'). 1138 myfile 1139 [eclipse]: exists(myfile). 1140 yes. 1141 1142 [eclipse]: sh('ls /home/user/workdir'). 1143 myfile 1144 [eclipse]: exists('/home/user/workdir'). 1145 yes. 1146 1147Fail: 1148 [eclipse]: sh('ls nofile'). 1149 nofile not found 1150 [eclipse]: exists(nofile). 1151 no. 1152 1153Error: 1154 exists(File). (Error 4). 1155 exists([file]). (Error 5). 1156 1157 1158 1159", 1160 see_also:[existing_file/4, get_file_info / 3, sh / 1, system / 1, delete / 1, mkdir / 1]]). 1161 1162:- comment(exit / 1, [ 1163 summary:"The Prolog session is ended and the specified status returned to the 1164operating system. 1165 1166", 1167 amode:(exit(+) is erroneous), 1168 desc:html(" Used to exit from the Prolog session. If user_end/0 is defined and 1169 global, it is called. All buffers are flushed, streams are closed and 1170 ECLiPSe exits. The specified status code is returned to the operating 1171 system. exit(0) is identical with halt. 1172 1173<P> 1174"), 1175 args:["Status" : "Integer"], 1176 exceptions:[4 : "Status is not instantiated.", 5 : "Status is instantiated to a non-integer."], 1177 eg:" 1178Success: 1179 [eclipse]: exit(5). 1180 csh% echo $status 1181 5 1182 csh% 1183 1184 1185 1186", 1187 see_also:[halt / 0, break / 0, pause / 0]]). 1188 1189:- comment(get_file_info / 3, [ 1190 summary:"Succeeds if the file File (with absolute or relative pathname) exists and 1191the value of its attribute Attr unfies with Value. 1192 1193", 1194 amode:(get_file_info(+,-,-) is nondet), 1195 amode:(get_file_info(+,+,-) is semidet), 1196 desc:html("\ 1197 This predicate is used to test the properties of a specified file. 1198 If Attr specifies one of the attributes listed below, then Value is 1199 unified with the attribute value on return. 1200 If Attr is a variable, the predicate on backtracking returns all 1201 attribute-value pairs that are relevant for the given file. 1202<P> 1203 The possible attributes and their meanings are: 1204<P> 1205<PRE> 1206 Attribute Type Meaning 1207 --------------------------------------------------------- 1208 mode integer file mode (see table below) 1209 size integer file size in bytes 1210 type atom file type: file,directory,link,socket, 1211 fifo,char_device or block_device 1212 1213 device integer device number 1214 inode integer inode number (Unix) 1215 nlink integer number of links (Unix) 1216 uid integer user ID of the owner (Unix) 1217 uname string user name of the owner (Unix) 1218 gid integer group ID of the owner (Unix) 1219 gname string group name of the owner (Unix) 1220 1221 atime integer time of last access 1222 mtime integer time of last data modification 1223 ctime integer time of last status change 1224 adate string date of last access (text) 1225 mdate string date of last data modification (text) 1226 cdate string date of last status change (text) 1227 1228 readable on/off file is/isn't readable by this process 1229 writable on/off file is/isn't writable by this process 1230 executable on/off file is/isn't executable by this process 1231</PRE> 1232 The *name attributes are string representation of the corresponding *id 1233 attributes. The *date attributes are string representation of the 1234 corresponding *time attributes. The time for the *time attributes is 1235 measured as seconds elapsed since 00:00:00 GMT, Jan 1, 1970. 1236<P> 1237 The flags readable, writable and executable indicate whether the running 1238 ECLiPSe process has the corresponding permissions on the file. Note that 1239 the executable permission for Windows may be approximate, because Windows 1240 (especially Vista) has a different system for dealing with execute 1241 permission. 1242<P> 1243 The use of the 'mode' attribute and the following numbers is deprecated 1244 in favour of the 'type', 'readable', 'writable' and 'executable' 1245 attributes. The meaning of the bits in the mode attribute is as follows: 1246<PRE> 1247 Mode Meaning 1248------------------------------------------------ 1249 8'170000 file type 1250 8'040000 directory 1251 8'020000 character special 1252 8'060000 block special 1253 8'100000 normal file 1254 8'120000 symbolic link 1255 8'140000 socket 1256------------------------------------------------ 1257 8'004000 set user ID on execution 1258 8'002000 set group ID on execution 1259------------------------------------------------ 1260 8'000700 owner access 1261 8'000400 read permission for owner 1262 8'000200 write permission for owner 1263------------------------------------------------ 1264 8'000070 group access 1265 8'000040 read permission for group 1266 8'000020 write permission for group 1267------------------------------------------------ 1268 8'000007 other access 1269 8'000004 read permission for others 1270 8'000002 write permission for others 1271 8'000001 execute/search permission for others 1272</PRE> 1273"), 1274 args:["File" : "Atom or string.", "Attr" : "Atom or variable.", "Value" : "Constant or variable."], 1275 fail_if:"Fails if the file File does not exist, or doesn't have the attribute Attr", 1276 exceptions:[4 : "File is not instantiated.", 5 : "File is neither an atom nor a string.", 5 : "Attr is instantiated but not to an atom.", 5 : "Value is instantiated but not to a constant."], 1277 eg:" 1278Success: 1279 is_directory(File) :- 1280 get_file_info(File, type, directory), 1281 1282 1283 % the same test via mode bits: 1284 is_directory(File) :- 1285 get_file_info(File, mode, Mode), 1286 Mode /\\ file_type =:= directory_flag. 1287 1288 file_type(8'170000). 1289 directory_flag(8'40000). 1290 1291 1292 % A file is younger if its time is greater 1293 is_younger(File1, File2) :- 1294 get_file_info(File1, mtime) > get_file_info(File2, mtime). 1295 1296Fail: 1297 get_file_info(nofile, mode, Mode). 1298 get_file_info('/', mode, 8'100000). 1299 1300Error: 1301 get_file_info(File, ctime, T). (Error 4). 1302 get_file_info([file], gid, G). (Error 5). 1303 get_file_info(file, 1, X). (Error 5). 1304 1305 1306 1307", 1308 see_also:[exists / 1, delete / 1, exec / 3, local_time/8, local_time_string/3]]). 1309 1310:- comment(halt / 0, [ 1311 summary:"The Prolog session is ended (the same as Control-D at the top-level loop). 1312 1313", 1314 amode:(halt is erroneous), 1315 desc:html(" Used to exit from the Prolog session. If user_end/0 is defined and 1316 global, it is called. All buffers are flushed, streams are closed and 1317 ECLiPSe exits. Zero as status code is returned to the operating system. 1318 halt is identical with exit(0). 1319 1320<P> 1321"), 1322 args:[], 1323 eg:" 1324Success: 1325 [eclipse]: halt. 1326 cygnus% echo $status 1327 0 1328 cygnus% 1329 1330 [eclipse]: [user]. 1331 problem_exit :- 1332 writeln(debug_output, 'PROBLEM IN RECOVERY PROCEDURE'), 1333 halt. 1334 user compiled 132 bytes in 0.02 seconds 1335 yes. 1336 [eclipse]: problem_exit. 1337 PROBLEM IN RECOVERY PROCEDURE 1338 % 1339 1340 1341 1342", 1343 see_also:[exit / 1, break / 0, pause / 0]]). 1344 1345:- comment(kill / 2, [ 1346 summary:"Send the signal Signal to the process number Pid", 1347 amode:(kill(+,+) is semidet), 1348 desc:html("\ 1349 Send the signal Signal to the process with process ID Pid. 1350 If Signal is 0, then only a check for existence of the process 1351 is performed, i.e. kill/2 fails if the process does not exist. 1352 A process ID of 0 can be used as a shorthand for the current process. 1353<P> 1354 This predicate is modelled after the UNIX system call kill(2). 1355 Signal names are derived from their official names by stripping 1356 SIG and using lower case, e.g. 'segv' for SIGSEGV. 1357<P> 1358 On Windows, a subset of the functionality is supported: 1359 <UL> 1360 <LI>Checking for process existence using signal 0</LI> 1361 <LI>Terminating a process using signal 'term'</LI> 1362 <LI>Sending signals 'abrt, 'fpe, 'ill, 'int, 'segv' or 'term' 1363 to the current process/LI> 1364 </UL> 1365<P> 1366"), 1367 args:["Pid" : "Integer", "Signal" : "Atom or Integer"], 1368 fail_if:"Fails if Signal is 0 and process Pid does not exist", 1369 exceptions:[4 : "Pid or Signal are not instantiated.", 1370 5 : "Pid is instantiated to a non-integer.", 1371 5 : "Signal is instantiated to neither an integer nor an atom.", 1372 6 : "Signal is not a signal name or number.", 1373 170 : "Pid or Signal has an invalid value.", 1374 170 : "No permission to access process Pid."], 1375 eg:" 1376Success: 1377 [eclipse]: get_flag(pid, Pid), kill(Pid, 31). 1378 Signal 31 1379 Pid = 2929 1380 yes. 1381 1382 [eclipse]: kill(2929, 0) 1383 yes. 1384 1385 [eclipse]: kill(1234, term) 1386 yes. 1387Failure: 1388 [eclipse]: kill(9999, 0) 1389 no. 1390", 1391 see_also:[exec / 2, exec / 3, exec_group / 3, get_flag / 2, wait / 2]]). 1392 1393:- comment(pathname / 3, [ 1394 summary:"If FilePath is a pathname of a file, succeed if Path is the pathname of its 1395parent directory and Name is the local file name. 1396 1397", 1398 amode:(pathname(+,-,-) is det), 1399 desc:html(" This predicate is used to decompose FilePath which is either a relative 1400 or absolute pathname of a file, into two components, namely the pathname 1401 of its parent directory including the trailing \"/\" if any, and the plain 1402 name of the file Name. 1403 1404<P> 1405"), 1406 args:["FilePath" : "String or atom.", "Path" : "Variable or string.", "Name" : "Variable or string."], 1407 exceptions:[4 : "FilePath is not instantiated.", 5 : "FilePath is neither a string nor an atom.", 5 : "Path is neither a string nor a variable.", 5 : "Name is neither a string nor a variable."], 1408 eg:" 1409Success: 1410 [eclipse]: pathname(\"/home/user/userfile\", P, F). 1411 P = \"/home/user/\" 1412 F = \"userfile\" 1413 yes. 1414 1415 pathname(\"/home/user\",\"/home/\"). 1416 pathname(\"/home/\",\"/home/\",\"\"). 1417 pathname(\"home\",\"\",\"home\"). 1418 1419Fail: 1420 pathname(\"/home/file\",\"/home\",\"file\"). 1421 1422Error: 1423 pathname(F,P,R). (Error 4). 1424 pathname(\"/home/file\",P,file) (Error 5). 1425 1426 1427 1428", 1429 see_also:[pathname/4]]). 1430 1431:- comment(pathname / 4, [ 1432 summary:"Decomposes a filename into its directory path, base name and suffix", 1433 amode:(pathname(+,-,-,-) is det), 1434 desc:html("\ 1435 This predicate is used to decompose FilePath which is either a relative 1436 or absolute pathname of a file, into three components, namely the pathname 1437 of its parent directory including the trailing \"/\" if any, the `base' 1438 name of the file (the plain file name without the suffix), and the 1439 suffix, if any. The concatenation of Path, BaseName and Suffix yields 1440 the original filename FilePath. 1441"), 1442 args:["FilePath" : "String or atom.", 1443 "Path" : "Variable or string.", 1444 "BaseName" : "Variable or string.", 1445 "Suffix" : "Variable or string."], 1446 exceptions:[4 : "FilePath is not instantiated.", 1447 5 : "FilePath is neither a string nor an atom.", 1448 5 : "Path, BaseName or Suffix is neither a string nor a variable."], 1449 eg:" 1450Success: 1451 1452 [eclipse]: pathname(\"/home/user/userfile.pl\", P, B, S). 1453 1454 P = \"/home/user/\" 1455 B = \"userfile\" 1456 S = \".pl\" 1457 yes. 1458 1459 [eclipse]: pathname(\"/home/user/userfile\", P, B, S). 1460 P = \"/home/user/\" 1461 B = \"userfile\" 1462 S = \"\" 1463 yes. 1464 1465Fail: 1466 pathname(\"/home/file.pl\",\"/home/\",\"file\", \"pl\"). 1467 1468Error: 1469 pathname(F,P,R,S). (Error 4). 1470 pathname(\"/home/file.pl\",P,file,'.pl') (Error 5). 1471 1472 1473 1474", 1475 see_also:[pathname/3, split_string/4, join_string/3, canonical_path_name/2]]). 1476 1477:- comment(read_directory / 4, [ 1478 index:[directory,folder], 1479 summary:"Unifies SubdirList with a list of subdirectories and FileList with a list 1480of matching files in the specified directory. 1481 1482", 1483 amode:(read_directory(+,+,-,-) is det), 1484 desc:html(" read_directory/4 scans the directory specified by Directory. It 1485 collects the names of the subdirectories in SubdirList and the names of 1486 the files matching Pattern in FileList. SubdirList and FileList are 1487 lists of strings. Pattern is a string containing a filename 1488 specification similar to the usual UNIX convention. The metacharacters 1489 recognised are: * matches an arbitrary sequence of characters, ? 1490 matches any single character, [] matches one of the characters inside 1491 the brackets unless the first one is a ^ in which case it matches any 1492 character but those inside the brackets. 1493 1494<P> 1495 Filenames beginning with a dot are not suppressed by default, but the 1496 directories \".\" and \"..\" are omitted from SubdirList. 1497 1498<P> 1499"), 1500 args:["Directory" : "Atom or String", "Pattern" : "Atom or String", "SubdirList" : "Free variable or (maybe partial) list of strings", "FileList" : "Free variable or (maybe partial) list of strings"], 1501 exceptions:[4 : "Directory or Pattern is not instantiated.", 5 : "Directory or Pattern is neither atom nor string.", 5 : "SubdirList or FileList are instantiated, but not to lists.", 170 : "An error occurred trying to access Directory."], 1502 eg:" 1503 Success: 1504 [eclipse]: read_directory(\"/usr/john\", \"*\", Dirlist, Filelist). 1505 Dirlist = [\"subdir1\", \"subdir2\"] 1506 Filelist = [\"one.c\", \"two.c\", \"three.pl\", \"four.pl\"] 1507 yes. 1508 [eclipse]: read_directory(., \"[^t]*.pl\", Dirlist, Filelist). 1509 Dirlist = [\"subdir1\", \"subdir2\"] 1510 Filelist = [\"four.pl\"] 1511 yes. 1512 Fail: 1513 [eclipse]: read_directory(\".\", \"*.c\", _, [\"one.c\"]). 1514 no. 1515 Error: 1516 read_directory(_, \"*\", Dirs, Files). (error 4) 1517 read_directory([46], \"*\", Dirs, Files). (error 5) 1518 read_directory(\".\", _, Dirs, Files). (error 4) 1519 read_directory(\".\", 3, Dirs, Files). (error 5) 1520 read_directory(\".\", \"*.pl\", Dirs, file). (error 5) 1521 read_directory(\"/private\", \"*\", _, Files). (error 170) 1522 1523 1524 % EXAMPLE: find_tree(+Root, +Pattern, -ListOfRelativeFiles) 1525 % Recursively find all files matching Pattern below the directory 1526 % or list of directories Roots. 1527 1528 find_tree(Root, Pattern, AllFiles) :- (atom(Root);string(Root)), !, 1529 find_dir(Root, \"\", \"\", Pattern, AllFiles, []). 1530 find_tree(Roots, Pattern, AllFiles) :- 1531 find_tree(Roots, Pattern, AllFiles, []). 1532 1533 find_tree([], _Pattern, AllFiles, AllFiles). 1534 find_tree([Root|Roots], Pattern, AllFiles, AllFiles0) :- 1535 find_dir(Root, \"\", \"\", Pattern, AllFiles, AllFiles1), 1536 find_tree(Roots, Pattern, AllFiles1, AllFiles0). 1537 1538 find_dir(_, _, [], _, AllFiles, AllFiles) :- !. 1539 find_dir(Root, RelPath, [Dir|Dirs], Pattern, AllFiles, AllFiles0) :- !, 1540 find_dir(Root, RelPath, Dir, Pattern, AllFiles, AllFiles1), 1541 find_dir(Root, RelPath, Dirs, Pattern, AllFiles1, AllFiles0). 1542 find_dir(Root, RelPath, Dir, Pattern, AllFiles, AllFiles0) :- 1543 ( RelPath==\"\" -> RelDir=Dir 1544 ; concat_string([RelPath,/,Dir], RelDir) ), 1545 ( RelDir==\"\" -> AbsDir=Root 1546 ; concat_string([Root,/,RelDir], AbsDir) ), 1547 read_directory(AbsDir, Pattern, SubDirs, Files), 1548 find_files(Root, RelDir, Files, AllFiles, AllFiles1), 1549 find_dir(Root, RelDir, SubDirs, Pattern, AllFiles1, AllFiles0). 1550 1551 find_files(_, _, [], AbsFiles, AbsFiles). 1552 find_files(Root, RelDir, [File|Files], [AbsFile|AbsFiles], AbsFiles0) :- 1553 ( RelDir==\"\" -> concat_string([Root,/,File], AbsFile) 1554 ; concat_string([Root,/,RelDir,/,File], AbsFile) ), 1555 find_files(Root, RelDir, Files, AbsFiles, AbsFiles0). 1556", 1557 see_also:[cd / 1, getcwd / 1, get_flag / 2, pathname / 4, existing_file/4, exists / 1, mkdir / 1]]). 1558 1559:- comment(sh / 1, [ 1560 summary:"The string or atom ShellCommand is passed as a command to the operating 1561system, and the command is executed there (it is a synonym for system/1). 1562 1563", 1564 amode:(sh(+) is semidet), 1565 desc:html(" Used to send a command ShellCommand to the operating system. The 1566 command uses the streams input, output and error as the UNIX streams 1567 stdin, stdout and stderr respectively. ECLiPSe -specific streams, like 1568 null or a string stream, can not be used. 1569 1570<P> 1571"), 1572 args:["ShellCommand" : "String or atom."], 1573 fail_if:"Fails if the Shell couldn't be executed or if the command returned a non-zero status", 1574 exceptions:[4 : "ShellCommand is not instantiated.", 5 : "ShellCommand is instantiated, but not to a string or atom."], 1575 eg:" 1576Success: 1577 [eclipse]: sh('ls -F'). 1578 file1 dir1/ 1579 yes. 1580 1581 [eclipse]: sh(date). 1582 Fri Aug 25 12:00:00 MET DST 1989 1583 yes. 1584 1585 [eclipse]: sh(\"cd ..\"). 1586 yes. 1587 1588 [eclipse]: sh('which eclipse'). 1589 /home/user/eclipse 1590 yes. 1591 1592Error: 1593 sh(S). (Error 4). 1594 sh(40). (Error 5). 1595 1596 1597 1598", 1599 see_also:[exec / 2, exec / 3, exec_group / 3, setenv/2, wait / 2]]). 1600 1601:- comment(system / 1, [ 1602 summary:"The string or atom ShellCommand is passed as a command to the operating 1603system, and the command is executed there (it is a synonym for sh/1). 1604 1605", 1606 amode:(system(+) is semidet), 1607 desc:html(" Used to send a command ShellCommand to the operating system. The 1608 command uses the streams input, output and error as the UNIX streams 1609 stdin, stdout and stderr respectively. ECLiPSe -specific streams, like 1610 null or a string stream, can not be used. 1611 1612<P> 1613"), 1614 args:["ShellCommand" : "String or atom."], 1615 fail_if:"Fails if the Shell couldn't be executed or if the command returned a non-zero status", 1616 exceptions:[4 : "ShellCommand is not instantiated.", 5 : "ShellCommand is instantiated, but not to a string or atom."], 1617 eg:" 1618Success: 1619 [eclipse]: system('ls -F'). 1620 file1 dir1/ 1621 yes. 1622 1623 [eclipse]: system(date). 1624 Fri Aug 25 12:00:00 MET DST 1989 1625 yes. 1626 1627 [eclipse]: system(\"cd ..\"). 1628 yes. 1629 1630 [eclipse]: system('which eclipse'). 1631 /home/user/eclipse 1632 yes. 1633 1634Error: 1635 system(S). (Error 4). 1636 system(40). (Error 5). 1637 1638 1639 1640", 1641 see_also:[exec / 2, exec / 3, exec_group / 3, setenv/2, sh / 1, wait / 2]]). 1642 1643:- comment(wait / 2, [ 1644 summary:"Wait for a child process to terminate and report its process ID and status.", 1645 amode:(wait(+,-) is semidet), 1646 amode:(wait(-,-) is nondet), 1647 desc:html("\ 1648 This predicate is used to make the ECLiPSe process wait until a 1649 child process (created e.g. by exec/3 and identified by its process id Pid) 1650 terminates. Status is unified with the child process exit status. 1651<P> 1652 A child process created with exec/3 still exists in the operating system 1653 even after it exits, as long as it was not waited for. Therefore it is 1654 advisable to use a wait/2 call after every exec/3 (note that exec/2 waits 1655 for the child process internally). 1656<P> 1657 <B>UNIX specific behaviour:</B> 1658 The predicate can be invoked with Pid uninstantiated. In this case it will 1659 be resatisfiable and succeed once for every child process that terminates, 1660 as soon as a child process terminates, as long as there are child processes. 1661<P> 1662 If the child process created by exec/3 or exec_group/3 could not be 1663 executed, the child exits with status 128 + errno. 1664<P> 1665 When wait/2 is interrupted by a signal, the signal handler will be allowed 1666 to execute, and if it does not abort, wait/2 will be restarted subsequently. 1667<P> 1668 When the child process terminated normally, then Status is the value 1669 that the child process exited with, multiplied by 256 (see wait(2)). 1670<P> 1671 <B>WINDOWS specific behaviour:</B> 1672 The predicate can only be used to wait for one specific process, i.e. the 1673 Pid argument must be instantiated and the predicate is not resatisfiable. 1674<P> 1675 When the child process terminated normally, then Status is the value 1676 that the child process exited with. 1677"), 1678 args:["Pid" : "Integer or variable", "Status" : "Integer or variable"], 1679 fail_if:"Fails if there are no child processes or the specified process does not exist", 1680 exceptions:[5 : "Pid or Status are instantiated to non-integers."], 1681 eg:" 1682Success: 1683 [eclipse]: exec([true], [], Pid), wait(Pid, Status). 1684 Pid = 3417 1685 Status = 0 1686 Yes (0.00s cpu) 1687 1688 [eclipse]: exec([true], [], Pid), exec([date], [], Pid2), wait(Pid2, S2). 1689 Thu May 17 16:58:45 MET DST 1990 1690 1691 Pid = 10617 1692 Pid2 = 10618 1693 S2 = 0 1694 Yes (0.00s cpu) 1695 1696 1697 % Unix only 1698 [eclipse 7]: exec([true],[],Pid1), exec([true],[],Pid2), wait(P,S). 1699 1700 Pid1 = 13718 1701 Pid2 = 13719 1702 P = 13718 1703 S = 0 1704 More (0.00s cpu) ? ; 1705 1706 Pid1 = 13718 1707 Pid2 = 13719 1708 P = 13719 1709 S = 0 1710 More (0.00s cpu) ? ; 1711 1712 No (0.00s cpu) 1713 1714 1715Fail: 1716 [eclipse]: exec(\"true\", [], Pid), wait(1111, S). 1717 1718 No (0.00s cpu) 1719 1720 1721Example (UNIX only): 1722 1723 % Kill the process in case the wait is aborted, 1724 % e.g. due to a timeout or after-event handler 1725 1726 wait_with_cleanup(Pid, Status) :- 1727 catch( 1728 wait(Pid, Status), 1729 Tag, 1730 ( kill(Pid, 2), wait(Pid, _), throw(Tag) ) 1731 ). 1732", 1733 see_also:[exec / 2, exec / 3, exec_group / 3, kill / 2, sh / 1]]). 1734 1735 1736:- comment(local_time / 8, [ 1737 summary:"Conversion between local time and universal time", 1738 amode:(local_time(+,+,+,+,+,+,?,-) is semidet), 1739 amode:(local_time(-,-,-,-,-,-,-,+) is det), 1740 args:[ 1741 "Year" : "Integer or variable", 1742 "Month" : "Integer or variable", 1743 "Day" : "Integer or variable", 1744 "Hour" : "Integer or variable", 1745 "Minute" : "Integer or variable", 1746 "Second" : "Integer or variable", 1747 "DST" : "0, 1 or variable (daylight savings time flag)", 1748 "UnixTime" : "Variable or integer (seconds since 1/1/1970)" 1749 ], 1750 1751 desc:html("\ 1752 This predicate is used to convert between local time (taking 1753 into account time zone and daylight savings time settings) and 1754 UTC (Universal Coordinated Time, represented as 'Unix time', i.e. 1755 in seconds since 1970-01-01, 00:00). 1756 <P> 1757 The conversion works in both directions. If the UnixTime argument 1758 is instantiated, it gets converted to the local date and time, and 1759 the first 6 arguments get unified accordingly. 1760 <P> 1761 If the first 6 (or 7) arguments are instantiated, they will be 1762 interpreted under the current time zone and daylight savings time 1763 rules, and converted into 'Unix time', which is unified with the 1764 last argument. 1765 <P> 1766 In both directions, the DST argument can usually remain uninstantiated, 1767 and will be unified with 1 if the date specified is while daylight 1768 savings time is in effect, and 0 otherwise. Note however, that during 1769 the switch from summer to winter time, there is usually a one hour 1770 overlap, where the same time of day exists twice, once in summer and 1771 once in winter time. In this case, when converting from local time 1772 to UTC, the caller should instantiate DST in order to disambiguate. 1773 <P> 1774 The predicate can also be used to test for valid local date and time: 1775 If the first 6 (or 7) arguments do not represent a valid date, the 1776 predicate fails. 1777 <P> 1778 This predicate is based on the POSIX localtime() and mktime() functions. 1779"), 1780 fail_if:"The first 7 arguments do not represent a valid date", 1781 exceptions:[ 1782 4 : "The arguments are insufficiently instantiated", 1783 5 : "Any of the arguments is not of the expected numerical type", 1784 6 : "UnixTime is out of range"], 1785 eg:" 1786 ?- get_flag(unix_time,T), local_time(Yr,Mo,Dy,Hr,Mi,Sc,Ds,T). 1787 Yr = 2003 1788 Mo = 4 1789 Dy = 4 1790 Hr = 16 1791 Mi = 38 1792 Sc = 30 1793 Ds = 1 1794 T = 1049470710 1795 Yes (0.00s cpu) 1796 1797 ?- local_time(2003,4,4,16,38,30,1,T). 1798 T = 1049470710 1799 Yes (0.00s cpu) 1800 1801 ?- local_time(2003,4,4,16,38,30,_,T). 1802 T = 1049470710 1803 Yes (0.00s cpu) 1804 1805 ?- local_time(2003,1,1,25,0,0,_,_). % invalid hour 1806 No (0.00s cpu) 1807 1808 ?- local_time(2003,2,29,12,0,0,_,_). % invalid date (no leap year) 1809 No (0.00s cpu) 1810 1811 % The following examples assume DST rules for Britain 1812 ?- local_time(2003,3,30,1,30,0,_,_). % invalid time (skipped hour) 1813 No (0.00s cpu) 1814 1815 ?- local_time(2003,10,26,1,0,0,1,T). % 1h before end of summer time 1816 T = 1067126400 1817 Yes (0.01s cpu) 1818 1819 ?- local_time(2003,10,26,1,0,0,0,T). % 1 hour later 1820 T = 1067130000 1821 Yes (0.00s cpu) 1822", 1823 see_also:[date/1, local_time_string/3, library(calendar)]]). 1824 1825 1826:- comment(local_time_string / 3, [ 1827 summary:"Create a string representation of the local time", 1828 amode:(local_time_string(+,+,-) is det), 1829 args:[ 1830 "UnixTime" : "Integer (seconds since 1/1/1970)", 1831 "Format" : "String or Atom", 1832 "TimeString" : "Variable or string" 1833 ], 1834 1835 desc:html("\ 1836 This predicate converts UTC (Universal Coordinated Time, represented 1837 as 'Unix time', i.e. in seconds since 1970-01-01, 00:00) into a 1838 textual representation of the local time (taking into account time 1839 zone and daylight savings time settings), according to the given 1840 format string. 1841 <P> 1842 The format string is similar to the format string in the printf/2,3 1843 predicate, but accepts different format specifiers. The exact set of 1844 format specifiers available depends on the underlying operating 1845 system (refer to the description of strftime()), but the following 1846 are generally available: 1847 <DL> 1848 <DT><STRONG>%a</STRONG></DT> <DD>Abbreviated weekday name for current locale 1849 1850 <DT><STRONG>%A</STRONG></DT> <DD>Full weekday name for current locale 1851 1852 <DT><STRONG>%b</STRONG></DT> <DD>Abbreviated month name for current locale 1853 1854 <DT><STRONG>%B</STRONG></DT> <DD>Full month name for current locale 1855 1856 <DT><STRONG>%c</STRONG></DT> <DD>Preferred date and time representation for current locale 1857 1858 <DT><STRONG>%d</STRONG></DT> <DD>Day of month as decimal number (01-31) 1859 1860 <DT><STRONG>%H</STRONG></DT> <DD>Hour in 24-hour format (00-23) 1861 1862 <DT><STRONG>%I</STRONG></DT> <DD>Hour in 12-hour format (01-12) 1863 1864 <DT><STRONG>%j</STRONG></DT> <DD>Day of year as decimal number (001-366) 1865 1866 <DT><STRONG>%m</STRONG></DT> <DD>Month as decimal number (01-12) 1867 1868 <DT><STRONG>%M</STRONG></DT> <DD>Minute as decimal number (00-59) 1869 1870 <DT><STRONG>%p</STRONG></DT> <DD>Current locale's A.M./P.M. indicator for 12-hour clock 1871 1872 <DT><STRONG>%S</STRONG></DT> <DD>Second as decimal number (00-59) 1873 1874 <DT><STRONG>%U</STRONG></DT> <DD>Week of year (00-53), with first Sunday first day of week 01 1875 1876 <DT><STRONG>%w</STRONG></DT> <DD>Weekday as decimal number (0-6, Sunday is 0) 1877 1878 <DT><STRONG>%W</STRONG></DT> <DD>Week of year (00-53), with first Monday first day of week 01 1879 1880 <DT><STRONG>%x</STRONG></DT> <DD>Date representation for current locale 1881 1882 <DT><STRONG>%X</STRONG></DT> <DD>Time representation for current locale 1883 1884 <DT><STRONG>%y</STRONG></DT> <DD>Year without century, as decimal number (00-99) 1885 1886 <DT><STRONG>%Y</STRONG></DT> <DD>Year with century, as decimal number 1887 1888 <DT><STRONG>%Z</STRONG></DT> <DD>Time-zone name or abbreviation, empty if time zone is unknown 1889 1890 <DT><STRONG>%%</STRONG></DT> <DD>Percent sign 1891 </DL> 1892 <P> 1893 This predicate is based on POSIX strftime(). 1894"), 1895 exceptions:[ 1896 4 : "UnixTime or Format are uninstantiated", 1897 5 : "UnixTime, Format or TimeString are instantiated, but not strings"], 1898 eg:" 1899 ?- get_flag(unix_time, T), local_time_string(T, \"%c\", S). 1900 T = 1049564174 1901 S = \"Sat Apr 05 18:36:14 2003\" 1902 Yes (0.00s cpu) 1903 1904 ?- get_flag(unix_time, T), 1905 local_time_string(T, \"We write the year %Y in time zone %Z\", S). 1906 T = 1049564247 1907 S = \"We write the year 2003 in time zone BST\" 1908 Yes (0.00s cpu) 1909", 1910 see_also:[date/1, local_time/8, library(calendar)]]). 1911 1912 1913 1914