Porting UNIX Applications
Neale Ferguson
TABNSW-OPEN
May, 1996
TAB of NSW
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
Appendix D. How to Speak 'Strine
Appendix E. Java Directory Structure
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.
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:
- Port UNIX-type C language applications to MVS and possibly extend them to take advantage of unique MVS strengths
- Give workstation users access to MVS applications and data
- Use MVS as a large data server
- Use MVS for its access to large, high-speed tape devices for data-intensive applications
- Automatically back up and migrate hierarchical file systems
- Use MVS as a server for batch applications
- With OpenEdition DCE, access remote applications and data transparently
- Enterprises using OpenEdition MVS can use any combination of these applications.
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.
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
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=rmSimilarly, 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"
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.
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}
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.
Pass the command to CMS for processing.
Copy a file
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.
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).
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,
find / -name "*.c" -audit rwx=sf
find / -name "*.c" -audit 777
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"
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.
Move a file.
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.
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
These files can be used to tailor the shell for your:
# 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 #
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"
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 README1= 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
====>
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):
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:
find ./ -name "*.c" -type f ./javasrc/build/solaris/sun/javac/genconst.c ¢.C CEE5206S The signal SIGINT was received. [neale - /home/neale]>
find / -name "*.c" /etc/yylex.c /etc/yyparse.c /etc/samples/compile.c ¢.V CEE5220S The signal SIGQUIT was received. [1] + Done(152) 1314 Quit /bin/find [neale - /home/neale]>
find ./ -name "*.c" -type f ./javasrc/build/solaris/sun/javac/genconst.c ¢.Z [1] + Stopped (SIGTSTP) -type f [neale - /home/neale]> bg [1] -type f [neale - /home/neale]> ./javasrc/build/win32/java/java/mkopcodes.c kill %1 CEE5205S The signal SIGTERM was received. [1] + Done(143) -type f 2049 Terminated /bin/find
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:
I adopt the second course and use the profile script to override the VM defaults each time anyone enters the shell.
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
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 bfsSimilarly, 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:
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
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:
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.
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.
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).
#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
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.
I wrote my own support code for these API calls (trivial).
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
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).
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)
#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
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.
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.
#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
Highly recommended package if you are porting GNU type packages.
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;
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]>
CC=c89 ./configure gnumake gnumake install
#ifdef __OPEN_VM builtin_function(enum built_in_function function) #else builtin_function(function) enum built_in_function function; #endif
#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
if ($0 E. /[.!?:][C.]C.)'"*]*$/) --> if ($0 E. /[.!?:][C.]C.)'"*]*$/)
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).
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).
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 /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.
$ 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 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
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.
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.
Perhaps my feelings about OpenEdition and the porting exercise can be summed up in a report card style.
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:
- Same function as the original:
In the case of a IRC client/server you want them to be compatible with another brand (name one) client and servers.
- Look and feel for Unix folks (e.g. same admin. commands);
- Look and feel for VM folks (how well does it integrate?);
- Reliability (how does one measure that?);
- Performance (response times) and cost (cpu, storage, I/O);
- Initial porting effort and maybe maintenance work involved.
Rob
Let the contest begin!
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. |
make (-EeinpqrstuVvx) (-k|-S) (-c dir) (-f file) ... (macro definition ...) (-D macro definition ...) (target ...)
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.
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 = stringis 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 := stringexpands macros inside string before creating macro.
macro += stringadds string to the previous value of macro.
Comments begin with the pound (#) character and extend to the end of the line. make discards all comment text.
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"
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:
The possible rule operators are listed as follows:
%.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.
You specify the conditional expression as follows:
.IF expression ... if text ... .ELSE ... else text ... .ENDor:
.IF expression ... if text ... .ELSIF expression2 ... elsif text ... .ELSE ... else text ... .END
POSIX.2, UNIX systems.
The following features of make are enhancements to POSIX.2:
macroname := stringassigned macroname += stringassigned
"a:target" : "a:prerequisite"
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)
#------------------------------------------------------------------------ # # 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
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.
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.
(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.
You say | We say |
---|---|
AIX | IIX |
Sequel (SQL) | ESS-Q-ELL |
C-I-C-S | KICKS |
D-O-S | DOS |