ILEC

Good example ILE C code calling PASE utilities using PASE libc.a popen(‘pase command’,’r’).

#include <stdio.h>
#include <qp2user.h>
#include <qtqiconv.h>
#define JOB_CCSID 0


static iconv_t to_conv;
static iconv_t from_conv;
static int pase_running;
static QP2_ptr64_t pase_libc_id;
static void *pase_popen_func;
static void *pase_pclose_func;
static void *pase_fgets_func;

void ile_iconv_open(void) {
  char from_ilecode[32] = "IBMCCSID000370000000";
  char to_pasecode[32]   = "IBMCCSID01208";
  char from_pasecode[32] = "IBMCCSID012080000000";
  char to_ilecode[32]   = "IBMCCSID00037";
  /* convert (tocode, fromcode)*/
  to_conv = iconv_open(to_pasecode, from_ilecode);
  from_conv = iconv_open(to_ilecode, from_pasecode);
}

size_t ile_iconv_to_pase(char *srcptr, size_t srclen, 
              char *dstptr, size_t dstlen)
{
  char * iconv_srcptr = srcptr;
  char * iconv_dstptr = dstptr;
  size_t iconv_srclen = srclen;
  size_t iconv_dstlen = dstlen;

  iconv(to_conv, &iconv_srcptr, &iconv_srclen, 
              &iconv_dstptr, &iconv_dstlen);

  return iconv_srclen;
}
size_t ile_iconv_from_pase(char *srcptr, size_t srclen, 
              char *dstptr, size_t dstlen)
{
  char * iconv_srcptr = srcptr;
  char * iconv_dstptr = dstptr;
  size_t iconv_srclen = srclen;
  size_t iconv_dstlen = dstlen;

  iconv(from_conv, &iconv_srcptr, &iconv_srclen, 
              &iconv_dstptr, &iconv_dstlen);

  return iconv_srclen;
}

void ile_iconv_close(void) {
  if (to_conv.cd) iconv_close(to_conv);
  if (from_conv.cd) iconv_close(from_conv);
}

void pase_start(void) {
  char * iarg0 = "/usr/lib/start32";
  char * iarg[10];
  char * ienv0 = "PASE_THREAD_ATTACH=Y";
  char * ienv[10];
  int paseCCSID = 819;

  /* start pase /usr/lib/start32 (start32 leave active) */
  if (!pase_running) {

    ile_iconv_open();

    iarg[0] = iarg0;
    iarg[1] = NULL;
    ienv[0] = ienv0;
    ienv[1] = NULL;
    pase_running = Qp2RunPase(iarg0, NULL, NULL, 
                  0, paseCCSID, 
                  (const char  *const *)&iarg, 
                  (const char  *const *) &ienv);
  }
}

void pase_stop(void) {
  if (pase_libc_id) {
    Qp2dlclose(pase_libc_id);
  }
  if (pase_running) {
    Qp2EndPase();
    ile_iconv_close();
  }
}

/* libc.a id (PASE APIs like popen) */
QP2_ptr64_t pase_libc(void) {
  pase_start();
  if (!pase_libc_id) {
    pase_libc_id = Qp2dlopen(NULL, QP2_RTLD_NOW, JOB_CCSID);
  }
  return pase_libc_id;
}

