Support This Project Get i5/OS Programmer's Toolkit at SourceForge.net. Fast, secure and Free Open Source software downloads

Example Programs for MI/EMI Novice

Go back to main page of i5/OS Programmer's Toolkit.

Date Last Modified: Mon Sep 7 15:44:39 CST 2009

Attention:
This page is to be enriched from time to time. Please take note of the project's summary page https://sourceforge.net/projects/i5toolkit/ for update notification.
Here're some example MI (Machine Interface Instructions) programs for MI novice. All programs provided here confirm to EMI Syntax Specification. For usage information of a specific MI instruction, please refer to IBM's documentation on Machine Interface Instructions, i5/OS Machine Interface For document of MIC builtins, please refer to Specifications of EMI Builtins.

Contents

Print OS Version Information

To retieve OS version (Licensed Internal Code version release modification) of an i5/OS installation, use the MATMATR instruction with option hex 020C.

/* *
 * @file sep10.emi
 *
 * @attention applicable on V5R4 and later 
 */

dcl dd os-version char(6) bas(.os-version) ; 

entry *(plist-main) ext         ; 

dcl dd mat-tmpl char(16) auto        ;
dcl spcptr .mat-tmpl auto init(mat-tmpl) ; 
        dcl dd bytes-in bin(4) def(mat-tmpl) pos(1) init(16) ; 
        dcl dd bytes-available bin(4) def(mat-tmpl) pos(5) ; 
        dcl dd lic-version char(6) def(mat-tmpl) pos(9) ; 

        cpynv bytes-in, 16             ;
        cpybrep os-version, ' '        ;
        matmatr .mat-tmpl, x"020C" ; 
        cpybla os-version, lic-version ; 

dcl dd len bin(2) auto          ;
        triml len, os-version   ;
        %sendmsg(os-version, len) ;

brk 'RTN'                       ;
        rtx *                   ; 
pend                            ;

List Activation Groups of One's Current Job

To list activation groups of the current job, we need the following two MI instructions:

Download source file sep5.emi

entry * ext                     ;

dcl spcptr tmpl-ptr auto        ;
dcl spc tmpl-t bas(tmpl-ptr)    ;
        dcl dd bytes-in bin(4) dir ;
        dcl dd bytes-out bin(4) dir ;
        dcl dd agp-num bin(4) dir   ;

        /* get number of activation groups */
dcl dd bytes-needed bin(4) auto       ;
        modasa tmpl-ptr, 12     ;
        cpynv bytes-in, 12      ;
        matpragp tmpl-ptr       ;
        cpynv bytes-needed, bytes-out ;
        modasa tmpl-ptr, -12          ;

        modasa tmpl-ptr, bytes-needed ;
        cpynv bytes-in, bytes-needed  ;
        matpragp tmpl-ptr             ;

        /* print agp names */
dcl dd agp-info-0 char(136) auto bdry(16)     ;
dcl spcptr agp-info-ptr auto init(agp-info-0) ;
dcl spc agp-info-spc bas(agp-info-ptr)        ;
        dcl dd agp-bytes-in bin(4) dir        ;
        dcl dd agp-bytes-out bin(4) dir       ;
        dcl dd * char(8) dir                  ;
        dcl dd * char(48) dir                 ;
        dcl dd agp-name char(30) dir          ;
dcl dd ind pkd(3,0) auto                      ;
dcl dd num bin(4) auto                        ;
dcl dd agp-mark bin(4) unsgnd bas(tmpl-ptr)   ;
dcl dd agp-mark-ch char(4) bas(tmpl-ptr)   ;
dcl dd msg char(64) auto                      ;
dcl dd cvtnc-tmpl char(7) auto init(x'02000300000000') ;

        cpynv ind, 0            ;
        cpynv num, agp-num      ;
        addspp tmpl-ptr, tmpl-ptr, 12 ;
        cpynv agp-bytes-in, 136       ;
        cpyblap msg, 'Activation groups of current job:', ' ' ;
        %sendmsg(msg, 33)       ;
        cpyblap msg, "    Num  Activation Group Name          Activation Mark", ' ' ;
        %sendmsg(msg, 64)       ;

