Examples: UNIX-type APIs

This simple example program illustrates the use of several integrated file system functions.

Note: Read the Code license and disclaimer information for important legal information.

The program performs the following operations:

(1)
Uses the getuid() function to determine the real user ID (uid).
(2)
Uses the getcwd() function to determine the current directory.
(3)
Uses the open() function to create a file. The owner (the person who created the file) is given read, write, and execute authority to the file.
(4)
Uses the write() function to write a byte string to the file. The file is identified by the file descriptor that was provided in the open operation ((3)).
(5)
Uses the close() function to close the file.
(6)
Uses the open() function to open the file for read only.
(7)
Uses the read() function to read a byte string from the file. The file is identified by the file descriptor that was provided in the open operation ((6)).
(8)
Uses the close() function to close the file.
(9)
Uses the unlink() function to remove the link to the file.

Example in ILE C: Using the Integrated File System

This example program uses the integrated file system from ILE C.

/********************************************************************/
/*                                                                  */
/* Language:            ILE C                                       */
/*                                                                  */
/* Description:         Demonstrate use of integrated file system   */
/*                      from ILE C                                  */
/*                                                                  */
/********************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>


#define BUFFER_SIZE       2048
#define TEST_FILE         "test.file"
#define TEST_DATA         "Hello World!"
#define USER_ID           "user_id_"


char  InitialFile[BUFFER_SIZE];
char  InitialDirectory[BUFFER_SIZE] = ".";
char  Buffer[32];
int   FilDes = -1;
int   BytesRead;
int   BytesWritten;
uid_t UserID;


void CleanUpOnError(int level)
{
   printf("Error encountered, cleaning up.\n");
   switch ( level )
      {
       case 1:
           printf("Could not get current working directory.\n");
           break;
       case 2:
           printf("Could not create file %s.\n",TEST_FILE);
           break;
       case 3:
           printf("Could not write to file %s.\n",TEST_FILE);
           close(FilDes);
           unlink(TEST_FILE);
           break;
       case 4:
           printf("Could not close file %s.\n",TEST_FILE);
           close(FilDes);
           unlink(TEST_FILE);
           break;
       case 5:
           printf("Could not open file %s.\n",TEST_FILE);
           unlink(TEST_FILE);
           break;
       case 6:
           printf("Could not read file %s.\n",TEST_FILE);
           close(FilDes);
           unlink(TEST_FILE);
           break;
       case 7:
           printf("Could not close file %s.\n",TEST_FILE);
           close(FilDes);
           unlink(TEST_FILE);
           break;
       case 8:
           printf("Could not unlink file %s.\n",TEST_FILE);
           unlink(TEST_FILE);
           break;
       default:
           break;
      }
   printf("Program ended with Error.\n"\
          "All test files and directories may not have been removed.\n");
}


int main ()
{
(1)
/* Get and print the real user id with the getuid() function. */
   UserID = getuid();
   printf("The real user id is %u. \n",UserID);

(2)
/* Get the current working directory and store it in InitialDirectory. */
   if ( NULL == getcwd(InitialDirectory,BUFFER_SIZE) )
      {
      perror("getcwd Error");
      CleanUpOnError(1);
      return 0;
      }
   printf("The current working directory is %s. \n",InitialDirectory);

(3)
/* Create the file TEST_FILE for writing, if it does not exist.
   Give the owner authority to read, write, and execute. */
   FilDes = open(TEST_FILE, O_WRONLY | O_CREAT | O_EXCL, S_IRWXU);
   if ( -1 == FilDes )
      {
      perror("open Error");
      CleanUpOnError(2);
      return 0;
      }
   printf("Created %s in directory %s.\n",TEST_FILE,InitialDirectory);

(4)
/* Write TEST_DATA to TEST_FILE via FilDes */
   BytesWritten = write(FilDes,TEST_DATA,strlen(TEST_DATA));
   if ( -1 == BytesWritten )
      {
      perror("write Error");
      CleanUpOnError(3);
      return 0;
      }
   printf("Wrote %s to file %s.\n",TEST_DATA,TEST_FILE);

(5)
/* Close TEST_FILE via FilDes */
   if ( -1 == close(FilDes) )
      {
      perror("close Error");
      CleanUpOnError(4);
      return 0;
      }
   FilDes = -1;
   printf("File %s closed.\n",TEST_FILE);


