Porting UNIX Applications to OpenEdition

Porting UNIX Applications

Neale Ferguson

TABNSW-OPEN

May, 1996

TAB of NSW
GPO Box 4168
Sydney NSW 2001
Porting UNIX Applications to OpenEdition

Abstract

VM/ESA Version 2 and MVS Version 5 delivers Open Systems facilities to programmers in the VM and MVS environments. In this presentation I will discuss the reasons for porting applications. Following this I will take detailed look at a few applications I've ported and describe the facilities and techniques utilised to make them work.

For the purposes of clarity a quick How to speak Australian guide has been included in the appendices.

Audience: General

Keywords: VM, MVS, UNIX, OpenEdition


Table of Contents

Abstract

Introduction

  • Leveraging Your Investment
  • Porting Applications

  • TAB Context
  • Tools
  • POSIX 1003.2 - Shell and Utilities
  • Hierachical File System
  • Miscellaneous
  • Porting Observations
  • General
  • Make and Make files
  • The Applications
  • dmake Observations
  • pgp Observations
  • java Observations
  • xsb Observations
  • httpd Observations
  • gnu make Observations
  • perl Observations
  • gzip Observations
  • gcc Observations
  • Some other Applications
  • Future Requirements
  • fork
  • XPG4 Compliance
  • Conclusion
  • Challenges
  • Appendix A. OpenVM Commands

    Appendix B. A Make Primer

  • Targets
  • Macros
  • Comments
  • Makefile Contents
  • Rules
  • Conditionals
  • Portability
  • Related Information
  • Make file for XSB
  • Appendix C. OpenEdition MVS

  • List of the Single UNIX Specification commands
  • OpenEdition MVS Software Application Providers
  • Appendix D. How to Speak 'Strine

  • Common Words
  • Some Translations
  • Appendix E. Java Directory Structure


    Introduction

    Reports from Carl Greiner of the Meta Group and Barry Graham of Xephon report continuing growth in S/390. A nett growth of 33% per annum is being achieved in S/390 MIPs (a gross figure of 50% - the difference being due to data centre consolidations). Similarly, DASD, which is estimated at 3Gb per MIP, is also growing at a healthy rate.

    At the same time the price of this same hardware is dropping rapidly. Currently, hardware accounts for around 40% of the IT budget. The Meta Group estimate that by 1998 this figure will drop to 6% as both CPU technology (via CMOS and CMOS/ECL) and DASD improve their price/performance. Some estimate a cost of $1 per megabyte for DASD in the next few years.

    Once upon a time the big push to UNIX was based on the inexpensive nature of the hardware. This is very true of the desktop and departmental systems. However, to meet the needs of the enterprise the UNIX high-end equipment is not dirt-cheap. In fact, the price of S/390 systems are dropping to such a point that the advantage once held by UNIX in this area is not as compelling. Considering hardware will soon no longer be the big ticket item within an enterprise this factor is not going to be the deciding one.

    In terms of systems management, S/390 still has it all over UNIX. As these facilities are being developed for the UNIX environment the price of the software (another of the original reasons to make the switch from S/390) is increasing enormously. Thus, there are very sound business reasons developing for keeping your applications on the S/390 platform.


    Leveraging Your Investment

    The term legacy is often used to refer to applications running under S/390. Often it is often used as a perjorative: implying that they are outmoded, inefficient, or wasteful. Sure these applications may have been around for a long time but if they are the cash generators of your enterprise they don't sound like a legacy to me. In the case of the TAB, for example, out legacy systems are responsible for the turnover of $AUD3.5 billion per annum.

    This heritage is not going to disappear nor would you want it to. What you do want is for these applications to become part of the new enterprise.

    Client/Server is here to stay. While VM has been doing it since day 1, in its modern incarnation Client/Server has passed through various stages in its development:

    Therefore, the S/390 has to become an active participant in the client/server story. I'll go even further by saying it should be a driving force. This is where OpenEdition is coming from. We are taking the heritage of systems management, reliability, availability, and skills and leveraging them by adding value in the form of open standards and interoperability.

    There are a number of reasons why we are seriously looking at OpenEdition as a base for UNIX-style applications:

    The OpenEdition MVS developers cite several reasons for porting applications. Their reasons are just as valid for VM:

    OpenEdition MVS can be applied to your enterprise in many ways. Using OpenEdition MVS, your enterprise can:

    Porting Applications


    TAB Context

    The TAB has been a user of VM since 1974 and DOS since 1970. This has been the mix up until this time. Exposure to UNIX has been way of university courses and an old RT PC we got thrown in with our original 3090s.

    Therefore, we have approached OpenEdition from the point of view of what does it do and what does it offer? My observations must be considered in this context not as a UNIX expert commenting on the way IBM has implemented the product.


    Tools

    POSIX 1003.2 - Shell and Utilities

    These are the end user interactive commands that own the terminal, interpret the command string and invoke the required command. A set of built-in commands is provided to the user for

    IBM has licensed MORTICE Kern Systems Inc. to provide their Shell and Utilities source code to be used as the basis for supporting POSIX 1003.2. As such, this is a separately priced feature of VM/ESA.

    Under VM the shell is a CMS application which provides a subcommand environment. It executes other OpenEdition applications (the Utilities and user applications). The shell and utilities are provided to:

    It is not a replacement for a full UNIX interactive end-user environment (e.g. no vi but isn't that a blessing?).

    CMS users can enter the shell when needed via

    OPENVM SHELL
    

    command. UNIX users can enter the shell via their PROFILE EXEC. CP and CMS commands, plus any regular CMS application can be executed from the shell via the cms shell builtin command.

    For those familiar with UNIX shell commands here is a list of the commands supported by VM/ESA OpenEdition (compare this to MVS see "List of the Single UNIX Specification commands"):

    alias    continue expr     ln       pathchk  sort     ulimit
    ar       cp       false    locale   pax      strip    umask
    awk      cpio     fc       localede pr       stty     unalias
    basename cut      fg       logger   print    su       uname
    bc       c89      find     logname  printf   tail     uniq
    bg       date     fold     lp       ps       tar      unset
    break    dd       getconf  ls       pwd      tee      wait
    cat      df       getopts  mailx    read     test     wc
    cd       diff     grep     make     readonly time     whence
    chgrp    dirname  head     mkdir    return   times    xargs
    chmod    echo     iconv    mkfifo   rm       touch    yacc
    chown    ed       id       mknod    rmdir    tr
    cksum    env      jobs     mv       sed      trap
    cmp      eval     join     newgrp   set      true
    cms      exec     kill     nohup    sh       tty
    comm     exit     let      od       shift    type
    command  export   lex      paste    sleep    typeset
    

    Some Useful Commands

    alias

    Use alias to tailor commands: e.g. If don't you like using the command rm you can use alias to allow you to refer it as erase:

    alias erase=rm
    
    Similarly, if you find when you invoked grep with the -i option then you can use alias so that when you invoke grep it automatically invokes the -i option:
    alias grep="grep -i"
    

    ar

    maintains archive libraries. The archive library is a collection of files, usually object files. Using ar, you can perform various operations on archive libraries, such as creating a new library, adding members to an existing library, deleting members from a library, extracting members from a library, printing a table of contents for a library, and so on.

    This command is useful for collecting common object files for subsequent use by other applications.

    awk

    like make, is the stuff from which courses are built. You may encounter them during your porting endeavours. The VM developers define awk as follows:

    awk is a file-processing language that is well suited to data manipulation and retrieval of information from text files.

    An awk program consists of any number of user-defined functions and rules of the form:

    pattern {action}
    

    chmod

    Change access permission to a file or directory. To use this command you must be a super-user, the owner of the file or directory, or have appropriate privileges.

    This command is useful after porting an application and assigning authorities when releasing to the enterprise.

    cms

    Pass the command to CMS for processing.

    cp

    Copy a file

    c89

    compiles, prelinks, and builds IBM C for VM/ESA programs. First, c89 performs the compilation phase (including preprocessing) by compiling all operands of the file.c form. The result of each compile step is a file.o file. If all compilations are successful, or if only file.o and no file.c files are specified, c89 proceeds to the module build phase, which consists of a prelink step and CMS module generation step.

    In the module build phase, c89 combines all file.o files from the compilation phase along with any file.o operands that were specified. Any file.a and -l libname operands that were specified are also used.

    c89 is what your make recipes will invoke to compile and build the application.

    diff

    this command attempts to determine the minimal set of changes needed to convert a file whose name is specified by the first argument into the file specified by the second argument.

    By default, output consists of descriptions of the changes in a style like that of the ed text editor. A line indicating the type of change is given. The three types are a (append), d (delete), and c (change).

    find

    searches a given file hierarchy specified by path, finding files that match the criteria given by expression. Each directory, file, or special file encountered in the hierarchy is "passed through" the command arguments, and if a match is found, then an action defined by the command arguments occurs.

    For example,

    1. To find all files with a suffix of .c that have the audit mode set to rwx (read, write, execute), enter:
      find / -name "*.c" -audit rwx=sf
      

    2. To find all files with a suffix of .c and audit mode bits set to 777 (rwx), enter:
      find / -name "*.c" -audit 777
      

    grep

    searches files for one or more pattern arguments. It does plain string, basic regular expression, and extended regular expression searching.

    grep is very useful when undertaking porting as it allows you to search for things like entry points in source files you may be having problems with. When teamed with the piping facilities of OpenEdition you can get grep to perform some large and complex searches for you and have action taken on the files found.

    Combined with find it is a powerful tool for searching through entire directory structures:

    find ./ -name "*.c" | xargs grep -i "fork"
    

    ls

    lists files and directories. If the pathname is a file, ls displays information on the file according to the requested options. If it is a directory, ls displays information on the files and subdirectories therein.

    ls is the OpenEdition equivalent to the CMS listfile command.

    make

    See "Make and Make files".

    mv

    Move a file.

    pax

    Of all the command you will need to deal with pax, make, and c89 are the ones you'll probably deal with more than others.

    pax reads and writes archive files. An archive file concatenates the contents of files and directories, and can also record such information as file modification dates, owner names, and so on. You can therefore use a single archive file to transfer a directory structure from one machine to another, or to back up or restore groups of files and directories.

    pax understands cpio, tar, and ustar archive formats (compressed and uncompressed).

    pax will also perform character set conversion: i.e. from ASCII to EBCDIC (usually ISO-8859 to IBM-1047). This is a handy utility. Becareful, though, if your archive contains a mixture of ASCII and binary data.

    rm

    Remove a file or directory structure.

    &

    Use & at the end of a command string to cause the command to run in the background.

     find ./ -name "*.c" -type f &
     [1]     1609
     [neale - /home/neale/XSB/emu]>
     ./auxlry.c
     ./util.c
     ./xsb_error.c
    

    profile and .profile

    These files can be used to tailor the shell for your:

    1. System-wide needs - creating a file called profile in the /etc directory;
      # sample /etc/profile
      export TZ=EST0EDT
      export MAKESTARTUP=/etc
      # export LC_ALL='En_US'
      cms 'VMFCLEAR'
      date '+%A %B %Od %r %Z %Y'
      # The MAILMSG will be printed by the shell every MAILCHECK seconds
      # (default 600) if there is mail in the MAIL system mailbox.
      export MAIL=/usr/mail/$LOGNAME
      export MAILMSG="You have new mail."
      #
      PATH=/bin:/usr/bin:/etc:$HOME:$HOME/bin
      export PATH
      HOME=/home/$LOGNAME
      cd $HOME
      PS1='[$LOGNAME - $PWD]>'
      PS2="> "
      cms 'SET OUTPUT AD ['
      cms 'SET OUTPUT BD ]'
      cms 'SET INPUT [ AD'
      cms 'SET INPUT ] BD'
      alias help="cms help oshell"
      if [ -s "$MAIL" ]           # This is at Shell startup.  In normal
      then echo "$MAILMSG"        # operation, the Shell checks periodically
      fi
      #
      

    2. Your individual needs - creating a file called .profile in your home directory.

    XEDIT

    Although not strictly a shell command, I create a simple shell script to invoke XEDIT whenever I use the command x. For those of you who want to feel UNIXy why not create a vi script to do the same!

    cms "X '$1' (NAMETYPE BFS"
    

    Homegrown BFSLIST

    Just as FILELIST provides a scrollable fullscreen display of files in a directory or on a minidisk, I needed a tool to better access files within a BFS. I wrote some simplex EXECs, PIPEs and filters to produce BFSLIST. Now I could work on projects by acting on files displayed on a directory basis:

     NEALE    BFSLIST  A0  V 80  Trunc=80 Size=12 Line=1 Col=1 Alt=0
    Directory: /home/neale/XSB/
    Cmd    T Privs     Owner    Group        Size Date       Time     FileID
           D rwxrwxr-x neale    system          0 1995/10/11 11:15:11 cmplib
           D rwxrwxr-x neale    system          0 1996/02/08 15:35:12 emu
           D rwxrwxr-x neale    system          0 1995/10/12 13:55:04 examples
           D rwxrwxr-x neale    system          0 1995/10/12 08:26:01 lib
           F rwxr-xr-x neale    system       5514 1994/11/21 23:54:08 makeall
           F rwxr-xr-x neale    system       5343 1994/11/21 23:54:08 makeall.sh
           D rwxrwxr-x neale    system          0 1994/11/21 23:57:52 manual
           F rw-r--r-- neale    system         69 1994/11/21 23:54:08 registration
           D rwxrwxr-x neale    system          0 1995/11/20 08:48:07 syslib
           F rw-r--r-- neale    system       6039 1994/11/21 23:54:07 LICENCE
           F rw-rw-r-- neale    system        779 1995/09/20 08:38:53 MakeLog
           F rw-r--r-- neale    system       4820 1994/11/21 23:54:07 README
    

    1= Help 2= Refresh 3= Quit 4= Cancel 5= Sort(dir) 6= Sort(size) 7= Backward 8= Forward 9= FL /n 10= 11= XEDIT/LIST 12= Cursor

    ====>

    3270 Considerations

    UNIX evolved as a character orientated operating system while S/390 operating systems have their roots in the record orientated world. It is amusing to read a UNIX bigot stating that S/390 languages were record orientated because of their punch card legacy while they have the far superior byte mechanism. The truth is the legacy UNIX has is its tty roots.

    In a large enterprise it would be suicide for a system to field interrupts generated by every key stroke that's why 3270's have enter keys. This requires some adjustment to the way a UNIX application may work under OpenEdition (see "pgp Observations"). Similarly, the character set used by a UNIX programmer is slightly different to that used on S/390 (and I don't mean just ASCII/EBCDIC):

    Escape Sequences

    On a workstation the CTRL key is used extensively to send (not surprisingly) control sequences to the system. This, of course, will not work under a 3270 which has no control key nor anyway of generating the sequence it produces. To support applications which rely on such sequences special 3270 character sequences are used. By default, this appears as:

    <esc-char><signal><enter>
    

    where: <esc-char> = ¢. <signal> = character such as 'C', 'V', 'D', or 'Z' <enter> = enter key

    Thus to signal CTRL-C you would enter:

    ¢.C<enter>
    

    The meanings of some of the escape sequences are as follows:

    VM Terminal Characters

    Some of the characters with either special meaning to UNIX applications or favoured by them, tend to clash with the S/390 system. For example, under VM/ESA, the default line delete character is the '¢.' sign, similarly the " and @ signs both have special meaning. Therefore, to avoid this clash do one of two things:

    1. Change to always use different characters; or,

    2. Change to different characters during the course of your OpenEdition work.

    I adopt the second course and use the profile script to override the VM defaults each time anyone enters the shell.

    Square Brackets

    Typically the 3270 keyboard doesn't have the characters [ or ] available. The PC keyboard utility, 3174 utility, or 3472 setup will allow you to make them available by remapping the keyboard. Depending on the codepage, however, they may be X'BA' and X'BB' instead of X'AD' and X'BD'. Under CMS this is easy to fix:

    set output [ AD
    set output ] BD
    set input [ AD
    set input ] BD
    

    Hierachical File System

    As part its implementation of 1003.1 CMS & MVS have provided a byte-stream oriented hierachical file system (aka the Byte File System). Under CMS this is an extension of the Share File System. Byte files can coexist with standard CMS SFS files within the one server. This means that it also shares a common set of administration commands and utilities. DFSMS/VM is also able to manage this storage.

    Byte files are characterized by the following:

    Figure 1. Standard File System Layout


                /
                |
     ---------------------------------------
     |    |     |     |      |      |      |
    bin  dev   etc   tmp    lib     u     usr
                                           |
                           -------------------------------------------
                           |       |     |      |        |      |    |
                          lpp    mail   man    lib    include  pub spool
                                                |        |
                                                |       sys
                                                |
                                ----------------------------
                                |          |       |       |
                             charmap   localedef  msg    locale
    

    Users can extend this Standard File System Layout:

    Under CMS you can XEDIT byte files just as you can with CMS files.

    XEDIT '/usr/data.file' (nametype bfs
    
    Similarly, files can by accessed by POSIX byte file services via the use of an external link. External links are a way to represent a non-POSIX object as its POSIX counterpart:

    For example:

    1. Usage of CMSEXEC external links:

    2. Usage of CMSDATA external links:

    Files (including modules) can also be exchanged between the CMS file system and byte file system.

    OPENVM RUN /bin/program1
    OPENVM PUTBFS PROFILE EXEC A /usr/.profile
    OPENVM GETBFS /usr/Makefile MAKE FILE A
    

    Miscellaneous

    At the time of my porting exercises my VM system has no direct connection to the Internet. This was for security reasons and has been changed after the installation of our Firewall. Thus, getting the applications from places like ftp.uu.net was not a straightforward matter.

    The steps I went through to get an archive from a site on the Internet to my BFS were as follows:

    1. ftp archive to my OS/2 system;

    2. Use ALMCOPY to transfer to VM. ALMCOPY has no support for long names so when you ftp make sure you make the local name fits the 8.3 naming convention;

    3. Use OPENVM PUTBFS command to transfer from CMS file system (minidisk or SFS) to BFS. Depending on how large the archive is you may need to increase storage because the internal PIPE command uses a lot of storage: e.g. TEX archive was 20M and needed a virtual machine larger than 64M.

    Porting Observations

    As part of our work on the VM/ESA Version 2 ESP I have attempted to port various packages FTP'd from sites around the world to see how easy/hard it is to move a UNIX application to OpenVM. The following sections detail my observations.

    General

    For VM/ESA users, the major area where conversion effort will be required is that VM does not support fork(). There are compelling reasons why the developers did not implement it (at least in the first incarnation of OpenEdition for VM). Consider what fork(). actually does and how applications use it. fork() clones another process which has the same programs, data, files etc. as the original. This means an entirely new address space has to be created. MVS, which also wasn't going to support fork(), implemented it via the use of APPC hot-pools. VM, on the other hand, observed that most applications which used fork() did so in order to execute another program. That is, the programmer was prepared to suffer the overhead of cloning a process just so he/she could then clear the space and run another program. This is overkill. Therefore, the VM developers implemented spawn() which combines the fork() and exec paradigm in a single call:

    Use the spawn service to create a child process to run the specified executable file. This service combines the semantics of the fork and exec services.

    The other use of fork() is for reasons of multi-tasking. It would be more efficient if the application used the POSIX threads support instead. In instances where a fork() can't be avoided there are techniques involving spawn() you can use to simulate it.

    Make and Make files

    Here is the simple description of make:

    make helps you manage projects containing a set of interdependent files, such as a program with many source and object files, or a document built from source files, macro files, and so on. make keeps all such files up to date with one another. If one file changes, make updates all the other files that depend on the changed file.

    In reality, make is the stuff of a two week course. There are some many things it can do and so many ways you can get it to do things. It is also the source of some of the major headaches when porting things.

    Generally, make is pretty straightforward. Most developers attempt to keep it that way but occasionally you discover someone who has obviously been programming in APL. I recommend you familiarise yourself with make and some simple make recipes before you start the porting. For those who've developed on PCs or UNIX then you have a headstart and won't have much difficulty in getting the porting exercise underway.

    I've included the relevant sections from the make help information in the appendices to help you understand its function more clearly (see Appendix B. "A Make Primer").

    For the novice UNIX programmer like myself, the hardest thing to debug are make files. In fact, they can be the difference between proceeding with a port or not (as I discovered with the alpha release of java).

    The Applications

    dmake
    Make replacement from U. Waterloo. Supports extensions used by many makefiles.

    pgp
    Pretty Good Privacy (ftp'd from a site in New Zealand).

    java
    Sun's Java and Hotjava system (compiler, interpreter and browser).

    xsb
    Prolog/Hilog compiler and interpreter.

    httpd
    NCSA's public domain web server.

    gnu make
    GNU's version of make. Even more flexible than dmake.

    perl
    UNIX scripting language (awk meets c).

    dmake Observations

    1. fork/exec to spawn change trivial.
      #if defined (__OPEN_VM)
         inherit.flags=0;
         for (n_args = 1; argv[n_args] != 0; n_args++);
         switch ( pid = spawnp((const) argv[0], 0, NULL,
                               &inherit, (const) argv, environ) )
         {
          int   wid;
          int   status;
      

      case -1 : perror("Call to spawn() failed"); Handle_result(-1, ignore, _abort_flg, target); return(-1);

      default: /* parent */ _add_child(pid, target, ignore, last); } #else switch( pid=fork() ){ int wid; int status;

      case -1: /* fork failed */ Error("%s: %s", argv[0], sys_errlist[errno]); Handle_result(-1, ignore, _abort_flg, target); return(-1); ; case 0: /* child */ execvp(argv[0], argv); Continue = TRUE; /* survive error message */ Error("%s: %s", argv[0], sys_errlist[errno]); kill(getpid(), SIGTERM); /*NOTREACHED*/

      default: /* parent */ _add_child(pid, target, ignore, last); } #endif

    2. access(fn, 0) is not acceptable, you must use access(fn, F_OK) or access(fn, 8);
    3. I needed to modify routines that provided support for:
    4. Worked after about 2 hours of effort:
      dmake -?
      Usage:
      
      dmake [-P#] [-{f|K} file] [-{w|W} target ...] [macro[!][[*][+][:]]=value...]
            [-v{cdfimt}] [-ABcdeEghiknpqrsStTuVxX] [target ...]
      

    Highly recommended package if you are getting into the porting business. Considering it's been developed at U.Waterloo home of the S&U it's a shame it didn't get used instead.

    pgp Observations

    1. No fork conversions;

    2. Reliance on XPG4 calls -

      I wrote my own support code for these API calls (trivial).

    3. ttycbreak - change tty characteristics - non-canonical input. pgp generates keys based on a random number. It determines this random number by timing the interval between key strokes. On a UNIX box this is no problem, but under OpenEdition VM the timing characteristics will be very different. Characters will only be received by the application when the enter key is hit. The interval between individual characters will be a function of:

      Not the original intent of the routine but effective nonetheless.

    I now have a working pgp application:

    -rw-------   1 neale    system       162 Dec 21 09:11 pubring.pgp
    -rw-------   1 neale    system        24 Dec 21 09:58 randseed.bin
    -rw-------   1 neale    system       415 Dec 21 09:11 secring.pgp
    

    java Observations

    I originally started porting the alpha version late last year. The make files were so horrendous and complex I did not get very far with the project. In fact, this was the impetus for me to obtain dmake as it supported many of the extensions to make the java developers were exploiting.

    Subsequently, I have recently downloaded the beta version. This has much saner looking make files. However, I've managed to shake a bug out of the shell and utilities which is still under investigation with IBM.

    A copy of the java directory structure is included in Appendix E. "Java Directory Structure" for your interest. The C code itself doesn't look like it will hold too many surprises (fingers crossed).

    xsb Observations

    1. No fork/spawn conversion required.

    2. Reliance on XPG4 calls -

    3. The package comes with the Prolog source and object files. The compiled C code allows you to process these object files. However, the prolog code has a lot of ASCII character set reliances. Therefore, I had to:

      1. Convert as much of the object file from ASCII to EBCDIC. This required me to understand the layout and content of the object files. I guessed right and converted the files after a couple of days work. The files still contained tokens that referred to ASCII symbols but they were sufficient to allow me to bring the interpreter up.

      2. Port the application to a Sun system (courtesy of a local university). Where I changed the Prolog source code to reflect the EBCDIC requirements and re-compiled these files (only 2 files). I then moved these object files back to OpenVM.

      3. Recompile all the Prolog source under OpenVM to ensure all was well.

    Prolog compiler and interpreter now work perfectly:

    [test.P]
    male(tom).
    male(joshua).
    male(bill).
    male(bart).
    smoker(guiseppe).
    smoker(tom).
    smoker(bart).
    vegitarian(tom).
    sophie_could_date(X) :-
       male(X), not(smoker(X));
       vegitarian(X).
    vegos   :- vegitarian(X), writeln(X), fail; true.
    smokers :- smoker(X), writeln(X), fail; true.
    males   :- male(X), writeln(X), fail; true.
    dates   :- sophie_could_date(X), writeln(X), fail; true.
    

    xsb -i XSB Version 1.4.1 (94/11/21) [sequential, single word, optimal mode] | ?- [test] [test loaded] yes | ?- smokers. guiseppe tom bart yes | ?- dates. joshua bill tom yes | ?- halt. End XSB (cputime 0.70s, elapsetime 71.04s)

    httpd Observations

    1. Many fork/exec spawn conversions:
      #ifndef __OPEN_VM
          if ((pid = fork()) == -1)
              die(SERVER_ERROR,"Could not fork a new process",*out);
          if (!pid)
          {
           char *argv0;
      

      close(p[0]); signal(SIGHUP,SIG_DFL); if (tfd != STDIN_FILENO) { dup2(tfd,STDIN_FILENO); close(tfd); } if (p[1] != STDOUT_FILENO) { dup2(p[1],STDOUT_FILENO); close(p[1]); } error_log2stderr(); if (!(argv0 = strrchr(decrypt,'/'))) argv0 = decrypt; else ++argv0; if (execlp(decrypt,argv0,pem_user,(char *)0) == -1) die(SERVER_ERROR,"Could not exec decrypt command",*out); } #else fd_map[STDIN_FILENO] = tfd; fd_map[STDOUT_FILENO] = p[1]; fd_map[STDERR_FILENO] = logfd; /*---------------------------------------------------------*/ /* Indicate that some signals should be set to default */ /*---------------------------------------------------------*/ inherit.flags = SPAWN_SETSIGDEF; /*---------------------------------------------------------*/ /* Clear set of signals to be defaulted & add SIGHUP */ /*---------------------------------------------------------*/ sigemptyset(&inherit.sigdefault); sigaddset(&inherit.sigdefault, SIGHUP); if (!(argv0 = strrchr(decrypt,'/'))) argv0 = decrypt; else ++argv0; /*---------------------------------------------------------*/ /* Set up program arguments for child process */ /*---------------------------------------------------------*/ child_args[0] = argv0; child_args[1] = pem_user; child_args[2] = NULL; /*---------------------------------------------------------*/ /* Spawn a new process */ /*---------------------------------------------------------*/ pid = spawnp(decrypt, 3, fd_map, &inherit, child_args, environ); if (pid == -1) die(SERVER_ERROR,"Could not spawn the decrypt program", *out); #endif

    2. One fork call needed to be converted to POSIX threads.

    3. XPG4 reliances.

    I haven't progressed very far with this one. The motivation to do so has lessened with the announcement of Web Servers from Beyond and Sterling.

    gnu make Observations

    1. Invoke configurator:
      CC=c89 CFLAGS=-O2 ./configure
      

      You may have to make manual alterations to config.h to reflect the facilities OpenEdition VM has or hasn't. In addition, the file make.h needs to have the following line added to indicate OpenEdition is POSIX compliant:

      #if !defined (POSIX) && defined (_OPEN_VM) && defined (_POSIX_SOURCE)
      #define POSIX
      #endif
      

      By making changes to the configuration files you automatically include or exclude code OpenEdition won't handle.

    2. fork/exec to spawn change trivial - code for MSDOS spawn already there. Simply add the #include <spawn> and struct inheritance inherit; statements.

    3. ctime() function needs to be defined:
      #ifndef __OPEN_VM
        extern char *ctime ();
      #endif
      

      then replace fork()/exec() with spawn:

      # ifndef __OPEN_VM
        pid = vfork ();
        if (pid < 0)
          perror_with_name (error_prefix, "fork");
        else if (pid == 0)
          child_execute_job (0, pipedes[1], argv, envp);
      # else
        inherit.flags = 0;
        pid = spawnp((const) argv[0], 0, NULL, &inherit,
                     (const) argv, (const) envp);
        if (pid < 0)
          perror_with_name (error_prefix, "spawn");
      # endif
      

    4. Needs ar.h. I found this on the old RT PC and copied it over to VM

    5. Worked after about 4 hours effort.

    Highly recommended package if you are porting GNU type packages.

    perl Observations

    1. Used as is from
      ftp://lscftp.kgn.ibm.com/pub/oe/toys/perl.pax.Z
      

      Programs have already been compiled so they just need to be linked via make -f makefile;

    2. Can specify #undef HAS_FORK and fork code will be bypassed. You will have to supply do_spawn code (examples in os2 and vms subdirectories).

    Sample perl program and invokation:

    test.pl
    $* = 1;
    undef $/;
    $input = <>;
    @records = split(/^--\n/, $input);
    print @records + 0, "\n";
    print $records[0], "\n";
    

    test.data foo -- bar -- baz --

    ./perl test.pl test.data 3 foo [neale - /home/neale/PERL]>

    gzip Observations

    1. Works straight out of the box!
      CC=c89 ./configure
      gnumake
      gnumake install
      

    gcc Observations

    1. __STDC__ || __OPEN_VM to get <stdarg.h>

    2. Re-write functions to prevent promoting of arguments:
      #ifdef __OPEN_VM
      builtin_function(enum built_in_function function)
      #else
      builtin_function(function)
      enum built_in_function function;
      #endif
      

    3. fork() spawn()

    4. sbrk()

    5. rindex()

    6. index()

    7. strdup()

    8. BISON/FLEX

    9. DEF STOR 64M

    10. Copy 'H' files to /usr/include

    11. Assembler
      #include <stdlib.h>
      #include <spawn.h>
      main(int argc, char **argv)
      {
       int status, i_arg;
       char command-1024- = "cms CASM";
      

      for (i_arg = 1; i_arg < argc; i_arg++) { strcat(command, " "); strcat(command, argv-i_arg-); } status = system(command); exit (status); } ______________________________________________________________________________ /* Assemble a file residing in BFS */ address command parse arg Args parse var Args '-o' ObjName Source 'EXEC OPENVM QUERY DIR (STACK' 'PIPE (name BLD:PATH)', '| stack', '| take 1', '| spec w3 1', "| strip both str /'/", '| spec w1 1 $/'STRIP(ObjName)'$ n', '| var PathName' 'PIPE (name BLD:ASM)', '| <' Source, '| untab -5', '| pad 80', '| > CASM CMSUT2 A3 F' 'FILEDEF SYSIN DISK CASM CMSUT2 A3' 'FILEDEF SYSPUNCH DISK CASM CMSUT3 A3' 'HLASM (PRINT' RetC = Rc 'PIPE (name BLD:OBJECT)', '| disk CASM CMSUT3 A3', '| >' PathName 'FILEDEF SYSIN CLEAR' 'FILEDEF SYSPUNCH CLEAR' exit RetC

    ircd Observations

    bind Observations

    inn Observations

    1. #include <vmsock><string><arpa/inet>

    2. rnews: fork to spawn

    3. givesocket/takesocket

    4. iconv routines

    5. writev

    6. rc.news use ${INND} else change inndstart.c/innd.c to use give/take

    7. hostname utility for rc.news

    8. bypass setgroups in inndstart

    awf Observations

    1. Regular expression:
      if ($0 E. /[.!?:][C.]C.)'"*]*$/) --> if ($0 E.
      /[.!?:][C.]C.)'"*]*$/)
      

    General Observations or When UNIX <> UNIX

    Whoever said that an open system was what ever system you were selling was close to the truth. Each of the above packages have so much conditional compilation code according to the target system that it's almost funny. The dmake package, for example, has subdirectories containing system dependent code for:

    The parameters that the various C compilers support is also a source of work. Many support -O2 or -O4 to indicate optimization levels whereas c89 (currently) only supports -O. In addition, if I want a compiler listing from c89 I have to specify -V. However, this also gives me the include files and the assembler listing which I have to wade through (it also changes the flag setting that results in the printing of every damn informational message it can think of).

    Some other Applications

    I downloaded the following tools from OpenEdition MVS ftp site (lscftp.kgn.ibm.com). Most of these were ported or written by John Pfuntner (pfuntner@vnet.ibm.com).

    banner
    Print banner pages. The author alludes to the ASCII-EBCDIC problems you can encounter when porting applications:
    The basic challenge to overcome in this port was its dependencies upon the ASCII character set. There is an array for each character that tells the utility how to "print" the character. The array is indexed by the character being printed. I first took a very naive approach by converting the data as soon as it was encountered but as I recall, this produced unexpected results. As it turned out, I had to move where the translations occurred later on in the code. The result is that you get the characters coming out exactly as you want them to.

    dirsize
    Tool to traverse directory trees and report the amount of data in bytes in the tree. This is more easily shown in examples:
      $ dirsize /bin
        /bin/IBM contains 11005503 bytes
      /bin contains 11005503 bytes
      ------------------------------------------------
        /u/pfuntnr/bin contains 1331712 bytes
        /u/pfuntnr/dbx contains 0 bytes
          /u/pfuntnr/external/dirsize contains 6519 bytes
          /u/pfuntnr/external/ifind contains 7327 bytes
          /u/pfuntnr/external/omvstape contains 54962 bytes
          /u/pfuntnr/external/pschart contains 4238 bytes
          /u/pfuntnr/external/stat contains 6644 bytes
        /u/pfuntnr/external contains 82799 bytes
        /u/pfuntnr/oldnotes contains 4945920 bytes
          /u/pfuntnr/roast/h contains 0 bytes
        /u/pfuntnr/roast contains 0 bytes
        /u/pfuntnr/temp contains 30072 bytes
        /u/pfuntnr/tmp contains 0 bytes
          /u/pfuntnr/toronto/h contains 0 bytes
        /u/pfuntnr/toronto contains 0 bytes
      /u/pfuntnr contains 6797194 bytes
    

    The amount of data in any directory is the total of all the files in the directory plus the amount of data in any of subdirectories contained in the directory (a recursive definition). Indentation is used to indicate subdirectories. Files are only counted once, no matter how many links they have. This means that even though /bin/IBM/FSUMSSH and /bin/sh are links to the same file, the size of the file is only counted once.

    ifind
    Tool that can be used to find files in a filesystem that share the same data. A file can be known by several different links (sometimes called a "hard link" to distinguish them from "symbolic links) and they all point to the same "inode" - a number which uniquely identifies the file in the filesystem.

    ovmtape
    (omvstape) Input and output support of tape devices.

    pschart
    Tool that will display processes in a different way than the regular ps utility does. You may have noticed that it is often difficult to follow parent/child relationships in the output from 'ps'. pschart displays processes using indentation to convey the parent/child relationships:
    $ pschart
      pid=393219 user=PFUNTNR cmd=
        pid=458756 user=PFUNTNR cmd=sh -L
          pid=5898250 user=PFUNTNR cmd=pschart
          pid=1310725 user=PFUNTNR cmd=beeper
    There were no zombie processes
    

    stat
    Tool to display information about files you specify on the command line. It basically reports all the information that the stat() function returns:
      $ stat stat.c
      Info for 'stat.c':
        The absolute pathname is '/u/pfuntnr/external/stat/stat.c'
        It is a regular file
      inode: 12044, device id: 7 (OMVS.HFS.PFUNTNR)
      Permissions: User: RW, Group: R, Other: R
      There are 1 links to this file
      Owning user: PFUNTNR (3)    Owning group POSIX (1)
      The file has 6644 bytes
      Created:  Sat Jul 30 1994 10:30:24 AM EDT
      Accessed: Sat Jul 30 1994 10:30:24 AM EDT
      ctime:    Sat Jul 30 1994 10:30:24 AM EDT
      mtime:    Sat Jul 30 1994 10:30:24 AM EDT
    

    Future Requirements

    fork

    Initially, when I was considering what missing pieces I'd like IBM to provide I believed fork() was not the number one priority. However, subsequent porting exercises have shown me how pervasive fork is. While it might be better in terms of performance and aesthetics to convert to spawn() the truth is there is vast suite of programs portable to VM/ESA requiring programming effort. This effort can be trivial (in the case of the fork() - exec() paradigm) or it can be extensive (in cases where fork() is used for multitasking purposes).

    I think it is in everyone's interest for fork() to be supported. If it's quick, dirty, and inefficient to start with then so be it. Warn people in big black letters that this is the case but get something out there which will reduce the amount of effort required to port an application.

    XPG4 Compliance

    Perhaps my desire for XPG4 compliance will not be met: there are some compelling reasons both for and against attempting this. Some related to technical issues such as character mode support and others are business issues. However, I believe there is a lot IBM can do which won't require massive resources.

    What I have found in my porting endeavours is that while fork() to spawn() conversion is required it is expected: i.e. you go into the porting exercise prewarned. However, it is annoying to come across unsupported calls that require you to do additional programming: e.g. gettimeofday().

    There are many XPG4 calls that are not reliant on system interfaces but are implemented in the library such as random() and getrusage(). Such routines should be made available.


    Conclusion

    Perhaps my feelings about OpenEdition and the porting exercise can be summed up in a report card style.

    Quality
    A+ - Well constructed, robust, and reliable

    Integration
    A+ - CMS and OpenEdition sit together naturally and complement each other. This is true of the SFS/BFS/ADSM/DFSMS interoperability.

    Function
    B- - a good start but needs to build on what's there

    Tools
    A- - everything I needed to do was facilitated by the tools provided. More extensions to make would be appreciated.

    Potential
    A - if given the right guidance, resources, and attention it will be an excellent workhorse.

    Challenges

    The challenge for VM development is to build on the base they have established. Much will be or has been said about DCE in other places but the major strengths of the OpenEdition platform will be realised when DCE is fully exploited.

    The other challenge for IBM is to get the 3rd party developers active and to support them. The MVS OpenEdition home page has a lot of useful information including technical data, downloadable tools, and vendor promotion (see "OpenEdition MVS Software Application Providers"). Software only lives as long as people are interested in using it.

    The challenge for third party vendors is to recognise that there is a market now accessible to them. Outside of OpenEdition we've seen vendors such as Beyond Software and Sterling fill the niche created by the lack of a VM Web Server. OpenEdition has created more niches for vendors to provide a lot of added value to VM installations. It is my hope they will start to take up these opportunities.

    My personal challenge has been issued by Rob van der Heij:

    Would it be a good idea to do a contest for that; you port an existing application to VM using the Posix support, me trying to implement it with pipes?

    What about IRC client and server code, I guess the programs are available somewhere on the net. If we do a contest somebody should set the rules and the targets, think Melinda would be a great judge ;-)

    Just a few things I can think of:

    Rob

    Let the contest begin!


    Appendix A. OpenVM Commands


    CMS Shell Function
    openvm set dir cd  Change a working directory  
    openvm owner chgrp  Change the group owners of a file or directory. To use this command you must be a super-user or the owner of the file or directory.  
    openvm permit chmod  Change access permission to a file or directory. To use this command you must be a super-user, the owner of the file or directory, or have appropriate privileges.  
    openvm owner chown  Change the owner or group of a file or directory. To use this command you must be a super-user.  
    openvm getbfs
    openvm putbfs
    cp  Copy a file  
    xedit ed  Create or edit text in a file  
    openvm create link ln  Link another name to a file (in addition to its original name)  
    openvm listfile ls  List the files in a directory  
    openvm create directory mkdir  Create a directory. The mkdir command has an option for creating intermediate directories in a pathname.  
    - mkfifo  Make a named pipe (FIFO special file).  
    - mknod  Make a character special file or a named pipe (FIFO special file). Super-user required.  
    openvm rename mv  Move a file from one directory to another directory, or rename a file or directory.  
    openvm query directory pwd  Display working directory  
    openvm erase rm  Remove (erase or delete) a file from a directory.  
    openvm erase rmdir  Remove (erase or delete) a directory empty of files.  
    openvm mount -  Add a mountable BFS or BFS subdirectory tree to the file hierachy.  
    openvm create extlink -  Create a BFS pathname to be used to reference a file or other data that resides outside of the BFS.  
    openvm create symlink ln  Create a BFS pathname to be used to reference an object residing in one BFS using a pathname in the same or another BFS.  
    openvm query link ls  Display information associated with symbolic or external links.  
    openvm set mask umask  Define the file creation mask to be used when creating a BFS object.  
    openvm query mask umask  Display the file creation mask in effect.  
    openvm query mount -  Display what is mounted in your hierachy  
    openvm unmount -  Remove a BFS or BFS subdirectory tree from your hierachy.  

    Appendix B. A Make Primer

     make (-EeinpqrstuVvx) (-k|-S) (-c dir) (-f file) ...
     (macro definition ...) (-D macro definition ...) (target ...)
    

    Targets

    A target is normally a file that you want to ensure is up to date with the files on which it is dependent (the prerequisites). make updates all targets that are specified on the command line. If you do not specify any target, make updates the targets in the first rule of the makefile. A target is out of date if it is older than any of its prerequisites (based on modification times) or if it does not exist.

    To update a target, make first recursively ensures that all the target's prerequisites are up to date, processing them in the order in which they appear in the rule. If the target itself is out of date, make then runs the recipe associated with the target. If the target has no associated recipe, make considers it up to date.

    Macros

    Macro definitions can appear on the command line or in makefiles. Macro definitions on the command line overrule definitions in makefiles; makefile definitions never overrule command-line definitions. Macro definitions on the command line may not have any white space between the macro name and the = character.

    Macro definitions may take several forms.

    macro = string
    
    is the usual form. If string contains macro references, make does not expand them when the macro is defined, but when the macro is actually used.
    macro := string
    
    expands macros inside string before creating macro.
    macro += string
    
    adds string to the previous value of macro.

    Comments

    Comments begin with the pound (#) character and extend to the end of the line. make discards all comment text.

    Makefile Contents

    Inside makefiles, you can split long lines over several lines of text. To do this, put a backslash (\) at the very end of the line. You can use this technique to extend comments as well as recipe lines and macro definitions, for example.

    If a rule or macro definition must contain a # character, use \#; otherwise, make mistakes the # for the beginning of a comment. Also, $$ stands for $.

    File names that contain a colon must always be enclosed in quotes, as in:

      "a:target" : "a:prereq"
    

    Rules

    The general format of a rule is:

    targets (attributes) ruleop (prerequisites) (;recipe)
    {<tab> recipe}
    
    where the items enclosed in square brackets are optional. (This is just a documentation convention; you do not actually enter the square brackets.) The parts of the rule are described as follows:

    targets
    One or more target names.

    attributes
    A list, possibly empty, of attributes to apply to the list of targets.

    ruleop
    A separator string that separates the target names from the prerequisite names and may also affect the processing of the specified targets.

    prerequisites
    A list of zero or more names on which the specified targets depend.

    recipe
    May follow on the same line as the prerequisites, separated from them by a semicolon. A recipe is a group of commands following a target, which specifies how to make that target. If a recipe is present, make takes it as the first in the list of recipe lines defining how to make the named targets. Additional recipe lines can follow the first line of the rule. Each such recipe line must begin with a tab character.

    The possible rule operators are listed as follows:

    targets : prereqs
    Is a simple rule definition. You can specify only one set of rules for making a target, except within metarules. In metarules, you can specify more than one recipe for making the target. If a target has more than one associated metarule, make uses the first metarule that matches.

    targets :! prereqs
    Executes the recipe for the associated targets once for each recently changed prerequisite. Ordinarily, make runs the recipe only once, for all out-of-date prerequisites at the same time.

    targets :^. prereqs
    Inserts the specified prerequisites before any other prerequisites already associated with the specified targets.

    targets :- prereqs
    Clears the previous list of prerequisites before adding the new prerequisites.

    targets :: prereqs
    Is used for multiple rules applying to the same targets. Each rule can specify a different set of prerequisites with a different recipe for updating the target. If a target is out of date with respect to any of its prerequisites, make remakes the target using all the recipe lines associated with the rules that mention those prerequisites.

    targets :| prereqs
    Is used in metarules. It tells make to treat each metadependency as an independent rule. For example:
    %.o :| %.c rcs/%.c /srcarc/rcs/%.c
            recipe...
    

    is equivalent to:

    %.o : rcs/%.c
            recipe...
    %.o : /srcarc/rcs/%.c
            recipe...
    

    You can follow the first line of a rule with any number of recipe lines. Each of these must begin with a tab character.

    Conditionals

    You specify the conditional expression as follows:

       .IF expression
       ... if text ...
       .ELSE
       ... else text ...
       .END
    
    or:
       .IF expression
       ... if text ...
       .ELSIF expression2
       ... elsif text ...
       .ELSE
       ... else text ...
       .END
    

    Portability

    POSIX.2, UNIX systems.

    The following features of make are enhancements to POSIX.2:

    Related Information

    S. I. Feldman, Make--Program for Maintaining Computer Programs, Software--Practice and Experience 9 (no. 4, April 1979):225-65 (Bell Labs, Murray Hill, NJ)


    Make file for XSB

    #------------------------------------------------------------------------
    #
    #	File			: XSB/emu/Makefile
    #	Authors			: Jiyang Xu, Terrance Swift, Kostis Sagonas
    #	Last updated		: November 21, 1994
    #
    #------------------------------------------------------------------------
    #
    #=======================================================================
    # XSB Version Date:  94-11-21 (but it has to be given in hexadecimal).
    #=======================================================================
    #
    DATE = 0x5e0b15
    #
    #=======================================================================
    # Directory where XSB will be installed.
    #=======================================================================
    #
    DIR=/home/neale/XSB
    #
    #=======================================================================
    # Name of the executable file that will be created by this make
    #	We suggest the use of xsb.
    #=======================================================================
    #
    EXECUTABLE=xsb
    #
    #=======================================================================
    # Architecture (Type of machine):
    #	SUN, SOLARIS, NeXT, linux, SGI, HP300, DECstation, AMIGA, IBM,
    #	SEQUENT (not tested yet), or SONY_NEWS.
    #=======================================================================
    #
    MACHINE=VMESA
    #
    #=======================================================================
    # C compiler option -- please choose one of the following two:
    #       cc;
    #	gcc
    # and consult the debugging mode and the warning below.
    #=======================================================================
    #
    CC=c89
    #
    #=======================================================================
    # Debugging mode -- please choose one of the following:
    #	-DOLDTPROFILE;
    #	-O2 [-DTRACING];
    #	-g [-DDEBUG] [-DTRACING];
    #	-O2 -DPROFILE
    # where the []s denote optionality.
    #
    # WARNING !!!
    #	When making the emulator with the "-O*" options the temporary
    #	space available may not be sufficient. For example on our SPARC
    #       that had very little /tmp space the "-O*" option cannot be used
    #	for the file "main.c".  In your system depending on the amount
    #	of /tmp space of your machine there may be other files or you
    #	may not have any problems at all.
    #	If you are using the SUN C compiler, and have disk space in one
    #	of your directories, say "dir", add the following option to the
    #	entries of the files that cannot be compiled:
    #		-temp=dir
    #	If you are using the Gnu C compiler, consult its manual pages
    #	to find out how you can change the default tmp dir or how you
    #	can use pipes to avoid the use of tmp space.
    #=======================================================================
    #
    DEBUGOPTION=-DTRACING
    DEBUGOPTION4=-DTRACING
    #
    #=======================================================================
    # All of the above can be summarized as follows.
    #=======================================================================
    #
    CFLAGS = $(DEBUGOPTION) -D$(MACHINE)
    #
    CFLAGS4 = $(DEBUGOPTION4) -D$(MACHINE)
    #
    

    OBJS = init.o main.o debug.o subp.o loader.o dis.o inst.o system.o \ auxlry.o memory.o load_seg.o trace.o psc.o token.o builtin.o \ dynload.o cutils.o function.o cinterf.o xsb_error.o biassert.o \ trie_utils.o drutrsg.o druttod.o util.o

    WAMDEF = config_make.h cell.h register.h inst.h flags.h BDGDEF = binding.h deref.h

    # #======================================================================= # Linking command: # SUN : $(CC) -o $(EXECUTABLE) $(OBJS) -lm -N # SOLARIS : $(CC) -o $(EXECUTABLE) $(OBJS) -lm -lnsl -ldl # NEXT : $(CC) -o $(EXECUTABLE) $(OBJS) -lm # linux : $(CC) -o $(EXECUTABLE) $(OBJS) -lm # SGI : $(CC) -o $(EXECUTABLE) $(OBJS) -lm # HP300 : $(CC) -o $(EXECUTABLE) $(OBJS) -lm # DECstation : $(CC) -o $(EXECUTABLE) $(OBJS) -lm # AMIGA : $(CC) -o $(EXECUTABLE) $(OBJS) -lm # IBM : $(CC) -o $(EXECUTABLE) $(OBJS) -lm # SEQUENT : $(CC) -o $(EXECUTABLE) $(OBJS) -lm -lpps # SONY_NEWS : $(CC) -o $(EXECUTABLE) $(OBJS) -lm #======================================================================= # $(EXECUTABLE): $(OBJS) $(CC) -o $@ $(OBJS)

    clean: /bin/rm *.o

    $(OBJS) : auxlry.h

    init.o: init.c $(WAMDEF) psc.h memory.h loader.h choice.h auxlry.h register.h \ xmacro.h $(CC) -c $(CFLAGS4) init.c -DDATE=$(DATE) -DDIR=\"$(DIR)\" \ -DEXECUTABLE=$(EXECUTABLE) -DCC=\"$(CC)\"

    main.o: main.c $(WAMDEF) $(BDGDEF) memory.h emudef.h sig.h heap.h unify.i \ choice.h loader.h emusubs.i auxlry.h psc.h register.h xmacro.h \ slg_insts.i subinst.h tries.i xsb_error.h $(CC) -c $(CFLAGS) main.c

    debug.o: debug.c $(WAMDEF) $(BGDDEF) psc.h memory.h auxlry.h register.h \ choice.h xmacro.h $(CC) -c $(CFLAGS4) debug.c

    subp.o: subp.c $(WAMDEF) $(BDGDEF) psc.h heap.h memory.h unify.i token.h \ choice.h binding.h auxlry.h register.h sig.h special_unify.i xmacro.h $(CC) -c $(CFLAGS4) subp.c

    loader.o: loader.c config_make.h psc.h loader.h flags.h auxlry.h $(CC) -c $(CFLAGS4) loader.c

    dis.o: dis.c $(WAMDEF) psc.h loader.h memory.h auxlry.h xmacro.h $(CC) -c $(CFLAGS4) dis.c

    load_seg.o: load_seg.c $(WAMDEF) memory.h psc.h loader.h auxlry.h \ register.h xmacro.h $(CC) -c $(CFLAGS4) load_seg.c

    inst.o: inst.c inst.h auxlry.h subinst.h $(CC) -c $(CFLAGS4) inst.c

    psc.o: psc.c psc.h loader.h flags.h xmacro.h config_make.h $(CC) -c $(CFLAGS4) psc.c

    trace.o: trace.c $(WAMDEF) memory.h choice.h auxlry.h register.h $(CC) -c $(CFLAGS4) trace.c

    memory.o: memory.c config_make.h $(CC) -c $(CFLAGS4) memory.c

    token.o: token.c token.h auxlry.h config_make.h $(CC) -c $(CFLAGS4) token.c

    dynload.o: dynload.c config_make.h inst.h psc.h auxlry.h dyncoff.i $(CC) -c $(CFLAGS4) dynload.c -DEXECUTABLE=\"$(EXECUTABLE)\"

    cinterf.o: cinterf.c cinterf.h auxlry.h cell.h register.h psc.h flags.h heap.h \ deref.h binding.h choice.h config_make.h $(CC) -c $(CFLAGS4) cinterf.c

    builtin.o: builtin.c $(WAMDEF) $(BDGDEF) psc.h loader.h token.h xmacro.h \ heap.h memory.h subinst.h std_pred.i xsb_error.h $(CC) -c $(CFLAGS4) builtin.c

    biassert.o: biassert.c $(WAMDEF) $(BDGDEF) psc.h loader.h heap.h token.h \ memory.h subinst.h cinterf.h xsb_error.h $(CC) -c $(CFLAGS4) biassert.c

    auxlry.o: auxlry.c auxlry.h config_make.h $(CC) -c $(CFLAGS4) auxlry.c

    system.o: system.c mysyscall.h config_make.h $(CC) -c $(CFLAGS4) system.c

    cutils.o: cutils.c auxlry.h $(WAMDEF) $(BDGDEF) memory.h choice.h psc.h xmacro.h $(CC) -c $(CFLAGS4) cutils.c

    function.o: function.c auxlry.h cell.h register.h memory.h deref.h config_make.h $(CC) -c $(CFLAGS4) function.c

    xsb_error.o: xsb_error.c auxlry.h $(WAMDEF) xsb_error.h $(CC) -c $(CFLAGS4) xsb_error.c

    trie_utils.o: trie_utils.c $(WAMDEF) xmacro.h $(CC) -c $(CFLAGS4) trie_utils.c

    util.o: util.c $(CC) -c $(CFLAGS4) util.c

    std_pred.i: cell.h

    dyncoff.i: auxlry.h inst.h psc.h


    Appendix C. OpenEdition MVS


    List of the Single UNIX Specification commands

    Commands in bold print are Single UNIX Specification commands that were not supported in releases prior to MVS 5.2.2. inetd and cron are daemons. Additional (non-standard) commands added by OpenEdition MVS are identified by OE following the command.


    OpenEdition MVS Software Application Providers

    The following list shows many of the application providers who have announced support for OpenEdition MVS. (Products indicated may be trademarks or registered trademarks of their respective companies.)

    Note: Unix applications that are written to Oracle interfaces are now portable to MVS. Users may access the Oracle7 database on MVS through OpenEdition MVS.


    Appendix D. How to Speak 'Strine

    (Courtesy of www.twi.ch & http://australia-online.com/diction.html)

    If you want to pass for a native try speaking slightly nasally, shortening any word of more than two syllables and then adding a vowel to the end of it, making anything you can into a diminutive (even the Hell's Angels can become mere bikies) and peppering your speech with as many expletives as possible.


    Common Words

    Arvo
    Afternoon. "The Sarvo" means this afternoon, as in "Seeya the sarvo". On Xmas morning a lot of people go to the beach to test out their new prezzies. But by the early arvo, they're at home stuffing themselves with Chrissie din-dins!

    Avagoodweegend
    Classic Aussie farewell comparable to American TGIF, basically means Have a good weekend!

    Bend the Elbow
    To have a drink - pretty well self explanatory!

    Bickie
    Rhymes with "sticky". Literally means a biscuit, but Aussie bickies are more like American cookies, and American biscuits are more like Australian scones (pronounced like the "Fonz"!)... go figure!

    Bloody
    Universal epithet the great Australian adjective. Used to emphasize any point or story. Hence "bloody beauty"(bewdy!) or "bloody horrible" or even "absa-bloody-lutely"!

    Bludger
    Lazy bastard definitely an insult in Oz. Originally thought to be someone who lives off the earnings of a call girl. In conversation, the verb 'to bludge' is most commonly used like the US 'to bum' a cigarette.

    Bob's Yer Uncle
    "Everything is OK" or "Everything's Sweet" or "Going according to plan". Similar phrase includes: "She's apples!"... Bob may refer to Australia's long-serving Prime Minister , Sir Robert "Bob" Menzies.

    Bon-Bons
    Christmas Crackers. Special party favours which are essential on the Christmas table. Shaped like big lollies, their contents always include a corny joke or riddle, small plastic toy and a paper party hat (which must be worn by all who attend Chrissie dinner, even guests)

    Bonzer
    Pronounced "bonsa" - grouse, great, excellent.

    Boxing Day
    December 26th. Public holiday and traditional outdoor barbie day. Major Aussie sporting events kick off on this day including the 'Sydney to Hobart' and the 'Melbourne Test".

    Chew the Fat
    To talk, engage in pleasant conversation, to have a chinwag.

    Chook
    Chicken. Often served barbecued at fancy turns(parties). If your hostess is befuddled and/or overcome by trying to do too many things at once, one might say she was "running around like a chook with its head cut-off!"

    Chrissie
    Christmas. By now you probably realize that Aussies like to shorten any words they can by adding an "o" or "ie" or "y". No bloke named Christopher would be called Chrissie, probably 'Chrisso' or 'Toffa'.

    Crack a Tinnie
    Means to open up a can of beer major pastime during Aussie silly season.

    Dial
    Face. If some says to put a 'smile on your dial' it basically means to cheer up, she'll be right, mate.

    Dunny
    The toilet, W.C., or bathroom. If someone busting to know where the dunny is, tell 'em to "follow their nose to the thunderbox".

    Esky
    Portable icebox or cooler - it's always a good idea to have one in the boot (trunk) of your car stocked with some cold ones (ice cold tubes) just in case the party's bar runs dry .

    Fair Dinkum
    Kosher, the real thing - as in "Fair Dinkum Aussie" (true blue Australian original). Often used by itself as a rhetorical question to express astonishment verging on disbelief ... "Fair Dinkum, mate?" (you' ve got to be kidding, haven't you?)

    Full as a Goog
    Completely filled with food (and drink). A 'Goog' is an egg (sometimes called a "googie egg").

    G'day
    Universal greeting, used anytime day or night, but never as a farewell. Pronounced "gud-eye", usually followed by "mate" (mite) or a typically strung-together "howyagoinallright" (= how are you today, feeling pretty good?)

    Good Onya
    Omnipresent term of approval, sometimes ironic, offering various degrees of heartfelt congratulations depending on inflection. Indispensible during Aussie smalltalk - substitute "really, oh yeh, aha, etc."

    Good Tucker
    Excellent food. After pigging out at Chrissie lunch, it's polite to tell your hosts how good the tucker was.

    Grouse
    Rhymes with "house" - means outstanding, tremendous. Can be applied universally to all things social ... "grouse birds (women), grouse band, in fact, grouse bloody gay and hearty (great party!)"

    Happy as Larry
    Fortunate, lucky. Who "Larry" is may forever be lost at the bottom of the Katherine Gorge.

    Holls
    Vacations or 'holidays'. Since most Aussies get at least 4 weeks 'holls' every year they usually take 2 or 3 of them at Chrissie which is our biggest family get together time (like US Thanksgiving).

    Hooroo
    Pronounced "who-roo"... means "see ya later", make sure you don't say g'day when meaning goodbye - it's a dead giveaway you're not a true blue Aussie battler!

    Laughing Gear
    Mouth. Common phrase is "Wrap your laughing gear around this one" i.e. Have a drink!

    Lolly
    A sweet or candy. But to "Do Your Lolly" means to get agitated and angry, similar to "Spit the dummie"

    Mate
    Friend, associate, or anyone you can't remember the name of

    Melbourne Test
    Game of cricket played by Australia's national cricko team versus visiting country usually starting on Boxing day. The game lasts for up to 6 days, and is watched religiously on the TV (like a 5 day Superbowl)

    Ocker
    Pronounced "ocka" - Typical uncultivated Australian, similar to American "redneck".

    Paralytic
    Extremely drunk. Not good form too early on at a bash (party) especially if you end up having an "up & under" or "chunder" (puking or throwing-up while inebriated).

    Plonk
    Wine. Never used to describe the other main alcoholic beverage at an Australian social occasion - beer, i.e. the golden nectar, throat charmer, ice cold tube, etc.

    Prezzie
    Present or gift. If you've been a good little vegemite you'll probably get lots of bonza prezzies.

    Pull Your head In!
    Use sparingingly, since this equates a rather annoyed "shut up & mind your own business". Only say this to the host if you know you're leaving or off like a bride's nightie (out of there!)

    Raw Prawn
    Not necessarily an uncooked shrimp! If someone says "Don't come the Raw Prawn with me, mate" it basically means "Don't try to fool me or rip me off" or "Rack off Noddy, you're being a tad offensive".

    Rels/Relos
    Relatives, The family members you probably only see every Christmas!

    Ripper
    Pronounced "rippa" means beaut, tippy-tops, grouse - that bloke named "Jack" in the old Dart(England) was certainly not ripper!

    Score a Bait
    To be included on the guest list or receive an invitation means you've scored a bait or 'cracked a bait'.

    Sheila
    Archaic term now only found in Paul Hogan movies

    Shout
    To shout means to buy the next round (of drinks usually), so if someone says "It's your shout, mate" don't get vocal, just buy a couple of tinnies (cans of beer) and remain sociable, the next few drinks are someone else's responsibility!

    Silly Season
    Traditional summer holiday period, kicking off in December and running through to our national holiday Australia Day, January 26th (similar to the US July 4th).

    Spit The Dummie
    A "dummie" is Australian for a child's pacifier. Your Hostess will not usually have cause to spit the dummie (completely lose her cool or go ballistic) if you and your mates can act like proper toffs (refined gentlemen) and enjoy the soiree!

    Starters
    Australian for Hors D'oeuvres or "appetizers". Aussies call their appetizers "entrees". Also your first drink of the day, hence the ubiquitous question heard throughout the Silly Season: "What's for Starters?" Also commonly called a "Heart Starter".

    Strewth
    Pronounced "sta-ruth" ... general exclamation of disbelief or shock. i.e. "Strewth, would ya hava go at that, then?!" (My goodness, can you believe what we're seeing!?)

    Sydney to Hobart
    World famous Australian ocean Yacht race, commences on Boxing Day in Sydney Harbour boats from all around the world race down the East Coast across Bass Strait to our Apple Isle, "Tassie" (Tasmania).

    The Go
    The "rage" or current trendy thing. The latest trend in clothing or whatever is described as "all the go!"

    Whinge
    Rhymes with "hinge" as in door! Means to complain incessantly or to "belly ache". Whingers are not fun to have around and definitely not likely to be asked back again to the next party. If you must whinge, keep it amongst your good mates!

    Some Translations


    You say We say
     AIX   IIX  
     Sequel (SQL)   ESS-Q-ELL  
     C-I-C-S   KICKS  
     D-O-S   DOS  

    Appendix E. Java Directory Structure