Giovanni's logo
Supporting program state through User Spaces
this means Version 2
power search
blue line
1. Introduction

Non-persistent CGI are "stateless". In other words, the browser connects to the server, makes a request (calls a CGI), receives the response, then disconnects from the server. On the next request from the same browser, there is no guarantee that the same program has maintaned the state (variables and record positioning) it was left with at the end of the previous request.

In such a stateless situation, the developer has to implement some "tricks" to restore some variables on the next call to the CGI, such as

  • using hidden input fields in the HTML forms
  • writing and retrieving cookies

Sometimes, however, when designing complex transactions, these rather simple tricks may not be sufficient to fulfill state requirements and a programmer would be tempted to use "persistent" CGI instead. However, persistent CGI have their own problems.

In those cases, better methods for storing and retrieving state information are required.

2. User spaces

iSeries user spaces objects are ideal for this purpose:

  • Each user space can hold up to 16 MB of information
  • System APIs are provided to create a user space, change its attributes (including making it automatically extendible, retrieve a pointer to it, etc.)
  • Once addressability to a user space (a pointer) has been established, one can map, using based variables, many types of data into it, including data structures
  • Saving and restoring user state information can be accomplished as follow:
    • at the start of the transaction, create a uniquely named user space,
    • use based variable(s) to map the user's data into the space,
    • send an HTTP response to the user, including a hidden field containing the user space name,
    • when the user makes a request using the form that contains the hidden user space name, use that name to retrieve a pointer to the user space, thus restoring addressability to the user space's contents using the same based variables that were used to store them.

3. User space procedures
  1. Subprocedure "CrtUsrSpc" - Create an User Space
    It creates a randomly named, automatically extendible user space in a user-specified library. The user space's contents are initialized to all x'00's.


    • User space library (input)
      • If the library not found, CrtUsrSpc sets the user space name to blanks and MsgId to CPF9810
      • If the requestor does not have change authority to the library, CrtUsrSpc sets the user space name to blanks and MsgId to CPF2144
    • Pointer to user space (output)
      • Set to null if the user space is not created
    • Message ID (output)
      • blank if no errors
      • else, message id of error

    Optional Parameters

    • Public authority (input)
      • If not passed, it is set to *EXCLUDE
    • Text (input)
      • If not passed, it is set to 'Created by CGIDEV2' plus timestamp
    • Initial size (input)
      • If not passed, it is set to 12288
    • Extended attribute
      • If not passed, it is set to blanks


    • If successful
      • User space name
    • Otherwise
      • Blanks

    Errors in system APIs

    • If any of the called system APIs fails, a message is forced into the CGIDEBUG file.

     * Input variables
    D AnEntry         s             40    varying
     * User space
    D UsrSpcName      s             10
    D UsrSpcLib       c                   'CGIDEV2USP'
    * Message ID for CrtUsrSpc
    D MsgId           s              7
    * State related variables (user space contents)
    D State           ds                  based(StateP)
    D  Count                        10i 0
    D  Entries                    1000    varying
    C                   eval      UsrSpcName= CrtUsrSpc(
    C                               UsrSpcLib : StateP : MsgID)
    In this example, a user space is created in library CGIDEV2USP and its name is loaded into variable "UsrSpcName".

  2. Subprocedure "RtvUsrSpcPtr" - Retrieve Pointer to User Space


    • User space name (input)
    • User space library (input)


    • If successful
      • Pointer to the user space
    • Otherwise
      • Null pointer

    Errors in system APIs

    • If any of the called system APIs fails, a message is forced into the CGIDEBUG file.

    C                   eval      StateP = RtvUsrSpcPtr(UsrSpcName:
    C                             UsrSpcLib)
    C                   if        StateP = *null
                        ... ...
    C                   endif
    In this example, the contents of the user space are made accessible via data structure "State".

    To update the contents of the user space, one should just update the data structure "State":
    C                   eval      AnEntry = ZhbGetVar('AnEntry')
    C                   if        AnEntry <> ''
    C                   eval      Count = Count + 1
    C                   eval      Entries = Entries + '<br>' + AnEntry
    C                   endif

4. Sample program
CGI program STATE demonstrates the use of user space to maintain program state information.
In this programs, the user may enter, one at a time, several inputs. The inputs are saved in a user space. The user space contents are displayed to the user.