Midrange News for the IBM i Community

Posted by: Bob Cozzi
Rogue Programmer
Cozzi Productions, Inc.
Create User Space
© R. Cozzi Jr. has no ratings.
Published: 04 Mar 2014
Revised: 20 Jun 2015 - 648 days ago
Last viewed on: 29 Mar 2017 (2314 views) 

Using IBM i? Need to create Excel, CSV, HTML, JSON, PDF, SPOOL reports? Learn more about the fastest and least expensive tool for the job: SQL iQuery.

CRTUSRSPC Command Published by: Bob Cozzi on 04 Mar 2014 view comments
© R. Cozzi Jr.

Create User Space

I think QUSCRTUS (Create User Space) API was either the first or among the first few APIs IBM created during the 1980s to "open up" the system. While an "open system" never materialized it did start a wave of API introductions that number in the thousands today.

Of course I published a Create User Space CL command some 20 to 25 years ago, and continue to include one in my Cozzi AppTools product. Given the benefit of User Spaces to API usage, and as an alternative to dynamically allocated memory (%ALLOC in RPG IV) I am beginning a 3 part series of User Space Commands starting with CRTUSRSPC (Create User Space). The original version of this command appeared in Midrange magazine back in the early 1990s. It was written in RPGIII and later ported to RPG IV in the mid-1990s. Then in approximately 2002 I released RPG xTools and moved it into a Service Program. In 2012 I started porting all of my tools to C and C++ as I grew tired of fighting the IBM API interfaces (provided in QSYSINC). This C version is being published today.

I've settled on using C++ as a "better C language" but unfortunately as is the case with RPGIV, C++ has largely been ignored by the API and system information implementation. Rather than hash through the reasons why or try to build up a library of C++ stuff, what I am doing now is writing stand-alone programs in both C++ and C while leveraging the QSYSINC C library. A few months back I published the first of my C/C++ tools; a great little conversion routine that converts CL variables to upper or lower case. IBM (at my request along with others) implemented this capability in CL as %UPPER and %LOWER built-in functions (in v7r2).

The Create User Space (CRTUSRSPC) command is written entirely in C and creates an optionally auto-extendable User Space. There is rarely a case when a user space doesn't need to be auto-extend enabled, so this command/program creates the user space and then changes its auto-extend attribute to true. There is the AUTOEXT(*YES | *NO) parameter on the command, so you can adjust that setting. Recently I also added the legacy PUBAUT (Public Authority) parameter to the CRTUSRSPC command to allow people who need that type of capability to specify authority at creation time.

Dependencies: There are no 3rd-party dependencies for this command or program. The QSYSINC library must be installed, but it is included (aka "free") with IBM i, so everyone doing compiling should have it installed.

System Release: This should compile as far back on the Operating System as possible. I know it compiles fine on V5R4 and later, but it probably works back to at least V4R2.

Source Code: As always, the source code for any of my iOpen code is avialable at this link.

#include <stdlib.h>             
#include <stdio.h>         
#include <stdint.h>          
#define  __cplusplus__strings__ 
#include <string.h>         
#include <QUSEC.h>             
#include <QUSCRTUS.h>           
#include <QUSCUSAT.h>       
     /* Create User Space (CRTUSRSPC) Command Processing Program  */
     /* Author  :  Bob Cozzi                                      */
     /* Date    :  04March2014                                    */
     /* Purpose :  To allow CL Cmd-based User Space Creation      */
     /* Rev. Log:                                                 */
     /*  14June2014 - Released to public via midrangeNews.com     */
     /*  29June2014 - Added PubAut parameter to command.          */
     /*  30June2014 - Added AutoExtend parameter to command.      */

typedef _Packed struct Qus_Attr_t {
           int  count;
           int  key;
           int  dataLen;
           char data[10];
} usAttr_t;

#define autoExtend 3
#define copyParm(varName, parmNum) \
        if (argv[parmNum] != NULL) \