(6)
/* Open the TEST_FILE file for reading only. */
   if ( -1 == (FilDes = open(TEST_FILE,O_RDONLY)) )
      {
      perror("open Error");
      CleanUpOnError(5);
      return 0;
      }
   printf("Opened %s for reading.\n",TEST_FILE);


(7)
/* Read from the TEST_FILE file, via FilDes, into Buffer. */
   BytesRead = read(FilDes,Buffer,sizeof(Buffer));
   if ( -1 == BytesRead )
      {
      perror("read Error");
      CleanUpOnError(6);
      return 0;
      }
   printf("Read %s from %s.\n",Buffer,TEST_FILE);
   if ( BytesRead != BytesWritten )
      {
      printf("WARNING: the number of bytes read is "\
             "not equal to the number of bytes written.\n");
      }

(8)
/* Close the TEST_FILE file via FilDes. */
   if ( -1 == close(FilDes) )
      {
      perror("close Error");
      CleanUpOnError(7);
      return 0;
      }
   FilDes = -1;
   printf("Closed %s.\n",TEST_FILE);

(9)
/* Unlink the file TEST_FILE */
   if ( -1 == unlink(TEST_FILE) )
      {
      perror("unlink Error");
      CleanUpOnError(8);
      return 0;
      }
   printf("Unlinking file %s.\n",TEST_FILE);


   printf("Program completed successfully.\n");
   return 0;
}

Example in ILE COBOL: Using the Integrated File System