agp-loop:
        addn(s) ind, 1                         ;
        cmpnv(b) ind, num / hi(end-agp-loop)   ;
        matagpat agp-info-ptr, agp-mark, x'00' ; /* retieve basic actgrp info */

        cpybrep msg, ' '        ;
        cvtnc msg(5:3), ind, cvtnc-tmpl ;
        cpybla msg(10:30), agp-name ;
        cvthc msg(41:8), agp-mark-ch ;
        %sendmsg(msg, 64)  ;

        addspp tmpl-ptr, tmpl-ptr, 4 ;
        b agp-loop              ;
end-agp-loop:
        /* free tmpl-ptr */
        subn bytes-needed, 0, bytes-needed ;
        modasa tmpl-ptr, bytes-needed ;

        rtx *                   ;
pend                            ;

Run program SEP5

> call sep5                                              
  Activation groups of current job:                      
      Num  Activation Group Name          Activation Group Mark
      001                                 00000001       
      002                                 00000002       
      003  QTESAGRP                       00000241       
      004  QLGLOCAL                       00000251       

List Activation Entries in a Specific Activation Group

The following program accepts a 4 bytes activation group mark as input parameter, and prints information of each activation entry in the specified activation group. The output includes program library, program name, invocation count, and activation status of each activation entry. Note that only programs currently on the call-stack of a thread belongs to the specified activation group could have non-zero invocation counts.

/* *
 * @file sep6.mi
 *
 * list activation entries in a activation group
 *
 * @param[in] arg-mark, bin(4) unsgnd, activation group mark
 */

dcl spcptr agp-mark-ptr parm    ;
dcl ol pl-main(agp-mark-ptr) parm ext ;

entry *(pl-main) ext            ;

dcl dd agp-mark bin(4) unsgnd bas(agp-mark-ptr) ;

dcl spcptr agp-info-ptr auto            ;
dcl spc agp-info-spc bas(agp-info-ptr)        ;
        dcl dd agp-bytes-in bin(4) dir        ;
        dcl dd agp-bytes-out bin(4) dir       ;
        dcl dd * char(8) dir                  ;
dcl dd len bin(4) auto                        ;
dcl dd act-count bin(4) unsgnd bas(agp-info-ptr) pos(109) ;
dcl dd num-act bin(4) unsgnd auto                         ;

        /* get activation count */
        modasa agp-info-ptr, 16                ;
        cpynv agp-bytes-in, 16                 ;
        matagpat agp-info-ptr, agp-mark, x'00' ;
        cpynv len, agp-bytes-out               ;
        modasa agp-info-ptr, -16               ;

        modasa agp-info-ptr, len ;
        cpynv agp-bytes-in, len  ;
        matagpat agp-info-ptr, agp-mark, x'00' ;

        cpynv num-act, act-count ;
        subn len, 0, len        ;
        modasa agp-info-ptr, len ;

        /* list activation marks */
        modasa agp-info-ptr, 16                ;
        cpynv agp-bytes-in, 16                 ;
        matagpat agp-info-ptr, agp-mark, x'02' ;
        cpynv len, agp-bytes-out               ;
        modasa agp-info-ptr, -16               ;

        modasa agp-info-ptr, len ;
        cpynv agp-bytes-in, len  ;
        matagpat agp-info-ptr, agp-mark, x'02' ;

        /* matactat */
