IBM Corp 1993
370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370 370
C/370(TM) Compiler News
December 1993 Volume 1 Number 4
Welcome to the Fourth Issue of the C/370 Newsletter
This issue represents the last issue for 1993. We have managed to keep it going for a full year thanks to your support. It's been quite a year for all of us involved in bringing C/370 to you and 1994 appears to be just as busy. Thanks for using C/370 in 1993 and all the best from the C/370 Team to you in 1994.
In case you haven't heard the announcements, or seen the presentations from our friends in the Large Scale Systems Division (LSCD) on the exciting news for MVS/ESA OpenEdition Services, here's it is:
We announced in February 1993 that in March 1994, support for the MVS/ESA 4.3 OpenEdition Services would be provided with the then-current levels of the AD/Cycle ® C/370 Compiler and AD/Cycle Language Environment/370, or their equivalent.
What does this mean to you as a C programmer? Whether or not you are using C on other POSIX (TM) platforms, such as AIX/6000 or UNIX (TM) , you will see a number of benefits. We can't tell you all the details now, so stay tuned for further announcements. We can tell you that the MVS/ESA OpenEdition Services together with the C/370 support will provide you with the following highlights:
C is the language of the operating system programming interfaces defined by the Institute of Electrical and Electronics Engineers (IEEE (TM) ) Portable Operating System Interface (POSIX) standard. MVS/ESA OpenEdition will enable you to write C/370 code that exploits the new POSIX 1003.1 interfaces to the MVS/ESA environment. You will also be able to easily port applications from other platforms where these interfaces are already available.
Conformance to the American National Standards Institute/ International Organization for Standardization (ANSI/ISO 9899:1990 (1992) and the International Organization for Standardization/ International Electrotechnical Commission (ISO/IEC 9899:1990 (formerly ANSI X3J11.159-1989)) are the base for POSIX 1003.1 conformance.
Of course, C/370 will continue to support the development of applications for the traditional MVS environment. However, together with LE/370, facilities will be provided to enable traditional applications to access the new OpenEdition MVS services, and to enable OpenEdition applications to access traditional MVS services. You will be able to expand existing applications and access existing data from new OpenEdition MVS applications.
The MVS/ESA OpenEdition Shell and Utilities Feature and dbx Debugging Feature, will provide a familiar end-user environment and integrated development environment for the developing OpenEdition applications, with the AD/Cycle C/370 Compiler and the C runtime library of LE/370:
Will create executable files from C/370 source code, using the AD/Cycle C/370 Compiler.
Will provide debugging capabilities for use with AD/Cycle C/370 compiled programs, under the OpenEdition MVS environment. The AD/Cycle CODE/370 Debug Tool will remain the supported debugger for MVS applications not running under MVS/ESA OpenEdition.
The following table shows the maximum number of characters that are significant for identifiers in the different IBM C Products:
C Product Internal Identifiers External Identifiers C/Set++ (TM) 255 255 XL C/6000 250 250 C/400 255 255 C/370 255 255
The minimum length of internal identifiers is 250 and the minimum length of external identifiers is 250. Longer identifiers may be truncated and this truncation may make two identifiers look the same, even if you wanted them to be treated as distinct. If you want your code to be portable on IBM platforms, you should not give internal identifiers the same first 250 characters Similarly, no two external identifiers should have their first 250 characters the same.
Note: If you compile your C source code with the NOLONGNAME option on the 370, your external identifiers will be truncated to 8 characters and uppercased. You should always compile your code with the LONGNAME option if possible, since it is very difficult to write external identifiers that are all distinct in the first 8 characters.
If you need to refer to external identifiers with special characters that are not valid in identifiers (such as @), you can use the #pragma map directive. For instance, if you have an OS linkage function that is called @@FRED, you can code the following:
int __FRED(int, const char*); /* prototype for @@FRED */ #pragma map(__FRED, "@@FRED") #pragma linkage(__FRED, "OS")
If you want to refer to @@FRED you could code it as follows:
int x; x = __FRED(1, "Hello there");
We know that some of you have had problems entering and displaying characters such as the square bracket characters, [ and ], and the caret character, ^, for the host environment. If you use a programmable workstation or a 3270 terminal you can follow the documented procedures to map the keys on your keyboard to send the correct variant character hexadecimal values to the host system for the IBM compiler. Here are some hints and tips we have gathered to enter and display square brackets on a host editor.
If you are not sure whether your current keys generate correct hexadecimal values for the C/370 compiler and its library, you can use the following C program to show their hexadecimal values on the display. This program displays the hexadecimal values for the variant characters that your current setup uses and what the compiler and library expect.
The following sample program reads the ten characters from the input file MYFILE.DAT and displays the character values in hexadecimal notation. These ten variant characters are selected because they are syntactically important to the C compiler.
Create a file, MYFILE DAT A under VM/CMS or TSOid.myfile.dat under TSO. You must type them in MYFILE.DAT in this order on one single line and without spaces between them:
As follows
\][}{^~!#|
You can use the sample program to display the character values and then reset your environment to generate the codes as shown in the column expected by the compiler. Consult your system programmer for the code page that your installation uses. After re-editing your input file, you can run this program again. If you are running under TSO, the data file containing the ten variant characters is TSOid.myfile.dat.
#include <stdlib.h> void read_user_data(char *, int); void main() { char *user_char, *compiler_char; struct variant *compiler_var_char; int num_var_char, index; char *code_set; char *char_names[]={"backslash", "right bracket", "left bracket", "right brace", "left_brace", "circumflex", "tilde", "exclamation mark", "number sign", "vertical line"}; num_var_char=sizeof(char_names)/sizeof(char *); if ((user_char=calloc(num_var_char, 1)) == NULL) { printf("Error: Unable to allocate the storage\n"); exit(99); } read_user_data(user_char, num_var_char); /* managed to read the users' characters from the file */ code_set="default IBM-293"; compiler_char="\xe0\xbd\xad\xd0\xc0\x5f\xa1\x5a\x7b\x4f"; /* standard compiler code page */ printf("Compiler and library code page is : %s\n\n", code_set); printf(" Variant character values:\n"); printf(" %16s expected by compiler your current\n", ""); for (index=0; index<num_var_char; index++) printf(" %16s .: %X %X\n", char_names[index], compiler_char[index], user_char exit(0); } void read_user_data(char* char_array, int num_var_char) { FILE *stream; int num; if (stream = fopen ("myfile.dat", "rb")) if(!(num = fread(char_array, 1, num_var_char, stream))) { printf("Error: Unable to read from the file\n"); exit(99); } else { ;} else { printf("Error: Unable to open the file\n"); exit(99); } fclose(stream); return; }
Note:
After executing this program, you can use some of the following procedures to make sure that your special characters on the keyboard generate the hexadecimal values expected by the C/370 compiler.
If you know that the hexadecimal values of the square brackets that you key in are not those accepted by the C/370 compiler as square brackets, you can add SET INPUT commands in your XEDIT profile to convert the hexadecimal values of the keyed-in square brackets to ones that the C/370 compiler recognizes. This conversion will then happen during your XEDIT session. If you know that the square brackets that you key in are written correctly into the source file but are not displayed as square brackets you can add SET OUTPUT commands to correctly display the keyed-in square brackets during the XEDIT session. The following are three samples of XEDIT Profile changes that you can make to make sure that XEDIT writes out C/370 compiler hexadecimal values recognized as square brackets by the C/370 Compiler and displays the [ and ] characters correctly during the XEDIT session.
The following can be added to your XEDIT PROFILE if:
/*--------------------------------------------------------------------*/ /* Display: read x'AD' and x'BD' in the source file and display */ /* them as square brackets */ /*--------------------------------------------------------------------*/ /* */ /* XEDIT displays x'BA' which is a left square bracket when it */ /* encounters x'AD' in the source file */ Address COMMAND 'SET OUTPUT AD' 'BA'x /* Left square bracket */ /* */ /* XEDIT displays x'BB' which is a right square bracket when it */ /* encounters x'BD' in the source file */ Address COMMAND 'SET OUTPUT BD' 'BB'x /* Right square bracket*/ /*--------------------------------------------------------------------*/ /* Write: gets x'BA' and x'BB' from keyboard and writes them in the */ /* file as the hexadecimal values that the C/370 */ /* compiler recognizes as the left and right square */ /* brackets */ /*--------------------------------------------------------------------*/ /* */ /* XEDIT writes out x'AD' when it gets x'BA' from the keyboard */ Address COMMAND 'SET INPUT BA AD' /* Left square bracket */ Address COMMAND 'SET INPUT BB BD' /* Right square bracket*/ /* */ /*--------------------------------------------------------------------*/ /* Turn off text and APL characters for this XEDIT session */ /*--------------------------------------------------------------------*/ /* */ Address XEDIT 'SET TEXT OFF' Address XEDIT 'SET APL OFF' /* */ /*--------------------------------------------------------------------*/ /*Turn off text and APL characters at CP level for this logon session*/ /*--------------------------------------------------------------------*/ /* */ Address COMMAND 'CP TERMINAL TEXT OFF' Address COMMAND 'CP TERMINAL APL OFF'
The following can be added to your XEDIT PROFILE if:
/*--------------------------------------------------------------------*/ /* Display: read x'AD' and x'BD' in the source file and display */ /* them as square brackets */ /*--------------------------------------------------------------------*/ /* */ /* XEDIT displays x'BA' which is a left square bracket when it */ /* encounters x'AD' in the source file */ Address COMMAND 'SET OUTPUT AD' 'BA'x /* Left square bracket */ /* */ /* XEDIT displays x'BB' which is a right square bracket when it */ /* encounters x'BD' in the source file */ Address COMMAND 'SET OUTPUT BD' 'BB'x /* Right square bracket*/ /*--------------------------------------------------------------------*/ /* Write: gets x'AD' and x'BD' from keyboard and writes them in the */ /* file as correct hexadecimal values that the C/370 */ /* compiler recognizes as the left and right square */ /* brackets */ /*--------------------------------------------------------------------*/ /* */ /* XEDIT writes out x'AD' when it gets x'7C' from the keyboard */ Address COMMAND 'SET INPUT 7C AD' /* Left square bracket */ /* XEDIT writes out x'BD' when it gets x'5B' from the keyboard */ Address COMMAND 'SET INPUT 5B BD' /* Right square bracket*/ /* */ /*--------------------------------------------------------------------*/ /* Turn off text and APL characters for this XEDIT session */ /*--------------------------------------------------------------------*/ /* */ Address XEDIT 'SET TEXT OFF' Address XEDIT 'SET APL OFF' /* */ /*--------------------------------------------------------------------*/ /*Turn off text and APL characters at CP level for this logon session*/ /*--------------------------------------------------------------------*/ /* */ Address COMMAND 'CP TERMINAL TEXT OFF' Address COMMAND 'CP TERMINAL APL OFF'
The following can be added to your XEDIT PROFILE if:
/*--------------------------------------------------------------------*/ /* Display: read x'AD' and x'BD' in the source file */ /* or gets them from the keyboard and displays */ /* them as left and right square brackets */ /*--------------------------------------------------------------------*/ /* */ /* XEDIT displays x'BA' which is a left square bracket when it */ /* encounters x'AD' in the source file */ Address COMMAND 'SET OUTPUT AD' 'BA'x /* Left square bracket */ /* */ /* XEDIT displays x'BB' which is a right square bracket when it */ /* encounters x'BD' in the source file */ Address COMMAND 'SET OUTPUT BD' 'BB'x /* Right square bracket*/ /* */ /*--------------------------------------------------------------------*/ /* Set Input is not necessary */ /*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/ /* Turn off text and APL characters for this XEDIT session */ /*--------------------------------------------------------------------*/ /* */ Address XEDIT 'SET TEXT OFF' Address XEDIT 'SET APL OFF' /* */ /*--------------------------------------------------------------------*/ /*Turn off text and APL characters at CP level for this logon session*/ /*--------------------------------------------------------------------*/ /* */ Address COMMAND 'CP TERMINAL TEXT OFF' Address COMMAND 'CP TERMINAL APL OFF'
Note: You can use QUERY INPUT and QUERY OUTPUT to find out the existing settings for your XEDIT session. You can also create your own EXEC with SET INPUT and SET OUTPUT to clear settings or reset them. :enote.
When your PS/2 or 3270 terminal is sending correct hexadecimal values for the square brackets to the host system, you may still find that the ISPF editor is not correctly displaying them when you key them in. The following is a sample ISPF macro that enables you to view the [ and ] characters in text form, trigraph form or hex form, and toggle between the three settings. This macro must be included in a regular CLIST library concatenated to ISPF SYSPROG. The sample macro is named CBRACKET:
PROC 0 ISREDIT MACRO SET RP = &STR()) /* Symbolic values for 6 C language symbols. /* 1. left bracket, ebcdic hex value /* 2. right bracket, ebcdic hex value /* 3. left bracket, trigraph /* 4. right bracket, trigraph /* 5. left bracket, square /* 6. right bracket, square SET LBRACKET_HEX = X'AD' SET RBRACKET_HEX = X'BD' SET LBRACKET_TRI = &STR(??( SET RBRACKET_TRI = &STR(??&RP) SET LBRACKET_SQR = [ /* LBRACKET_SQR = HEX AB */ SET RBRACKET_SQR = ] /* RBRACKET_SQR = HEX AD */ ISREDIT FIND &LBRACKET_HEX ALL NX ISREDIT (N1) = FIND_COUNTS ISREDIT FIND &RBRACKET_HEX ALL NX ISREDIT (N2) = FIND_COUNTS IF (&N1 ª= &N2) THEN WRITE ........UNBALANCED HEX BRACKETS IF (&N1 > 0) THEN DO ISREDIT CHANGE &LBRACKET_HEX &LBRACKET_TRI ALL NX ISREDIT CHANGE &RBRACKET_HEX &RBRACKET_TRI ALL NX EXIT END ISREDIT FIND &LBRACKET_TRI ALL NX ISREDIT (N1) = FIND_COUNTS ISREDIT FIND &RBRACKET_TRI ALL NX ISREDIT (N2) = FIND_COUNTS IF (&N1 ª= &N2) THEN WRITE ........UNBALANCED TRIGRAPH IF (&N1 > 0) THEN DO ISREDIT CHANGE &LBRACKET_TRI &LBRACKET_SQR ALL NX ISREDIT CHANGE &RBRACKET_TRI &RBRACKET_SQR ALL NX EXIT END ISREDIT FIND &LBRACKET_SQR ALL NX ISREDIT (N1) = FIND_COUNTS ISREDIT FIND &RBRACKET_SQR ALL NX ISREDIT (N2) = FIND_COUNTS IF (&N1 ª= &N2) THEN WRITE ........UNBALANCED SQUARE BRACKETS IF (&N1 > 0) THEN DO ISREDIT CHANGE &LBRACKET_SQR &LBRACKET_HEX ALL NX ISREDIT CHANGE &RBRACKET_SQR &RBRACKET_HEX ALL NX EXIT END
Note: This macro may not need to be used with your host emulation software keyboard remapping. Apply your host emulation software keyboard remap first. If this does not enable correct display of [ and ] on ISPF then try this macro.
Follow this procedure if you are using a 3279-S3G-1 with ISPF, MVS or TSO. You should have the APL keys on your keyboards.
When you want to enter brackets [ or ] , press ALT APLon, enter the square brackets and then ALT APLoff. You get [ = x'AD' and ] = x'BD', which is what C/370 expects for square brackets.
These questions are culled from a variety of sources: from various question and answer databases, from customer calls, and from our own experiences.
If you have a question you like to ask us, have a comment about C/370, or just want to subscribe to this newsletter, please use the Reader's Comment Form at the back of this newsletter.
Question- How can I share VSAM datasets using C/370 ?
Answer
If your cluster is defined with shareoptions 1, VSAM supports multiple readers or a single writer, and ensures read and write integrity.
If your cluster is defined with shareoptions 2, VSAM supports multiple readers and a single writer, and ensures write integrity. The C/370 library doesn't guarantee read integrity. You can ensure read integrity by writing assembler functions to perform ENQs and DEQs, and calling them from you C/370 program (this is discussed further in the MVS Application Development Macro Reference, and Managing VSAM Data Sets).
If your cluster is defined with shareoptions 3, VSAM supports multiple readers and multiple writers. Neither VSAM nor C/370 can ensure read or write integrity. But again, you could ensure read/write integrity by writing assembler functions to perform ENQs and DEQs, and calling them from his C/370 program.
If your cluster is defined with shareoptions 4, VSAM supports multiple readers and multiple writers. Neither VSAM nor C/370 can ensure read or write integrity. But again, you can ensure read/write integrity by writing assembler functions to perform ENQs and DEQs, and calling them from your C/370 program. This is easier to do with Shareoptions 4 because VSAM provides the additional service of updating buffers for each direct request.
You can issue ENQs and DEQs against the data set name. C/370 does not use Control Interval Access, so ENQ'ing on the CI wouldn't be useful. ENQ'ing on the record key could potentially result in a loss of data if two writers attempt to write two different records into the same CI at the same time. If you are working with a PATH to an AIX, try ENQ'ing on the Base Cluster name, and once that ENQ is successful, ENQ on the PATH name.
Question- Strange compile error ...
Can anyone explain what this error message means? I can't find it in any of my manuals.
ERROR EDC1301 Spill size for function bfssdelf must be greater than 272My listing shows a complete list of the source code, with no errors of any sort, and the error summary followed by this message. The assembler listing (though requested) is not present. Optimization was set to level 2.
Answer
According to the CC HELPCMS file ( same applies to MVS ) SPILL is a compiler option.
SPill(size) SP(128) is the default. SPILL specifies the maximum size the spill area can be. You will receive a compile-time message if ------------------------------------------ you need to specify this option. -------------------------------
Using this compiler option should clear up this error message.
Question- Concatenation of 3 partitioned datasets
I am trying to concatenate 3 partitioned datasets with include files on the SYSLIB statement of a compilation:
//COMPILE EXEC PGM=EDCCOMP,REGION=1536K,COND=(8,LE), // PARM=(SOURCE,LONGNAME,NOSEQUENCE,NOMARGINS) //STEPLIB DD DSN=SYS1.EDC.SEDCLINK,DISP=SHR // DD DSN=SYS1.PLI.SIBMLINK,DISP=SHR // DD DSN=SYS1.EDC.SEDCCOMP,DISP=SHR //SYSLIB DD DSN=SYS1.EDC.SEDCHDRS,DISP=SHR // DD DSN=NSPCICS.C.H,DISP=SHR // DD DSN=NSPCICS.KK.C.H,DISP=SHR etc. This gets me the following error message: 131 |#include <kk.h> *=SEVERE==========> EDC0901 Unable to read DD:SYSLIB(KK).
The kk.h file is in the 3rd SYSLIB dataset. The datasets have different record lengths. The first one is FB,80,3120 and the other 2 are VB,104,3120. Changing the record format of the latter 2 datasets to FB,100,3120 did not help. Only changing them to exactly the same format as the first dataset (FB,80,3120) did help.
I don't like changing to FB,80, because this is one of many programs that I am migrating to MVS, with lots of lines longer than 80. I know that the #include <kk.h> should really be #include "kk.h", but again, I would rather not change all of the occurrences throughout the code. Any hints or tips on how to solve this problem?
Answer
You have discovered that the datasets must have the same characteristics in order to be used in a concatenation. This is not a C restriction, but an MVS restriction.
You will probably have to remove the dataset from the concatenation and use the SEARCH option to find it.
Question- SQL Calls in C/370
I need to know whether I can imbed SQL calls in c/370.
Answer
SQL statements can be imbedded in C programs. The SQL translator converts the statements into C code which performs the assignments and calls a database language interface module.
Question- Reading a line that has "\n" (hex 15) in it.
I'm writing a program to read another program's output, a bunch of structures with each structure taking up a line. Unfortunately some of the structures have hex 15, which is \n, in them. This causes FGETS to think that the line has stopped and therefore I get only part of the line that I need. Is there any way around this problem? I cannot use scanf() because I don't know which structure I'm reading ahead of time and can't specify the format.
Answer
Use fread(), which is meant for binary files. The C/370 Programming Guide explains this in Chapter 24 (Record I/O).
Question- __4kmalc()
Page 466 of the Programming Guide (V2R1) states that the __4kmalc() memory management function is available only in the systems programming environment.
I have a C source file that contains normal C functions called by a main function and system exit routine functions called as I/O interrupt handlers. The system exit routines are defined with the #pragma environment directive.
I want to use __4kmalc () from both the normal functions and the system exit routines. Can I?
If I include EDCXMEM TEXT in the module, will the systems programming versions of the other memory allocation functions (like malloc() and free()) work in the normal C functions as well?
Answer
You cannot mix the SPC memory functions with the Common Library or AD/Cycle Environments. The control blocks that define the environments are different.
If you try to allocate the memory in the function (coded as SPC exit) and pass it to the Common Library main(), you get in trouble as well: the SPC environment is established at entry to the function and taken down when you leave it. Thus allocated memory is freed, and you might be passing something that you do not own.
Consider using the persistent environment concept to do what you want. Your main() with its Common Library environment could call EDCXHOTC and establish an SPC environment for your exits. Then use EDCXHOTU to call the functions. One of these functions could allocate the storage using __4kmalc() and you could pass a pointer to the storage back to your main(). Before you terminated the main(), you could call EDCXHOTU for a function that frees the storage and then call EDCXHOTT to kill the SPC environment. Performance should be improved this way if you call more than one exit.
Question- Dynamic calling
I need to know how to dynamically call a C/370 program (MVS) that resides in a separate load module. I have reviewed the manuals, and cannot find out how to do this. Could you tell us how to do it, or give us the manual number/page # that tells us how?
Answer
Use a system() call. Make sure that the load module is in the STEPLIB. See page 411 in the V2R1 Programming Guide. (SC09-1384-00)
Question- Errno
If I want to interrogate the errno value, can I just do an if check on the field errno? That is , can I do the following?
. int testvalue=4; . if (errno == testvalue) .
Answer
Yes.
Question- Record I/O with C/370
I am trying to read a recfm=VB file. I would like to know where records end and begin. If I uses fopen(file ,"r,recfm=VB"), and fread(buffer, 1, rec_size, file)... I get the number of characters I requested.
Is there any way to use C/370 with record I/O? I'd like to know what the actual record length is of the record I've read.
Answer
Use fopen(file, "rb,type=record"). For record I/O, you need to open the file in a binary mode, i.e., "rb". Since you're opening for read, fopen() will figure out that the file is recfm=VB, so you don't have to mention it.
Then call fread(buffer, 1, rec_size, file). This will return the number of bytes in the record read. The next fread() will get the next record and so on. fread() doesn't add a null at the end of the record, so if you want to treat the record like a null-terminated string and the records on the disk aren't null terminated, make the buffer big enough and add a null yourself.
Question- SAA AD/CYCLE C/370 prelink ends with a warning
I have MVS/ESA SP 4.3, CICS/ESA 3.3, SAA AD/CYCLE C/370 V1R1, LE/370 V1R1M1 installed and running.
When I compile any batch C program, I get a warning at the prelink step. The Installation Guide says that the prelink IVP will give that warning and it is not an error. I am still worried and expecting a good explanation if it is really ok to get that warning at the prelink step.
Warning EDC4015: Unresolved References are detected: CEEBETBL EDCROOT DFHEXEC CEESG003 @@TRT STRNCPY SPRINTF
Does anyone know what is causing this warning and how it can be fixed?
Answer
When you prelink, you are prelinking only your own code, not your code as well as library code. Some of the unresolved references are to general library code (those routines starting with CEE and EDC) as well as C/370 library routines (SPRINTF, STRNCPY). @@TRT is a table used by the C/370 compiler for certain functions.
Question- Access to TTIME
I am writing a transaction control program for a service machine on VM/ESA. This program is written in C/370. It needs to access the system TTIME for billing purposes. Because the control program is complex, I don't want to write the whole thing in assembler.
The most efficient way that I can see to do this is to call an external assembler routine that issues a DIAG C and stores two integers in locations provided by the C caller. I am assuming that this will give me the information that I need with the minimum of runtime overhead.
My problem is in creating a MODULE that will run on VM/CMS. I compile and link according to the book but the module will not run. I have included my console session below. Testasm is the C/370 mainline that calls the ttime routine, which is written in assembler. The ttime routine has been previously assembled into a TEXT deck by the assembler programmer. The mainline routine uses #pragma linkage(TTIME, OS).
----------------------console file------------------------------------------ Ready; T=0.01/0.01 16:13:17 compile testasm Compiling C program TESTASM Compile completed with return code 0 Ready; T=0.29/0.43 16:13:22 global txtlib edcbase ibmlib cmslib Ready; T=0.01/0.01 16:13:37 load testasm ttime (clear rld reset ceestart Ready; T=0.01/0.02 16:13:52 genmod testasm (from ceestart Ready; T=0.01/0.01 16:14:01 testasm IBM004I PROGRAM TERMINATED, USER CODE = 2052 DURING INITIALIZATION. IBM019I . NO SUITABLE DUMP FILE DEFINITION DMSABE155T User abend 2052 called from 00079DE2 reason code 00000000 CMS ----------------------------------------------------------------------------
Any help would be appreciated.
Answer
On page 156 of the V2R1 manual, you will find a description of error codes from C/370. A 2052 means you have an AMODE 24 program and the library is loaded above the line. You can fix this by either
Question- How do I preserve case between REXX and C/370?
I am calling a C/370 program from a REXX program. I am passing mixed case parameters with the ARGV parameter to the C program. The first thing the C program does is display the ARGV, and it is all in lower case. This application is case-sensitive, and needs these parameters to be in their original state when sent to the C program. How can I do this?
Answer
When a CALL command invokes a C program the arguments are passed as lower case. This is done to comply with ANSI. If you wish to pass mixed case, you can specify the option 'asis' in the CALL command. A table is given on page 136 of the IBM C/370 Programming Guide, SC09-1384-00 describing the cases of passed arguments.
Question- Command line parms
Is there any way to access the unparsed command line (what reg 1 points to when CEESTART is called)? I have a program that has some significant whitespace in the parameter list, and I don't want it parsed. This program is loaded and called by another program (SCLM), so I can't change the parm list or add quotes around it.
Answer
Try using '#pragma runopts(noargparse)'. This runtime option disables argument parsing. It is described in the V2R1 programming guide on page 361.
Question- Fetching from system exits
I have an MVS subtask written as a C/370 system exit routine (page 478), and attached with the MVS ATTACHX macro. I also have a reentrant C module, which has writable static and must be able to be loaded from a normal C main program or an MVS subtask.
The problem is that the fetch() function is not supported in a systems programming environment (page 467). I assume it is the fetch() library function that would allocate the writable static for the loaded module.
The reentrant module is compiled with the RENT compile-time option, prelinked, and then linked to create the load module. When I issue the MVS LOAD macro from a normal C main program, the loaded reentrant module seems to get some C/370 heap storage where it expects to find its static strings. (A pointer to a string constant instead points to the characters "FREE", which looks like an malloc header.) I use a function name as the entry point of the load module.
What can I do to load a reentrant module with writable static from an MVS subtask? Page numbers refer to the IBM C/370 Programming Guide Version 2 Release 1.0.
Answer
You are correct about fetch() performing the allocation of your writable static. What happens when you just load it is that your generated code is expecting to find the address of writable static off of R12. It has offsets it expects from certain variables (including strings not compiled with #pragma strings(readonly)) and since you have no writable static set up, it won't work.
What you might try is building the routine you want to fetch as a main() and linking it as a fully operational C module. You can then system() call or LINK the module. This will transfer control to normal initialization which will allocate the writable static. To pass parameters other than char strings, use the LINK macro and on the other side, use __sysplist to access them. You also have to specify NOREDIR and NOARGPARSE as runopts to prevent inadvertent parsing of your arguments.
Question- DEF text folding to lower case
My C source under MVS passes a compile option "DEF(MACH_TYPE=MVS_AUSSIM)" in uper case. When I compile this source, the option is converted to lower case, which is not what I want. Is there a way to control the DEF text so that it gets folded UP?
Here are the contents of my CLIST used to compile the C source:
CC 'ECSUID2.TEST.C(CHIPROOT)' + OBJ('''ECSUID2.AUSPUDV.OBJLIB(CHIPROOT)''') + COPT('LANGLVL(ANSI),DEF(MACH_TYPE=MVS_AUSSIM),+ <===Entered upper== MARGINS(1,80),NOSEQ,GONUM,XREF,SOURCE,TEST(ALL)') Here is the C listing, showing the options used by the CC compiler: 15688187 V2 R1 M00 IBM C/370 ECSUID2.TEST.C(CHIPROOT) Command options: Program name. . . . . . . . . : ECSUID2.TEST.C(CHIPROOT) Compiler options. . . . . . . : *GONUMBER *NOALIAS *NODECK *NORENT : *XREF *NOAGGR *NOPPONLY *NOEXPM : *NOCSECT *NOLONGNAME *START : *TARGET() *FLAG(I) *TEST(SYM,BLOCK,LIN : *NOINLINE(AUTO,NOREPORT,250,1000) *NESTIN : *NOCHECKOUT(NOPPTRACE,PPCHECK,GOTO,ACCURACY : * NOEXTERNAL,TRUNC,INIT,NOPORT,GE : *NOSEARCH : *NOLSEARCH : *OBJECT ===Folded to Lower=========> : *DEFINE(mach_type=mvs_aussim) Language level. . . . . . . . : *ANSI Source margins. . . . . . . . : Varying length. . . . . . . : 1 - 80 Fixed length . . . . . . . : 1 - 80 Sequence columns. . . . . . . : Varying length. . . . . . . : none Fixed length. . . . . . . . : none
As you can see the DEFINE text is being changed to lower case by the CC compiler (or the CLIST) !!!!
Answer
This behaviour is the result of several factors.
The solution in your example is to provide the arguments in mixed case: def(MACH_TYPE=MVS_AUSSIM). When the C runtime gets the mixed case arguments, it knows that they were actually typed that way and leaves them alone.
Question- Multiple Memory files
I would like to know whether multiple C memory(hiperspace) files can be opened in one application. For instance, FILE *fp1 = fopen("file1", "w, type=memory(hiperspace)"); FILE *fp2 = fopen("file2", "w, type=memory(hiperspace)"); and so on. On the C/370 prog. guide manual (SC09-1384-00) it references to the following: Page 219, memory files in HS, the last sentence says: "More than one stream cannot be opened to a HS memory file" I do not really understand if I can or can not do the above.
Answer
The documentation is referring to multiple streams opened to the same hiperspace memory file. Multiple hiperspace files are allowed.
Question- Porting a C program to the mainframe
I am trying to port a C program written for the PC to the mainframe. I'm using the AD/Cycle C/370 compiler (5688-216) under MVS. I have several questions that have resulted from my efforts to accomplish this migration.
Answer
Question- Performance Problems
I am having performance problems with a new system I am now stress testing. BSAM appears to be used as the access method for many files. Our performance monitors show that we are waiting 11-17 percent of the time in BSAM's CHECK module.(IGG019BB) We would like to improve the performance on these files by buffering. Do you know why BSAM was chosen by C/370 as the access method?
The customer coded fopen() and fread() (with a BUFFER_LEN).
Answer
Support for file repositioning is the reason for selecting BSAM as the access method. QSAM access method is preferable for performance critical applications, but it is not currently supported by C/370. However, we have an outstanding requirement to add the support for QSAM access method in a future release of C/370.
Queston- Forcing an abend
I want to find a good way to force an abend in a C/370 program that does DB/2 calls so that DB/2 will back out to the beginning (or an explicit commit). I tried the abort() library routine, but that didn't work-it apparently doesn't cause an actual abend. Is there a way to force an abend in a C/370 program if a certain condition is detected by the program?
Answer
An ABEND is something we generally try to avoid, but if you wish to force one, you can use the following. For the runtime options , select NOSTAE to stop the attempt to generate a diagnostic message and a CEEDUMP when the abend occurs. There will be no attempt to close files and terminate the environment. Selecting NOSPIE lets the program interrupts be interpreted as abends. A simple way to generate an abend is to issue a divide by zero. Do not select OPT(2), and issue the following:
a=0; b=2; c=b/a;The compiler should not detect the divide by zero at compile time.
Question- CICS & C/370
We are using the CICS translator for C/370 on multiple source files. The translator is creating EIB declarations in each file so we are getting duplicate reference warnings for these variables at link time. Is only one set of EIB declarations necessary for each load module? If so I can prevent the other copies from being compiled by defining a __dfheitab constant to the C compiler. If each compile unit needs its own EIB declarations they should be declared with static scope.
Answer
There is only one EIB per CICS transaction. It is not part of the program, but is created by CICS. Addressability to it is provided by CICS. The translator inserts definitions (DSECT) of the EIB in your program. This is not allocated storage, but definitions of external data.
C/370's addressability to the EIB is not automatic as in other languages. It must be established by the program with an EXEC CICS ADDRESS command. This will return the address of the EIB which you use as a pointer.
In your load module, each of the separately compiled modules must use the same pointer value. You must either pass this value or make it a global variable accessible to all of the modules.
If the pointer name used in the separate modules is different, you must ensure that the VALUE is the same.
If you did not get a copy of any of our previous editions, just let us know and we will be more than happy to send them to you.
If you haven't already sent for your free subscription to this newsletter, now is the time to mail it in. So far, we have been able to keep to our plan of 4 issues a year (even thought we may sometimes be a little late). Please keep those cards and letters coming in to us so that we can keep publishing. We really thank the many of you who have already sent your comments and subscriptions in. If you prefer, mail or fax your business card to the address/phone number on the Reader's Comment Form.
For the many of you sending in the reply forms with your comments, we may need to call you to discuss your comments further. It's a great help if you include your phone number. Thanks!
Well, that's all we can squeeze in for now. In future issues, we'll bring back some performance tips and answer some more of your questions. Thanks for reading; please let us know what you think of this newsletter.
+--------------------------------------------------------------+This newsletter was produced by the C/370 Planning department of the IBM Software Solutions Toronto Laboratory. For further information on any of the products mentioned, please contact your local IBM office, or an authorized IBM Business Partner.
Numerous product references in this publication are registered trademarks or trademarks of International Business Machines Corporation unless otherwise indicated. IBM Canada Ltd., a related company, is a licensee.
This newsletter was created and marked for processing using IBM BookMaster(TM) (Program Number 5688-015) and IBM Document Composition Facility (DCF). (Program Number 5748-XX9).
The final copy was printed on an IBM 3825 Page Printer, an Advanced Function Printer.
This newsletter is © Copyright IBM Corporation 1994.
In Canada - © Copyright IBM Canada Ltd. 1994. +--------------------------------------------------------------+
Please note:
_______________________________________________________
_______________________________________________________
_______________________________________________________
_______________________________________________________
_______________________________________________________
Thank you for your cooperation and help. You can either mail this form to us, or hand it into an IBM office for forwarding.
You can also fax the form to us. Our fax number is 416-448-6057. Please mark your fax for the attention of Gord Sinclair. Thanks.
( ) Products marked (TM) or ® are trademarks or registered trademarks of the International Business Machines Corporation, unless otherwise indicated.
( ) Unix is a trademark of UNIX System Laboratories, Inc. POSIX and IEEE are trademarks of the Institute of Electrical and Electronic Engineers.
(1) These characters are not in the C character set.