/* FILE *popen(const char *command, const char *mode); */
QP2_ptr32_t pase_popen(char *command, char *mode) {
  int rc;
  const QP2_arg_type_t parm_sig[] = 
  { QP2_ARG_PTR32, QP2_ARG_PTR32, QP2_ARG_END };
  struct {
    QP2_ptr32_t command;
    QP2_ptr32_t mode;
    void * pcommand;
    void * pmode;
  } parm_val;
  int ret_sig = QP2_RESULT_PTR32;
  QP2_ptr32_t ret_val;
  QP2_ptr64_t temp_malloc;
  size_t commandlen, modelen;

  if (!pase_popen_func) {
    pase_popen_func = Qp2dlsym(pase_libc(), 
                   "popen", JOB_CCSID, NULL);
  }
  commandlen = strlen(command);
  parm_val.pcommand = Qp2malloc(commandlen+1, &temp_malloc);
  parm_val.command = (QP2_ptr32_t) temp_malloc;
  modelen = strlen(mode);
  parm_val.pmode = Qp2malloc(modelen+1, &temp_malloc);
  parm_val.mode = (QP2_ptr32_t) temp_malloc;
  ile_iconv_to_pase(command, commandlen, 
                parm_val.pcommand, commandlen+1);
  ile_iconv_to_pase(mode, modelen, 
                parm_val.pmode, modelen);
  rc = Qp2CallPase(pase_popen_func,
                   &parm_val,
                    parm_sig,
                    ret_sig,
                   &ret_val);
  Qp2free(parm_val.pcommand);
  Qp2free(parm_val.pmode);
  return ret_val;
}

/* int pclose(FILE *stream); */
QP2_word_t pase_pclose(QP2_ptr32_t stream) {
  int rc;
  const QP2_arg_type_t parm_sig[] = 
  { QP2_ARG_PTR32, QP2_ARG_END };
  struct {
    QP2_ptr32_t stream;
  } parm_val;
  int ret_sig = QP2_RESULT_WORD;
  QP2_word_t ret_val;

  if (!pase_pclose_func) {
    pase_pclose_func = Qp2dlsym(pase_libc(), 
                    "pclose", JOB_CCSID, NULL);
  }
  parm_val.stream = stream;
  rc = Qp2CallPase(pase_pclose_func,
                   &parm_val,
                    parm_sig,
                    ret_sig,
                   &ret_val);
  return ret_val;
}

/* char *fgets(char *s, int size, FILE *stream); */
QP2_ptr32_t pase_fgets(char *buf, int size, QP2_ptr32_t stream) {
  int rc;
  const QP2_arg_type_t parm_sig[] = 
  { QP2_ARG_PTR32, QP2_ARG_WORD, QP2_ARG_PTR32, QP2_ARG_END };
  struct {
    QP2_ptr32_t buf;
    QP2_word_t size;
    QP2_ptr32_t stream;
    void * pbuf;
  } parm_val;
  int ret_sig = QP2_RESULT_PTR32;
  QP2_ptr32_t ret_val;
  QP2_ptr64_t temp_malloc;
  int pase_size;

  if (!pase_fgets_func) {
    pase_fgets_func = Qp2dlsym(pase_libc(), 
                   "fgets", JOB_CCSID, NULL);
  }
  parm_val.pbuf = Qp2malloc(size, &temp_malloc);
  parm_val.buf = (QP2_ptr32_t) temp_malloc;
  parm_val.size = size;
  parm_val.stream = stream;
  rc = Qp2CallPase(pase_fgets_func,
                   &parm_val,
                    parm_sig,
                    ret_sig,
                   &ret_val);
  memset(buf, 0, size);
  if (ret_val) {
    pase_size = strlen(parm_val.pbuf);
    ile_iconv_from_pase(parm_val.pbuf, pase_size, 
                        buf, pase_size);
  }
  Qp2free(parm_val.pbuf);
  return ret_val;
}


int main(int argc, char *argv[])
{
  int rc;
  QP2_ptr32_t fp = 0;
  char buf[4096];

  /* start pase */
  pase_start();

  /* FILE *popen(const char *command, const char *mode); */
  fp = pase_popen("ls /QOpenSys", "r");

  /* char *fgets(char *s, int size, FILE *stream); */
  while (pase_fgets(buf, 4096, fp)) {
    printf("%s",buf);
  }

  /* int pclose(FILE *stream); */
  rc = pase_pclose(fp);

  /* stop pase */
  pase_stop();

  return 0;
}