This example program uses the integrated file system from ILE COBOL.

       PROCESS NOMONOPRC.
       IDENTIFICATION DIVISION.
      ***************************************************************
      ***************************************************************
      *
      *  Language:     COBOL
      *
      *  Description:  Demonstrate use of integrated file system
      *                from ILE COBOL
      *
      ***************************************************************
      *
      ***************************************************************
       PROGRAM-ID. IFS.
       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
         SOURCE-COMPUTER. IBM-AS400.
         OBJECT-COMPUTER. IBM-AS400.
         SPECIAL-NAMES.
      *  LINKAGE TYPE PROCEDURE FOR "geterrno",
         LINKAGE TYPE PROCEDURE FOR "getuid",
         LINKAGE TYPE PROCEDURE FOR "getcwd",
         LINKAGE TYPE PROCEDURE FOR "open",
         LINKAGE TYPE PROCEDURE FOR "write",
         LINKAGE TYPE PROCEDURE FOR "close",
         LINKAGE TYPE PROCEDURE FOR "read",
         LINKAGE TYPE PROCEDURE FOR "unlink".
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT LISTING ASSIGN TO PRINTER-QPRINT
                          ORGANIZATION IS SEQUENTIAL.
       DATA DIVISION.
      *
       FILE SECTION.
       FD  LISTING RECORD CONTAINS 132 CHARACTERS
                   LABEL RECORDS ARE STANDARD
                   DATA RECORD IS LIST-LINE.
       01  LIST-LINE        PIC X(132).
      *
       WORKING-STORAGE SECTION.
      *
      * Report lines
      *
       01  REALID.
           05  PRT-TEXT        PIC  X(20) VALUE "The real user id is ".
           05  USER            PIC  X(12).
       01  CURDIR.
           05  PRT-TEXT       PIC  X(21) VALUE "Current directory is ".
           05  INITIALDIR      PIC  X(100).
       01  NEWFIL.
           05  PRT-TEXT        PIC  X(20) VALUE "Created file:       ".
           05  FILENAME        PIC  X(100).
       01  DATAIN.
           05  PRT-TEXT        PIC  X(20) VALUE "Successfully read:  ".
           05  DATA-READ       PIC  X(100).
       01  ERRLIN.
           05  PRT-TEXT        PIC  X(20) VALUE "The errno value is: ".
           05  ERRVAL          PIC  X(12).
      *
      * Miscellaneous elements
      *
       01  BUFFER              PIC  X(32767).
       01  LENGTH-OF-BUFFER    PIC S9(09) BINARY VALUE 32767.
       01  TESTFILE.
           05 TEST-FILE        PIC  X(09) VALUE "test.file".
           05 NULL-TERMINATE   PIC  X(01) VALUE LOW-VALUE.
       01  OFLAG               PIC  X(04) VALUE X"0000001A".
       01  OFLAG-READ          PIC  X(04) VALUE X"00000001".
       01  OMODE               PIC  X(04) VALUE X"000001C0".
       01  TEST-DATA           PIC  X(12) VALUE "Hello World!".
       01  SIZE-TEST-DATA      PIC S9(09) BINARY VALUE 12.
       01  FILE-DESCRIPTOR     PIC S9(09) BINARY.
       01  BYTES-READ          PIC S9(09) BINARY.
       01  BYTES-WRITTEN       PIC S9(09) BINARY.
       01  RETURN-INT          PIC S9(09) BINARY.
       01  RETURN-PTR          POINTER.
      *
      * Beginning of mainline
      *
       PROCEDURE DIVISION.
       MAIN-LINE.
           OPEN OUTPUT LISTING.
      *
      * Get and print the real user id with the getuid function.
      *
           CALL "getuid" GIVING RETURN-INT.
      *
      * Check for error and report status.
      *
           IF RETURN-INT = -1  MOVE "Error getting real user id"
                                     TO LIST-LINE,
                               PERFORM ERROR-FOUND,
                  ELSE         MOVE RETURN-INT TO USER,
                               WRITE LIST-LINE FROM REALID.
      *
      * Get the current working directory and store it in BUFFER
      *
           CALL "getcwd" USING BY VALUE ADDRESS OF BUFFER,
                               BY VALUE LENGTH-OF-BUFFER,
                               GIVING RETURN-PTR.
      *
      * Check for error and report status.
      *
           IF RETURN-PTR = NULL MOVE "Error getting real current dir"
                                     TO LIST-LINE,
                               PERFORM ERROR-FOUND,
                  ELSE         MOVE BUFFER TO INITIALDIR,
                               WRITE LIST-LINE FROM CURDIR.
      *
      * Create the file test.file for writing.  If it does not exist,
      * give the owner authority to read, write, and execute.
      *
           CALL "open"   USING BY VALUE ADDRESS OF TESTFILE,
                               BY VALUE OFLAG,
                               BY VALUE OMODE,
                               GIVING FILE-DESCRIPTOR.
      *
      * Check for error and report status.
      *
           IF FILE-DESCRIPTOR = -1  MOVE "Could not create file"
                                     TO LIST-LINE,
                               PERFORM ERROR-FOUND,
                  ELSE         MOVE TEST-FILE TO FILENAME,
                               WRITE LIST-LINE FROM NEWFIL.
      *
      * Write TEST-DATA to test.file via file descriptor from open
      *
           CALL "write"  USING BY VALUE FILE-DESCRIPTOR,
                               BY VALUE ADDRESS OF TEST-DATA,
                               BY VALUE SIZE-TEST-DATA,
                               GIVING BYTES-WRITTEN.
      *
      * Check for error and report status.
      *
           IF BYTES-WRITTEN = -1  MOVE "Could not write to file"
                                     TO LIST-LINE,
                               PERFORM ERROR-FOUND,
                  ELSE         MOVE "Wrote to file successfully"
                                     TO LIST-LINE,
                               WRITE LIST-LINE.
      *
      * Close test.file via file descriptor
      *
           CALL "close"  USING BY VALUE FILE-DESCRIPTOR,
                               GIVING RETURN-INT.
      *
      * Check for error and report status.
      *
           IF RETURN-INT    = -1  MOVE "Could not close file"
                                     TO LIST-LINE,
                               PERFORM ERROR-FOUND,
                  ELSE         MOVE "Successfully closed file"
                                     TO LIST-LINE,
                               WRITE LIST-LINE.
      *
      * Open the file test.file for reading.
      *
           CALL "open"   USING BY VALUE ADDRESS OF TESTFILE,
                               BY VALUE OFLAG-READ,
                               GIVING FILE-DESCRIPTOR.
      *
      * Check for error and report status.
      *
           IF FILE-DESCRIPTOR = -1  MOVE "Could not open file"
                                     TO LIST-LINE,
                               PERFORM ERROR-FOUND,
                  ELSE         MOVE "File open successful"
                                     TO LIST-LINE,
                               WRITE LIST-LINE.
      *
      * Read from test.file via file descriptor from open
      *
           CALL "read"   USING BY VALUE FILE-DESCRIPTOR,
                               BY VALUE ADDRESS OF BUFFER,
                               BY VALUE LENGTH-OF-BUFFER,
                               GIVING BYTES-READ.
      *
      * Check for error and report status.
      *
           IF BYTES-READ = -1  MOVE "Read failed"
                                     TO LIST-LINE,
                               PERFORM ERROR-FOUND,
                  ELSE  IF BYTES-READ = BYTES-WRITTEN
                               MOVE BUFFER TO DATA-READ,
                               WRITE LIST-LINE FROM DATAIN,
                        ELSE MOVE "Data Truncation on Read"
                                  TO LIST-LINE,
                               PERFORM ERROR-FOUND.
      *
      * Close test.file via file descriptor
      *
           CALL "close"  USING BY VALUE FILE-DESCRIPTOR,
                               GIVING RETURN-INT.
      *
      * Check for error and report status.
      *
           IF RETURN-INT    = -1  MOVE "Could not close file"
                                     TO LIST-LINE,
                               PERFORM ERROR-FOUND,
                  ELSE         MOVE "Successfully closed file"
                                     TO LIST-LINE,
                               WRITE LIST-LINE.
      *
      * Unlink test.file
      *
           CALL "unlink"  USING BY VALUE ADDRESS OF TESTFILE,
                               GIVING RETURN-INT.
      *
      * Check for error and report status.
      *
           IF RETURN-INT    = -1  MOVE "Unlink of file failed"
                                     TO LIST-LINE,
                               PERFORM ERROR-FOUND,
                  ELSE         MOVE "Unlink of file successful"
                                     TO LIST-LINE,
                               WRITE LIST-LINE.
      *
           MOVE "Program run is successful" TO LIST-LINE.
           WRITE LIST-LINE.
           STOP RUN.
      *
      * End of MAINLINE
      *
      *
      * Common error reporting subroutine
      *
      * If errors occur, the Integrated File System exports the
      * variable 'errno' to assist in determining the problem.  As
      * 'errno' is lowercase, ILE COBOL cannot directly import this
      * variable and must use a C module to access it.  If the
      * developer has ILE C available, the following sample C code
      * will import 'errno' and make it available to the COBOL
      * application
      *
      *       #include <errno.h>
      *       int geterrno()
      *       {
      *         return errno;
      *       }
      *
      * To activate this C module remove the comment identifiers
      * following the WRITE statement and remove the comment
      * identifier from the geterrno declaration in the Configuration
      * Section.  Definitions for the returned errno are found in
      * file QSYSINC/SYS member ERRNO.
      *
       ERROR-FOUND.
           WRITE LIST-LINE.
      *    CALL "geterrno" GIVING RETURN-INT.
      *    MOVE RETURN-INT TO ERRVAL.
      *    WRITE LIST-LINE FROM ERRLIN.
           STOP RUN.