/* basic activation info */
dcl dd act-info char(72) auto bdry(16) ;
dcl spcptr act-info-ptr auto init(act-info) ;
dcl spc act-info-t bas(act-info-ptr)        ;
        dcl dd act-bytes-in bin(4) dir      ;
        dcl dd act-bytes-out bin(4) dir     ;
        dcl dd * char(8) dir                ;
        dcl sysptr act-pgm dir              ;
        dcl dd * bin(4) unsgnd dir          ; /* activation mark: act-mark */
        dcl dd * bin(4) unsgnd dir          ; /* activation group mark */
        dcl dd inv-count bin(4) unsgnd dir  ; 
        dcl dd ssf-count bin(4) unsgnd dir  ;
        dcl dd pgm-type char(1) dir         ;
        dcl dd act-status char(1) dir       ; /* bit 0: 0=inactive, 1=active */
        dcl dd tgt-agp char(1) dir          ;
        dcl dd * char(1) dir                ;
        dcl dd dep-act-count bin(4) unsgnd dir ;
        dcl dd act-mark-long char(8) dir    ;
        dcl dd agp-mark-long char(8) dir    ;

dcl dd ind bin(4) auto          ;
dcl spcptr act-mark-ptr auto    ;
dcl dd act-mark bin(4) unsgnd bas(act-mark-ptr) ;
dcl dd msg char(64) auto        ;
dcl dd cvtnc-attr char(7) auto init(x'02000200000000') ;
        cpynv ind, 0            ;
        cpynv act-bytes-in, 72  ;
        setsppfp act-mark-ptr, agp-info-ptr ;
        addspp act-mark-ptr, act-mark-ptr, 16 ;

        cpynv matptr-bytes-in, 77 ;

        cpyblap msg(1:10), "Library", " " ;
        cpyblap msg(11:10), "Program", " " ;
        cpyblap msg(21:10), "Inv-Cnt", " " ;
        cpyblap msg(32:10), "Act-sts", " " ;
        %sendmsg(msg, 64)                          ;

        cpybrep msg, ' '        ;

activation-loop:

        addn(s) ind, 1          ;
        cmpnv(b) ind, num-act / hi(end-loop) ;

        matactat act-info-ptr, act-mark, x'00' ;
brk 'CHK'                       ;
        /* check inv-count, act-pgm */
        matptr matptr-tmpl-ptr, act-pgm ;

        cpybla msg(1:10), matptr-ctx-name ;
        cpybla msg(11:10), matptr-pgm-name ;
        cvtnc  msg(28:2), inv-count, cvtnc-attr ;
        cmpbla(b) act-status, '0' / neq(=+3) ;
        cpyblap msg(31:10), "Inactive", " "  ;
        b =+2                   ;
:
        cpyblap msg(31:10), "Active", ' ' ;
:
        %sendmsg(msg, 64)           ;
recover:
        addspp act-mark-ptr, act-mark-ptr, 4 ;
        b activation-loop       ;
end-loop:

brk 'END'                       ;

        subn len, 0, len        ;
        modasa agp-info-ptr, len ;
        rtx *                   ;

/* template of MATPTR */
dcl dd matptr-tmpl char(77) auto ;
dcl spcptr matptr-tmpl-ptr auto init(matptr-tmpl) ;
dcl spc matptr-tmpl-t bas(matptr-tmpl-ptr)        ;
        dcl dd matptr-bytes-in bin(4) dir         ;
        dcl dd matptr-bytes-out bin(4) dir        ;
        dcl dd matptr-ptr-type char(1) dir        ;
        dcl dd matptr-ctx-type char(2) dir        ;
        dcl dd matptr-ctx-name char(30) dir       ;
        dcl dd matptr-pgm-type char(2) dir        ;
        dcl dd matptr-pgm-name char(30) dir       ;
        dcl dd matptr-ptr-auth char(2) dir        ;
        dcl dd matptr-ptr-tgt char(2) dir         ;

dcl excm ex excid(h'0000') bp(on-error) imd cv('MCH') ;

on-error:       

dcl dd ex-info char(16) auto init('Oops :p') ;
        %sendmsg(ex-info, 16)   ;
        b recover               ; /* 用法有问题 here-today */

pend                            ;
/* eof - sep6.mi */

Run program SEP6

