Hi Bryan,

Since you appear to be running V5R2, there are some ways that you can
simplify your code, please bear with me, and at the end I'll explain how
to get errno. :)

> I have wrapped the sys/stat.h C API as follows
>
>      // Will return 0 if successful and -1 if unsuccessful
>      D lstat           PR            10I 0 EXTPROC('lstat')
>      D  PathName                       *   VALUE
>      D  Buffer                         *   VALUE


A little bit nicer prototype of lstat() would look like this:

     D lstat           PR            10I 0 EXTPROC('lstat')
     D  PathName                       *   VALUE OPTIONS(*STRING)
     D  Buffer                             likeds(info)

a) I added options(*string) to the pathname.  With this specified, you
      do not need to manually append x'00' to the pathname.  (you do
      have to remember to trim trailing blanks, however, but that's
      true in any case)

b) I've changed the Buffer parameter to use the INFO data structure that
      you defined, rather than passing a pointer.  This makes your code
      a little nicer and a little more self-documenting.



> and then added for the pass to buffer a pointer to this
[SNIP]


     D info            DS                  qualified
     D                                     based(prototype_only) <-- added
     D                                     align     <-- added
     D  st_mode                       5U 0
     D  st_ino                       10U 0
     D  st_nlink                      5U 0
     D  st_uid                       10U 0
     D  st_gid                       10U 0
     D  st_size                      10I 0
     D  st_atime                     10I 0
     D  st_mtime                     10I 0
     D  st_ctime                     10I 0
     D  st_dev                       10U 0
     D  st_blksize                   10U 0  <-- changed from 10I -> 10U
     D  st_allocsize                 10U 0  <-- changed from 10I -> 10U
     D  st_objtype                   11A
     D  st_codepage                   5U 0
     D  st_ccsid                      5U 0
     D  st_reserved                  60A
     D  st_ino_gen_id                10U 0

a) I added based(prototype_only) to tell the compiler not to reserve
    memory for this data structure.  You won't want to use it directly,
    you'll only use it as the parameter for likeds()

b) You either need to specify the ALIGN keyword, or you need to add
    fields to push some of the fields out.  In ILE C fields in a data
    structure are aligned based on the field size.  in RPG they are
    not aligned by default, you have to specify the ALIGN keyword.

    (The alternative in this case would be to add a 2-byte field
    after st_nlink, and a 1 byte field after st_objtype to make the
    fields line up properly -- I did this in my copy, since I did it
    before the ALIGN keyword was invented.)

c) size_t is an unsigned field (ssize_t is the signed version) so I
     changed your 10U's to 10I.

>
> and then made the call to lstat by

[SNIP]

due to the changes I made in the prototype, you can now call lstat() like
this:

     D Success         S             10I 0
     D PathName        s            512A     varying
     D FileInfo        ds                    likeds(info)
      /free
          pathname = '/mydir/AFILE.EXT';
          success = lstat(pathname: fileinfo);


> on finding that Success is -1 I want to check errno. How can I pull errno (
> this is a variable that is defined in the errno.h header file ) into my RPG?

There's a function in the QC2LE binding directory called __errno().  It
returns a pointer to the errno variable.  I like to use a simple
subprocedure called "errno" in my RPG programs -- all it does it retrieve
the pointer and then return the value of errno.  Here's the proc:

    P errno           B                   export
    D errno           PI            10I 0
    D sys_errno       PR              *   ExtProc('__errno')
    D p_errno         S               *
    D wwreturn        S             10I 0 based(p_errno)
    C                   eval      p_errno = sys_errno()
    c                   return    wwreturn
    P                 E

Remember, you need to bind to QC2LE to use this procedure...  just insert
it into your H-spec with:

    H BNDDIR('QC2LE')

Once you've got that available, you can use errno like this:

     /free
         msg = 'error #' + %char(errno) + ' occurred.';
     /end-free

Or better yet, you can use the ILE C strerrno() function to get an error
message -- or -- you can get the error message from the QCPFMSG message
file.  The message ID will be CPEnnnn where nnnn is the value of errno.

For more on this topic, see the IFS tutorial on my web page.  I haven't
upgraded it to use the new features of V5R2, so it's not quite as nice as
the code I demonstrated above, but it's still got a lot of useful content:

http://www.scottklement.com/rpg/ifs.html




As an Amazon Associate we earn from qualifying purchases.

This thread ...

Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.