Example in ILE RPG: Using the Integrated File System

This example program uses the integrated file system from ILE RPG.

     F********************************************************************
     F*
     F*   Language:     ILE RPG
     F*
     F*   Description:  Demonstrate use of integrated file system
     F*                 from ILE RPG
     F*
     F********************************************************************
     FQSYSPRT   O    F  132        PRINTER
     D*
     D* Prototype the Integrated File System APIs
     D*
     Dgetuid           PR             9B 0 EXTPROC('getuid')
     Dgetcwd           PR              *   EXTPROC('getcwd')
     D                                 *   VALUE
     D                                9B 0 VALUE
     Dopen             PR             9B 0 EXTPROC('open')
     D                                 *   VALUE
     D                                4A   VALUE
     D                                4A   VALUE
     Dwrite            PR             9B 0 EXTPROC('write')
     D                                9B 0 VALUE
     D                                 *   VALUE
     D                                9B 0 VALUE
     Dclose            PR             9B 0 EXTPROC('close')
     D                                9B 0 VALUE
     Dopen2            PR             9B 0 EXTPROC('open')
     D                                 *   VALUE
     D                                4A   VALUE
     Dread             PR             9B 0 EXTPROC('read')
     D                                9B 0 VALUE
     D                                 *   VALUE
     D                                9B 0 VALUE
     Dunlink           PR             9B 0 EXTPROC('unlink')
     D                                 *   VALUE
     D*
     D* errno prototype; see error subroutine for further information
     D*
     D*errno           PR             9B 0 EXTPROC('geterrno')
     DUser             S             12A
     DBuffer           S          32767A
     DReturnPtr        S               *
     DReturnInt        S              9B 0
     DFileDesc         S              9B 0
     Dtest_file        S           2048A   INZ('test.file')
     DInitialDir       S           2048A
     Dtest_data        S             12A   INZ('Hello World!')
     DBytesWrt         S              9B 0
     DBytesRead        S              9B 0
     DFileName         S           2049A
     DPrintLine        S            100A
     DNull             C                   CONST(X'00')
     C*
     C* Get and print the real user id with the getuid function.
     C*
     C                   eval      ReturnInt = getuid
     C*
     C* Check for error and report status.
     C*
     C                   if        ReturnInt = -1
     C                   eval      PrintLine = 'Error getting real user id'
     C                   exsr      error
     C                   eval      *INLR = '1'
     C                   return
     C                   else
     C                   move      ReturnInt     User
     C                   eval      PrintLine = 'The real user id is '
     C                                 + %TRIML(User)
     C                   except
     C                   endif
     C*
     C* Get the current working directory and store it in Buffer.
     C*
     C                   eval      ReturnPtr=getcwd(%ADDR(Buffer)
     C                               : %SIZE(Buffer))
     C*
     C* Check for error and report status.
     C*
     C                   if        ReturnPtr = *NULL
     C                   eval      PrintLine = 'Error getting current directory'
     C                   exsr      error
     C                   eval      *INLR = '1'
     C                   return
     C                   else
     C*
     C* Print current directory name remembering to scan for null terminator.
     C*
     C     Null          scan      Buffer        NullFound         5 0
     C                   eval      InitialDir = %SUBST(Buffer&#58;1&#58;NullFound)
     C                   eval      PrintLine = 'Current Directory is '
     C                               + InitialDir
     C                   except
     C                   endif
     C*
     C* Create the file TEST_FILE for writing.  If it does not exist,
     C* give the owner authority to read, write, and execute.
     C*
     C                   eval      FileName = %TRIMR(test_file) + Null
     C                   eval      FileDesc = open(%ADDR(FileName)
     C                               : x'0000001A' : x'000001C0')
     C*
     C* Check for error and report status.
     C*
     C                   if        FileDesc = -1
     C                   eval      PrintLine = 'Could not create file'
     C                   exsr      error
     C                   eval      *INLR = '1'
     C                   return
     C                   else
     C                   eval      PrintLine = 'File '
     C                               + %TRIMR(test_file)
     C                               + ' created successfully'
     C                   except
     C                   end
     C*
     C* Write test_data to test_file via FileDesc returned by open
     C*
     C                   eval      BytesWrt = write(FileDesc
     C                               : %ADDR(Test_Data)
     C                               : %SIZE(Test_Data))
     C*
     C* Check for error and report status.  If an error occurs,
     C* attempt cleanup.
     C*
     C                   if        BytesWrt = -1
     C                   eval      PrintLine = 'Could not write to file'
     C                   exsr      error
     C                   eval      ReturnInt = close(FileDesc)
     C                   eval      ReturnInt = unlink(%ADDR(FileName))
     C                   eval      *INLR = '1'
     C                   return
     C                   else
     C                   eval      PrintLine = 'Wrote to '
     C                               + %TRIMR(test_file)
     C                               + ' successfully'
     C                   except
     C                   endif
     C*
     C* Close test_file via FileDesc
     C*
     C                   eval      ReturnInt = close(FileDesc)
     C*
     C* Check for error and report status.  If an error occurs,
     C* attempt cleanup.
     C*
     C                   if        ReturnInt = -1
     C                   eval      PrintLine = 'Could not close file'
     C                   exsr      error
     C                   eval      ReturnInt = close(FileDesc)
     C                   eval      ReturnInt = unlink(%ADDR(FileName))
     C                   eval      *INLR = '1'
     C                   return
     C                   else
     C                   eval      PrintLine = 'File '
     C                               + %TRIMR(test_file)
     C                               + ' closed successfully'
     C                   except
     C                   endif
     C*
     C* Open the file for read only
     C*
     C                   eval      FileDesc = open2(%ADDR(FileName)
     C                               : x'00000001')
     C*
     C* Check for error and report status.  If an error occurs,
     C* attempt cleanup.
     C*
     C                   if        FileDesc = -1
     C                   eval      PrintLine = 'Open of file failed'
     C                   exsr      error
     C                   eval      ReturnInt = unlink(%ADDR(FileName))
     C                   eval      *INLR = '1'
     C                   return
     C                   else
     C                   eval      PrintLine = 'Open of file successful'
     C                   except
     C                   endif
     C*
     C* Read from file
     C*
     C                   eval      BytesRead = read(FileDesc
     C                               : %ADDR(Buffer) : %SIZE(Buffer))
     C*
     C* Check for error and report status.  If an error occurs,
     C* attempt cleanup.
     C*
     C                   if        BytesRead = -1
     C                   eval      PrintLine = 'Read failed'
     C                   exsr      error
     C                   eval      ReturnInt = close(FileDesc)
     C                   eval      ReturnInt = unlink(%ADDR(FileName))
     C                   eval      *INLR = '1'
     C                   return
     C                   else
     C                   if        BytesRead = BytesWrt
     C                   eval      PrintLine = 'Data successfully read: '
     C                                + %TRIMR(Buffer)
     C                   else
     C                   eval      PrintLine = 'Data truncation on read'
     C                   endif
     C                   except
     C                   endif
     C*
     C* Close the LinkName file
     C*
     C                   eval      ReturnInt = close(FileDesc)
     C*
     C* Check for error and report status.  If an error occurs,
     C* attempt cleanup.
     C*
     C                   if        ReturnInt = -1
     C                   eval      PrintLine = 'Close of link failed'
     C                   exsr      error
     C                   eval      ReturnInt = close(FileDesc)
     C                   eval      ReturnInt = unlink(%ADDR(FileName))
     C                   eval      *INLR = '1'
     C                   return
     C                   else
     C                   eval      PrintLine = 'Close of link successful'
     C                   except
     C                   endif
     C*
     C* Unlink test_file
     C*
     C                   eval      ReturnInt = unlink(%ADDR(FileName))
     C*
     C* Check for error and report status.  If an error occurs,
     C* attempt cleanup.
     C*
     C                   if        ReturnInt = -1
     C                   eval      PrintLine = 'Unlink of file failed'
     C                   exsr      error
     C                   eval      ReturnInt = unlink(%ADDR(FileName))
     C                   eval      *INLR = '1'
     C                   return
     C                   else
     C                   eval      PrintLine = 'Unlink of file successful'
     C                   except
     C                   endif
     C*
     C* End of main program
     C*
     C                   eval      PrintLine = 'Program run is successful'
     C                   except
     C                   eval      *INLR = '1'
     C                   return
     C*
     C* Common error reporting subroutine
     C*
     C* If errors occur, the integrated file system exports the variable
     C* 'errno' to assist in determining the problem.  As 'errno' is
     C* lowercase, ILE RPG cannot directly import this variable and must
     C* use a C module to access it.  If the developer has ILE C
     C* available, the following sample C code will import 'errno' and
     C* make it available to the RPG application.
     C*
     C*     #include <errno.h>
     C*     int geterrno()
     C*     {
     C*       return errno;
     C*     }
     C*
     C* To activate this C module, remove the four comment identifiers
     C* following the 'except' statement and remove the comment identifier
     C* from the errno prototype.  Definitions for the returned errno
     C* are found in the file QSYSINC/SYS member ERRNO.
     C*
     C     error         begsr
     C                   except
     C*                  eval      ReturnInt = errno
     C*                  move      ReturnInt     Errnoval          9
     C*                  eval      PrintLine = 'Errno is ' + Errnoval
     C*                  except
     C                   eval      PrintLine = 'Program ended in error'
     C                   except
     C                   endsr
     OQSYSPRT   E                           1
     O                       PrintLine          100