我正在尝试用控制语言编写一个程序,该程序在调用使用它的Java实用程序之前在IFS中创建和填充配置文件。
我已成功调用open()和close()API来(重新)创建文件但是对于我的生活,我无法使用write()将某些内容放入文件中。到目前为止,它一直是一种学习经验,但是在write()调用中没有错误消息,我无法查看我的问题所在。
这几乎可以肯定我处理变量的方式,但调试会话表明它们应该是它们应该是。
/* ========================================================================= */
/* Processing for the PRCMQMSG command */
/* ========================================================================= */
PGM PARM(&ACTION &SRCMQ &TGTMQ)
/* Input parameters */
DCL VAR(&ACTION) TYPE(*CHAR) LEN(5)
DCL VAR(&SRCMQ) TYPE(*CHAR) LEN(125)
DCL VAR(&TGTMQ) TYPE(*CHAR) LEN(125)
/* Parameter elements */
DCL VAR(&SRCHOST) TYPE(*CHAR) STG(*DEFINED) +
LEN(30) DEFVAR(&SRCMQ 3)
DCL VAR(&SRCPORT) TYPE(*DEC) STG(*DEFINED) +
LEN(5) DEFVAR(&SRCMQ 33)
DCL VAR(&SRCQMGR) TYPE(*CHAR) STG(*DEFINED) +
LEN(30) DEFVAR(&SRCMQ 36)
DCL VAR(&SRCCHNL) TYPE(*CHAR) STG(*DEFINED) +
LEN(30) DEFVAR(&SRCMQ 66)
DCL VAR(&SRCQUE) TYPE(*CHAR) STG(*DEFINED) +
LEN(30) DEFVAR(&SRCMQ 96)
DCL VAR(&TGTHOST) TYPE(*CHAR) STG(*DEFINED) +
LEN(30) DEFVAR(&TGTMQ 3)
DCL VAR(&TGTPORT) TYPE(*DEC) STG(*DEFINED) +
LEN(5) DEFVAR(&TGTMQ 33)
DCL VAR(&TGTQMGR) TYPE(*CHAR) STG(*DEFINED) +
LEN(30) DEFVAR(&TGTMQ 36)
DCL VAR(&TGTCHNL) TYPE(*CHAR) STG(*DEFINED) +
LEN(30) DEFVAR(&TGTMQ 66)
DCL VAR(&TGTQUE) TYPE(*CHAR) STG(*DEFINED) +
LEN(30) DEFVAR(&TGTMQ 96)
/* IFS details */
DCL VAR(&PATH) TYPE(*CHAR) LEN(128) +
VALUE('/mqutil')
DCL VAR(&CFGFILE) TYPE(*CHAR) LEN(20)
DCL VAR(&JOB) TYPE(*CHAR) LEN(6)
/* IFS API flags */
DCL VAR(&O_RDONLY) TYPE(*INT) VALUE(1)
DCL VAR(&O_WRONLY) TYPE(*INT) VALUE(2)
DCL VAR(&O_RDWR) TYPE(*INT) VALUE(4)
DCL VAR(&O_CREAT) TYPE(*INT) VALUE(8)
DCL VAR(&O_EXCL) TYPE(*INT) VALUE(16)
DCL VAR(&O_TRUNC) TYPE(*INT) VALUE(64)
DCL VAR(&O_APPEND) TYPE(*INT) VALUE(256)
DCL VAR(&O_CODEPAGE) TYPE(*INT) VALUE(8388608)
DCL VAR(&O_TEXTDATA) TYPE(*INT) VALUE(16777216)
DCL VAR(&S_IRUSR) TYPE(*INT) VALUE(256)
DCL VAR(&S_IWUSR) TYPE(*INT) VALUE(128)
DCL VAR(&S_IXUSR) TYPE(*INT) VALUE(64)
DCL VAR(&S_IRWXU) TYPE(*INT) VALUE(448)
DCL VAR(&S_IRGRP) TYPE(*INT) VALUE(32)
DCL VAR(&S_IWGRP) TYPE(*INT) VALUE(16)
DCL VAR(&S_IXGRP) TYPE(*INT) VALUE(8)
DCL VAR(&S_IRWXG) TYPE(*INT) VALUE(56)
DCL VAR(&S_IROTH) TYPE(*INT) VALUE(4)
DCL VAR(&S_IWOTH) TYPE(*INT) VALUE(2)
DCL VAR(&S_IXOTH) TYPE(*INT) VALUE(1)
DCL VAR(&S_IRWXO) TYPE(*INT) VALUE(7)
/* IFS API parameters */
DCL VAR(&STROPN) TYPE(*INT) /* Open flags */
DCL VAR(&STRMODE) TYPE(*INT) /* Mode flags */
DCL VAR(&STRPATH) TYPE(*CHAR) LEN(149)
DCL VAR(&STRCODEP) TYPE(*INT) VALUE(819)
DCL VAR(&STRHAND) TYPE(*INT)
DCL VAR(&NULL) TYPE(*CHAR) LEN(1) VALUE(X'00')
DCL VAR(&CRLF) TYPE(*CHAR) LEN(2) VALUE(X'0D25')
DCL VAR(&ERRNO_PTR) TYPE(*PTR)
DCL VAR(&ERRNO) TYPE(*INT) STG(*BASED) +
BASPTR(&ERRNO_PTR)
DCL VAR(&ERRNO_CHR) TYPE(*CHAR) LEN(4)
DCL VAR(&MSGID) TYPE(*CHAR) LEN(7)
DCL VAR(&LINE) TYPE(*CHAR) LEN(250)
DCL VAR(&LINE_PTR) TYPE(*PTR) ADDRESS(&LINE)
DCL VAR(&LINELEN) TYPE(*UINT)
DCL VAR(&LINELEN_D) TYPE(*DEC) LEN(5 0)
/* Create and open a configuration file in the IFS */
RTVJOBA NBR(&JOB)
CHGVAR VAR(&CFGFILE) VALUE('mqconf_' |< &JOB)
CHGVAR VAR(&STRPATH) VALUE(&PATH |< '/' |< &CFGFILE +
|< '.connection' |< &NULL)
CHGVAR VAR(&STROPN) VALUE(&O_WRONLY + &O_CREAT + +
&O_TRUNC + &O_CODEPAGE + &O_TEXTDATA)
CHGVAR VAR(&STRMODE) VALUE(&S_IRWXU + &S_IRWXG + +
&S_IROTH)
CALLPRC PRC('open') PARM((&STRPATH) (&STROPN *BYVAL) +
(&STRMODE *BYVAL) (&STRCODEP *BYVAL)) +
RTNVAL(&STRHAND)
IF COND(&STRHAND = -1) THEN(DO)
CALLPRC PRC('__errno') RTNVAL(&ERRNO_PTR)
CHGVAR VAR(&ERRNO_CHR) VALUE(&ERRNO)
CHGVAR VAR(&MSGID) VALUE('CPE' || &ERRNO_CHR)
SNDPGMMSG MSGID(&MSGID) MSGF(QCPFMSG) MSGTYPE(*ESCAPE)
ENDDO
/* Write a line to the file */
CHGVAR VAR(&LINE) VALUE('This is a line of text in +
a file.' |< &CRLF)
RTVMSG MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA(&LINE) +
MSGLEN(&LINELEN_D)
CHGVAR VAR(&LINELEN) VALUE(&LINELEN_D)
CALLPRC PRC('write') PARM((&STRHAND *BYREF) +
(&LINE_PTR *BYREF) (&LINELEN *BYVAL))
/* Close the configuration file */
CALLPRC PRC('close') PARM((&STRHAND *BYVAL))
ENDPGM
我曾尝试以与&amp; ERRNO和&amp; ERRNO_PTR相同的方式声明&amp; LINE和&amp; LINE_PTR变量,但当我尝试将值分配给&amp; LINE时,这给了我一个指针未设置错误。我认为那是因为首先访问&amp; ERRNO_PTR,而对于&amp; LINE_PTR则不是这种情况。无论如何,这可能是一个红鲱鱼。
RTVMSG命令是查找不包括尾随空格的字符串长度的技巧。
我在调试中运行代码,在调用write()&amp; LINE之前包含了我期望的内容,和&amp; LINELEN是35,然后调用write()并且没有错误但是文件中也不存在该行。该文件仍为空。
最后一点。该程序的所有参数目前尚未使用,但我已经完成了以防万一我已经做了一些愚蠢的事情。基本上,前两个声明块可以忽略。
任何帮助表示感谢。
答案 0 :(得分:4)
您可以使用QSH和重定向来写入IFS比尝试使用C API容易得多。
/* DISABLE STDOUT */
ADDENVVAR ENVVAR(QIBM_QSH_CMD_OUTPUT) VALUE('NONE') REPLACE(*YES)
/* CREATE THE FILE WITH CCSID 819 */
ADDENVVAR ENVVAR(STRPATH) VALUE(&STRPATH) REPLACE(*YES)
QSH CMD('rm $STRPATH; touch -C 819 $STRPATH')
/* APPEND A LINE TO THE FILE */
ADDENVVAR ENVVAR(LINE) VALUE(&LINE) REPLACE(*YES)
QSH CMD('echo "$LINE">>$STRPATH')
了解更多信息:
如果您需要更高的性能,可以使用更灵活的HLL来访问API。 Scott Klement有一本很棒的电子书,名为Working with the IFS in RPG IV。
答案 1 :(得分:0)
我一直在寻找如何使用CL中的IFS API并遇到您的代码。我认为你写的问题是文件句柄(第一个参数)需要通过值传递。此外,不要在&amp; STROPN变量中指定O_CODEPAGE,因为它与代码页参数冲突。我正在使用此方法,并且能够为我正在处理的服务程序获取一个很好的跟踪文件。
答案 2 :(得分:0)
调用write函数只是一个小错误,句柄应该通过值传递,而不是byref 找到下面更正的写入电话,我测试了它及其工作
CALLPRC PRC('write') PARM((&STRHAND *BYVAL) +
(&LINE_PTR *BYREF) (&LINELEN *BYVAL))