void main(int argc, char *argv[])
        char us_name[20];
        char us_attr[10];
        int  us_initSize = 0;
        char us_replace[10];
        char us_autoExtend = '1';
        char us_text[50];
        char us_pubAut[10];

        char     initValue = 0x00;
        char     rtnLib[10];
        usAttr_t spaceAttr;
        Qus_EC_t ec;

        spaceAttr.count = 1;
        spaceAttr.key = autoExtend;  // Auto-extend

        memset(us_name,' ',sizeof(us_name));
        memset(us_attr,' ',sizeof(us_attr));
        memset(us_text,' ',sizeof(us_text));
        memset(us_pubAut,' ',sizeof(us_pubAut));
        memset(us_replace,' ',sizeof(us_replace));

        memset(rtnLib,' ',sizeof(rtnLib));
        if (argv[3]!=NULL)
           us_initSize = *(int*)argv[3];
        if (argv[4]!=NULL)
           us_autoExtend = *(char*)argv[4];

        if (us_attr==NULL || us_attr[0]== ' ' ||
            memicmp(us_attr,"*NONE",5)   != 0 ||
            memicmp(us_attr,"*BLANKS",7) != 0 ||
            memicmp(us_attr,"*BLANK",6)  != 0)
         memset(us_attr,' ',sizeof(us_attr));

        if (us_text==NULL || us_text[0]== ' ' ||
            memicmp(us_text,"*NONE",5)   != 0  ||
            memicmp(us_text,"*BLANKS",7) != 0  ||
            memicmp(us_text,"*BLANK",6)  != 0)
         memset(us_text,' ',sizeof(us_text));

        if (us_replace!=NULL && us_replace[0]!= ' ' &&
            (memicmp(us_replace,"*YES",4)==0 ||
             memicmp(us_replace,"*REPLACE",8)==0 ||
             us_replace[0]=='1')) {
            memset(us_replace,' ',sizeof(us_replace));
        else {
            memset(us_replace,' ',sizeof(us_replace));

        ec.Bytes_Provided = sizeof(ec);
        QUSCRTUS( us_name, us_attr, us_initSize, &initValue,
                  us_pubAut, us_text, us_replace, &ec);

        if (ec.Bytes_Available == 0 && us_autoExtend=='1') {  // Auto Extend?
          ec.Bytes_Provided = sizeof(ec);
          QUSCUSAT( rtnLib, us_name, &spaceAttr, &ec);

To compile the above source code, use PDM option 14, or the CRTCPGM command.

The Command Definition Source is provided below:

CRTUSRSPC:  CMD        PROMPT('COZZI - Create User Space')

             PARM       KWD(USRSPC) TYPE(QUAL) MIN(1) +
                          PROMPT('User Space')
 QUAL:       QUAL       TYPE(*NAME) MIN(1) EXPR(*YES)
             QUAL       TYPE(*NAME) DFT(*CURLIB) SPCVAL((*LIBL) +
                          (*CURLIB)) EXPR(*YES) PROMPT('Library')
             PARM       KWD(OBJATR) TYPE(*NAME) LEN(10) DFT(*BLANK) +
                          SPCVAL((*BLANK ' ')) EXPR(*YES) +
                          PROMPT('Object attribute') CHOICE('obj attr, *BLANK')
             PARM       KWD(SIZE) TYPE(*INT4) DFT(32K) RANGE(1 +
                          16776704) SPCVAL((1K 1024) (4K 4096) (32K +
                          32768) (1M 1048576) (2M 2097152) +
                          (*MAX16MB 16776704)) CHOICE('size, 1K, +
                          4K, 32K, 1M, 2M...') PROMPT('Initial size')

             PARM       KWD(AUTOEXT) TYPE(*LGL) RSTD(*YES) +
                          DFT(*YES) SPCVAL((*YES '1') (*NO '0')) +
                          EXPR(*YES) PROMPT('Auto extend')
             PARM       KWD(REPLACE) TYPE(*CHAR) RSTD(*YES) DFT(*NO) +
                          SPCVAL((*NO '0') (*YES '1')) EXPR(*YES) +
             PARM       KWD(TEXT) TYPE(*CHAR) LEN(50) DFT(*BLANK) +
                          SPCVAL((*BLANK ' ')) EXPR(*YES) +
                          PROMPT('Text ''description''')
             PARM       KWD(AUT) TYPE(*CHAR) LEN(10) RSTD(*YES) +
                          DFT(*LIBCRTAUT) SPCVAL((*LIBCRTAUT) +
                          (*CHANGE) (*EXCLUDE) (*USE) (*ALL)) +
                          EXPR(*YES) PROMPT('Authority') 

To compile, use PDM option 14 or CRTCMD

Return to midrangenews.com home page.
Sort Ascend | Descend