/* check activation entries in the second *DFTACTGRP */
> call sep6 x'00000002'                 
  Library   Program   Inv-Cnt    Act-sts
  QSHELL    QZSHQSHC         00 Active  
  QSHELL    QZSHBASE         00 Active  
  QSYS      QC2UTIL1         00 Active  
  QSYS      QC2POSIX         00 Active  
  QSYS      QLEAWI           00 Active  
  QSYS      QP0LLIB1         00 Active  
  QSYS      QP0LLIB2         00 Active  
  QSYS      QP0ZCPA          00 Active  
  QSYS      QP0ZTRML         00 Active  
  QSYS      QSYPAPI          00 Active  
/* ... ... */
  QRPLOBJ   Q5DA70AFBC       00 Active
  LSBIN     SEP6             01 Active

Use EMI Includes

Try to delete a nonexistent *USRSPC.
entry * ext                     ;

dcl dd spc char(20) auto init('SEP1      LSBIN') ;

        /* try to delete a nonexistent *USRSPC */
        setspp emi-qusdltus-al-usrspc, spc ;
        cpynv emi-ec-bytes-in, emi-qusec-len ;
        setsppfp emi-qusdltus-al-ec, emi-qusec-ptr ;
        callx emi-qusdltus, emi-qusdltus-al, * ;

brk 'CHK-EC'                    ;
        cmpnv(b) emi-ec-bytes-out, 0 / nhi(farewell) ;
        %sendmsg(emi-ec-exid, 7)                  ;

farewell:       
  rtx *                   ;

/include qusec.emi              ;
/include qusdltus.emi           ;

pend                            ;

Operate Stream Files using EMI Stream File Bulitins

Write a stream file.
/* *
 * @file sep14.emi
 *
 */

entry * ext                     ;

dcl dd fd bin(4) auto           ;
dcl dd path-name char(64) auto  ;
dcl dd file-mode bin(4) auto init(h'180') ;

        cpyblap path-name, '/home/ljl/923', x'00' ;
        cpynv fd, %stmf-creat(path-name, file-mode) ;
brk 'CRT'                       ;

dcl dd str char(8) auto init('morning!') ;
dcl dd written bin(4) auto               ;

        cpynv written, %stmf-write(fd, str, 8) ;
        cpybla str, 'MoRnInG!'                 ;
        %stmf-write(fd, str, 8) ;

brk 'WRT'                       ;
dcl dd rtn bin(4) auto          ;
        cpynv rtn, %stmf-close(fd) ;

brk 'CLS'                       ;
        rtx *                   ;

pend                            ;

Check result *STMF

> wrklnk '/home/ljl/923'

 ************Beginning of data**************
morning!MoRnInG!                            
 ************End of Data********************

Execute CL Commands Using EMI Builtin %system

EMI provides a builtin, %system to execute CL commands. See system (execute a CL command) for details. The following program uses the %system builtin to execute CL command CRTLIB to create a library.

/* *
 * @file sep19.emi
 *
 * usage example of EMI builtin %system
 */

entry * ext                     ;

dcl dd cmd char(64) auto        ;
dcl dd rtn bin(4) auto          ;

        cpyblap cmd,
          "CRTLIB LIB(HUHUHAHA) TEXT('Sun Wukong and Juliet')",
          x'00'                 ;
        cpynv rtn, %system(cmd) ;

        /* has the library been created? */
        cmpnv(b) rtn, 0 / neq(failed) ;
        cpyblap cmd,
          "WRKLIB HUHUHAHA",
          x"00"                 ;
        %system(cmd)            ;
        b farewell              ;
failed:
        cpyblap cmd,
          "CRTLIB command failed.",
          ' '                   ;
dcl dd len bin(2) auto          ;
        triml len, cmd, ' '     ;
        %sendmsg(cmd, len)      ;

farewell:       
        rtx *                   ;
pend                            ;
/* eof */

Call program SEP19.

mi-eg-1.png

Program SEP19 issues CL command WRKLIB after creating library HUHUHAHA by executing CL command CRTLIB

sect_mi_eg_07


Support This Project
Generated on Mon Aug 1 22:50:22 2011 for i5/OS Programmer's Toolkit: MIC - The Machine Instruction Language Compiler by  doxygen 1.5.9