× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



This looks really cool.  Thank you very much.  I'm going to try it out as
soon as I can.

I was looking in the wrong source files in QSYSINC for the constant
definitions.

My motivation was that a co-worker was looking for a way to call java
programs from RPG interactively (v4r5) without having to deal with closing
the QSHELL session, which I think QzshSystem will do.  I bought him off with
doing the calls in a submitted job.

I do understand the C origins of the Unix type apis.  The file apis, for
example, are pretty much the same as standard C low level file I/O.  I'd
just love to see some RPG examples to get an idea how to handle the things
that are more difficult than the data type conversions.  Remember Simon's
fun with printf()?

In order to convert the Unix people, someone has to tell them the apis
exist.  <g>

> -----Original Message-----
> From: Scott Klement [mailto:klemscot@klements.com]
> Sent: Friday, April 05, 2002 2:59 PM
> To: 'rpg400-l@midrange.com'
> Subject: RE: Using the QzshSystem Qshell API
>
>
>
>
> On Fri, 5 Apr 2002, Joel Fritz wrote:
> >
> > I spent an hour or so yesterday trying to find definitions
> for the constants
> > mentioned in the api doc.  Then I had to get back to work. <g>
>
> STRSEU QSYSINC/SYS WAIT will show you the C defs...
>
> >
> > It's one of my pet peeves that a lot of the api
> documentation is C oriented.
> > Makes you think that no one thought anyone would want to
> call them from RPG.
> > Some things like executable macros and functions with
> variable argument
> > lists don't necessarily translate into RPG easily.
> >
>
> Very true.   But, I think the reason that everything is C oriented is
> because it is designed to work just like the Unix version.
> I think the
> hope was that by providing lots of functions that are compatable with
> Unix, they'd be able to find converts from Unix to OS/400.
>
> C is the primary programming language on Unix systems.  In fact, the
> operating system itself is written in C.
>
> At any rate, this whole thread got me really excited about
> QzshSystem().
> (I have worked with waitpid() and the WIFxxxx macros before
> on FreeBSD,
> which is a Unix-type OS, but had never heard of QzshSystem
> until you guys
> mentioned it...)
>
> To a geek like me, being able to run Unix commands in an RPG
> program is
> an intoxicating idea :)
>
> So, I put together an RPG program that works (more or less) the same
> way as the sample C program from the Info Center manuals.  While the
> program itself isn't terribly useful (it does an ls, which
> would be better
> done with the opendir() and readdir() APIs) it's good as an example of
> how to execute a QSHELL command from RPG.
>
> Naturally, you'll want to split out some of the data into
> /copy members
> and service programs, but it's just easier to post the
> example as all one
> member, so here it is:
>
>      H BNDDIR('QC2LE') DFTACTGRP(*NO)
>
>       * The QSHELL APIs:
>       *
>      D QzshSystem      PR            10I 0 extproc('QzshSystem')
>      D   command                       *   value options(*string)
>
>      D QzshCheckShellCommand...
>      D                 PR            10I 0
> extproc('QzshCheckShellCommand')
>      D   command                       *   value options(*string)
>      D   path                          *   value options(*string)
>
>       ** IFS APIs used for simulating STDIN, STDOUT, STDERR
>
>      D open            PR            10I 0 ExtProc('open')
>      D  filename                       *   value options(*string)
>      D  openflags                    10I 0 value
>      D  mode                         10U 0 value options(*nopass)
>      D  codepage                     10U 0 value options(*nopass)
>
>      D close           PR            10I 0 ExtProc('close')
>      D  handle                       10I 0 value
>
>      D unlink          PR            10I 0 ExtProc('unlink')
>      D   path                          *   Value options(*string)
>
>      D O_RDONLY        C                   1
>      D O_WRONLY        C                   2
>      D O_CREAT         C                   8
>      D O_TRUNC         C                   64
>
>       * for retrieving the C error number 'errno':
>       *
>      D @__errno        PR              *   ExtProc('__errno')
>      D strerror        PR              *   ExtProc('strerror')
>      D    errnum                     10I 0 value
>      D p_errno         s               *
>      D errno           S             10I 0 based(p_errno)
>
>       * procedures that act like the C macros from <sys/wait.h>
>       *
>      D WIFEXITED       PR            10I 0
>      D   Status                      10I 0 value
>      D WIFSIGNALED     PR            10I 0
>      D   Status                      10I 0 value
>      D WIFSTOPPED      PR            10I 0
>      D   Status                      10I 0 value
>      D WIFEXCEPTION    PR            10I 0
>      D   Status                      10I 0 value
>      D WEXITSTATUS     PR            10I 0
>      D   Status                      10I 0 value
>      D WSTOPSIG        PR            10I 0
>      D   Status                      10I 0 value
>      D WTERMSIG        PR            10I 0
>      D   Status                      10I 0 value
>      D WEXCEPTNUMBER   PR            10I 0
>      D   Status                      10I 0 value
>      D WEXCEPTMSGID    PR             7A
>      D   Status                      10I 0 value
>
>      D                SDS
>      D  dsJobNo              264    269A
>
>       * Execute an OS/400 command
>      D QCMDEXC         PR                  ExtPgm('QCMDEXC')
>      D   command                    200A   const
>      D   length                      15P 5 const
>
>       * actual example starts here:
>
>      D command         S            100A   varying
>      D s               S             10I 0
>      D msg             S             52A
>      D x               S             10I 0
>
>      c                   exsr      SetupIO
>
>      c                   eval      command = 'ls'
>
>      c                   if
> QzshCheckShellCommand(command:*NULL) = 0
>
>      c                   eval      s = QzshSystem(command)
>
>       * the "exit status" is an integer returned from the
> program we ran.
>       * usually, C programs (at least, on Unix systems) do a
> exit(0) if
>       * they were successful, or exit(1 or higher) if they failed.
>
>      c                   select
>      c                   when      WIFEXITED(s) <> 0
>      c                               and WEXITSTATUS(s) = 0
>      c                   eval      msg = 'Exit status = 0 (success)'
>      c                   dsply                   msg
>
>      c                   when      WIFEXITED(s) <> 0
>      c                   eval      msg = 'Exit status = ' +
>      c                                 %editc(WEXITSTATUS(s): 'N')
>      c                   dsply                   msg
>
>      c                   when      WIFSIGNALED(s) <> 0
>      c                   eval      msg = 'Ended with signal ' +
>      c                                 %editc(WTERMSIG(s): 'N')
>      c                   dsply                   msg
>
>      c                   when      WIFEXCEPTION(s) <> 0
>      c                   eval      msg = 'Ended with error ' +
>      c                                  WEXCEPTMSGID(s)
>      c                   dsply                   msg
>
>      c                   endsl
>
>      c                   else
>
>      c                   eval      p_errno = @__errno
>      c                   eval      msg = %str(strerror(errno))
>      c                   dsply                   msg
>
>      c                   endif
>
>      c                   exsr      CloseIO
>
>      c                   eval      *inlr = *on
>
>
>
>       *===============================================================
>       * File descriptors 0, 1 & 2 are used by unix-environments for
>       *   stdin, stdout & stderr.
>       *
>       * Here we just direct those 3 descriptors to stream files
>       *===============================================================
>      CSR   SetupIO       begsr
>      C*------------------------
>      C* close them if they're open
>      c                   for       x = 0 to 2
>      c                   callp     close(x)
>      c                   endfor
>
>      c                   eval      Msg = *blanks
>
>       * open up 0, 1, 2 as files.
>      c                   if
> open('/dev/qsh-stdin-null':O_RDONLY)<>0
>      c                   eval      Msg = 'unable to open a fake STDIN'
>      c                   endif
>
>      c                   if        open('/tmp/stdout-'+dsJobNo:
>      c
> O_WRONLY+O_CREAT+O_TRUNC: 511)<>1
>      c                   eval      Msg = 'unable to open a
> fake STDOUT'
>      c                   endif
>
>      c                   if        open('/tmp/stderr-'+dsJobNo:
>      c
> O_WRONLY+O_CREAT+O_TRUNC: 511)<>2
>      c                   eval      Msg = 'unable to open a
> fake STDERR'
>      c                   endif
>
>      C* Ack! Something foiled my plans!
>      c                   if        Msg <> *blanks
>      c                   for       x = 0 to 2
>      c                   callp     close(x)
>      c                   dsply                   msg
>      c                   eval      *inlr = *on
>      c                   return
>      c                   endfor
>      c                   endif
>      C*------------------------
>      CSR                 endsr
>
>
>       *===============================================================
>       *  Close the descriptors opened by SetupIO
>       *===============================================================
>      CSR   CloseIO       begsr
>      C*------------------------
>      c                   for       x = 0 to 2
>      c                   callp     close(x)
>      c                   endfor
>
>      c                   callp     QCMDEXC('DSPF
> ''/tmp/stdout-' +dsJobNo+
>      c                                '''': 200)
>
>      c                   callp     unlink('/tmp/stdout-'+dsJobNo)
>      c                   callp     unlink('/tmp/stderr-'+dsJobNo)
>      C*------------------------
>      CSR                 endsr
>
>
>
> *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>       * Evaluates to a non-zero value if child terminated normally.
>       *  #define WIFEXITED(x)     (((x) & 0xFFFF0000) ? 0 :
> 0x00010000)
>
> *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>      P WIFEXITED       B                   export
>      D WIFEXITED       PI            10I 0
>      D   Status                      10I 0 value
>
>      D                 DS
>      D  binary                 1      4I 0
>      D  alpha1                 1      1A
>      D  alpha2                 2      2A
>      D  alpha3                 3      3A
>      D  alpha4                 4      4A
>
>      c                   eval      binary = Status
>      c                   bitoff    x'FF'         alpha3
>      c                   bitoff    x'FF'         alpha4
>      c                   if        binary <> 0
>      c                   return    0
>      c                   else
>      c                   eval      binary = 0
>      c                   biton     x'01'         alpha2
>      c                   return    binary
>      c                   endif
>
>      P                 E
>
>
>
> *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>       * Evaluates to a non-zero value if child terminated abnormally.
>       * #define WIFSIGNALED(x)   ((x) & 0x00020000)
>
> *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>      P WIFSIGNALED     B                   export
>      D WIFSIGNALED     PI            10I 0
>      D   Status                      10I 0 value
>
>      D                 DS
>      D  binary                 1      4I 0
>      D  alpha1                 1      1A
>      D  alpha2                 2      2A
>      D  alpha3                 3      3A
>      D  alpha4                 4      4A
>
>      c                   eval      binary = Status
>      c                   bitoff    x'FF'         alpha1
>      c                   bitoff    x'FD'         alpha2
>      c                   bitoff    x'FF'         alpha3
>      c                   bitoff    x'FF'         alpha4
>      c                   return    binary
>
>      P                 E
>
>
>
> *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>       * Evaluates to a non-zero value if status returned for a stopped
>       * child.
>       * #define WIFSTOPPED(x)    ((x) & 0x00040000)
>
> *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>      P WIFSTOPPED      B                   export
>      D WIFSTOPPED      PI            10I 0
>      D   Status                      10I 0 value
>
>      D                 DS
>      D  binary                 1      4I 0
>      D  alpha1                 1      1A
>      D  alpha2                 2      2A
>      D  alpha3                 3      3A
>      D  alpha4                 4      4A
>
>      c                   eval      binary = Status
>      c                   bitoff    x'FF'         alpha1
>      c                   bitoff    x'FB'         alpha2
>      c                   bitoff    x'FF'         alpha3
>      c                   bitoff    x'FF'         alpha4
>      c                   return    binary
>
>      P                 E
>
>
>
> *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>       * Evaluates to a non-zero value if status returned for a
>       * child process that terminated due to an error state.
>       * #define WIFEXCEPTION(x)  ((x) & 0x00080000)
>
> *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>      P WIFEXCEPTION    B                   export
>      D WIFEXCEPTION    PI            10I 0
>      D   Status                      10I 0 value
>
>      D                 DS
>      D  binary                 1      4I 0
>      D  alpha1                 1      1A
>      D  alpha2                 2      2A
>      D  alpha3                 3      3A
>      D  alpha4                 4      4A
>
>      c                   eval      binary = Status
>      c                   bitoff    x'FF'         alpha1
>      c                   bitoff    x'F7'         alpha2
>      c                   bitoff    x'FF'         alpha3
>      c                   bitoff    x'FF'         alpha4
>      c                   return    binary
>
>      P                 E
>
>
>
> *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>       * Evaluates to the low-order 8 bits from the childs exit status.
>       * #define WEXITSTATUS(x)   (WIFEXITED(x) ? ((x) &
> 0x000000FF) : -1)
>
> *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>      P WEXITSTATUS     B                   export
>      D WEXITSTATUS     PI            10I 0
>      D   Status                      10I 0 value
>
>      D                 DS
>      D  binary                 1      4I 0
>      D  alpha1                 1      1A
>      D  alpha2                 2      2A
>      D  alpha3                 3      3A
>      D  alpha4                 4      4A
>
>      c                   if        WIFEXITED(status) <> 0
>      c                   eval      binary = status
>      c                   bitoff    x'FF'         alpha1
>      c                   bitoff    x'FF'         alpha2
>      c                   bitoff    x'FF'         alpha3
>      c                   return    binary
>      c                   else
>      c                   return    -1
>      c                   endif
>
>      P                 E
>
>
>
> *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>       * Evaluates to the number of the signal that caused the
> child to stop.
>       * #define WSTOPSIG(x)      (WIFSTOPPED(x) ? ((x) &
> 0x0000FFFF) : -1)
>
> *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>      P WSTOPSIG        B                   export
>      D WSTOPSIG        PI            10I 0
>      D   Status                      10I 0 value
>
>      D                 DS
>      D  binary                 1      4I 0
>      D  alpha1                 1      1A
>      D  alpha2                 2      2A
>      D  alpha3                 3      3A
>      D  alpha4                 4      4A
>
>      c                   if        WIFSTOPPED(status) <> 0
>      c                   eval      binary = status
>      c                   bitoff    x'FF'         alpha1
>      c                   bitoff    x'FF'         alpha2
>      c                   return    binary
>      c                   else
>      c                   return    -1
>      c                   endif
>
>      P                 E
>
>
>
> *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>       * Evaluates to the number of the signal that caused the child to
>       * terminate.
>       * #define WTERMSIG(x)      (WIFSIGNALED(x) ? ((x) &
> 0x0000FFFF) : -1)
>
> *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>      P WTERMSIG        B                   export
>      D WTERMSIG        PI            10I 0
>      D   Status                      10I 0 value
>
>      D                 DS
>      D  binary                 1      4I 0
>      D  alpha1                 1      1A
>      D  alpha2                 2      2A
>      D  alpha3                 3      3A
>      D  alpha4                 4      4A
>
>      c                   if        WIFSIGNALED(status) <> 0
>      c                   eval      binary = status
>      c                   bitoff    x'FF'         alpha1
>      c                   bitoff    x'FF'         alpha2
>      c                   return    binary
>      c                   else
>      c                   return    -1
>      c                   endif
>
>      P                 E
>
>
>
> *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>       * Evaluates to the number of the OS/400 Exception that
> caused the
>       * child to terminate.
>       * #define WEXCEPTNUMBER(x) (WIFEXCEPTION(x) ? ((x) &
> 0x0000FFFF) : -1)
>
> *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>      P WEXCEPTNUMBER   B                   export
>      D WEXCEPTNUMBER   PI            10I 0
>      D   Status                      10I 0 value
>
>      D                 DS
>      D  binary                 1      4I 0
>      D  alpha1                 1      1A
>      D  alpha2                 2      2A
>      D  alpha3                 3      3A
>      D  alpha4                 4      4A
>
>      c                   if        WIFEXCEPTION(status) <> 0
>      c                   eval      binary = status
>      c                   bitoff    x'FF'         alpha1
>      c                   bitoff    x'FF'         alpha2
>      c                   return    binary
>      c                   else
>      c                   return    -1
>      c                   endif
>
>      P                 E
>
>
>
> *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>       *  Evaluates to the OS/400 exception msg id for the status code.
>       *  returns *blanks if no exception id is indicated.
>
> *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>      P WEXCEPTMSGID    B                   export
>      D WEXCEPTMSGID    PI             7A
>      D   Status                      10I 0 value
>
>       * Exception numbers returned by WEXCEPTNUMBER() can be
> turned into
>       * exception id's by using the following process:
>       *
>       * If the number returned (in hex) is 0x0000wwyy, and if
> zz is the
>       * decimal conversion of ww, then the exception id is "MCHzzyy".
>       *
>       * Example: WEXCEPTNUMBER(my_status) --> 0x00002401 then the
>       *          exception id would be "MCH3601".
>
>      D cvthc           PR                  extproc('cvthc')
>      D  OutputHex                      *   value
>      D  InputBits                      *   value
>      D  OutputSize                   10I 0 value
>
>      D                 DS
>      D  binary                 1      4I 0
>      D  alpha1                 1      1A
>      D  alpha2                 2      2A
>      D  alpha3                 3      3A
>      D  alpha4                 4      4A
>
>      D                 DS
>      D  cvtbin                 1      2U 0 inz(0)
>      D  cvtalpha               2      2A
>
>      D  dsMsgID        DS
>      D   MCH                   1      3A   inz('MCH')
>      D   first2                4      5A
>      D   last2                 6      7A
>
>
>      c                   eval      binary = WEXCEPTNUMBER(status)
>      c                   if        binary = -1
>      c                   return    *blanks
>      c                   endif
>
>      c                   eval      cvtalpha = alpha3
>      c                   move      cvtbin        first2
>
>      c                   callp     cvthc(%addr(last2):
> %addr(alpha4): 2)
>      c                   return    dsMsgID
>
>      P                 E
>
> _______________________________________________
> This is the RPG programming on the AS400 / iSeries (RPG400-L)
> mailing list
> To post a message email: RPG400-L@midrange.com
> To subscribe, unsubscribe, or change list options,
> visit: http://lists.midrange.com/cgi-bin/listinfo/rpg400-l
> or email: RPG400-L-request@midrange.com
> Before posting, please take a moment to review the archives
> at http://archive.midrange.com/rpg400-l.
>


As an Amazon Associate we earn from qualifying purchases.

This thread ...

Follow-Ups:

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.