155745691Smillert #define INCL_DOSPROCESS
255745691Smillert #define INCL_DOSSEMAPHORES
355745691Smillert #define INCL_DOSMODULEMGR
455745691Smillert #define INCL_DOSMISC
555745691Smillert #define INCL_DOSEXCEPTIONS
655745691Smillert #define INCL_DOSERRORS
755745691Smillert #define INCL_REXXSAA
855745691Smillert #include <os2.h>
955745691Smillert
1055745691Smillert /*
1143003dfeSmillert * The Road goes ever on and on
1243003dfeSmillert * Down from the door where it began.
1343003dfeSmillert *
1443003dfeSmillert * [Bilbo on p.35 of _The Lord of the Rings_, I/i: "A Long-Expected Party"]
1543003dfeSmillert * [Frodo on p.73 of _The Lord of the Rings_, I/iii: "Three Is Company"]
1655745691Smillert */
1755745691Smillert
1855745691Smillert #ifdef OEMVS
1955745691Smillert #ifdef MYMALLOC
2055745691Smillert /* sbrk is limited to first heap segement so make it big */
2155745691Smillert #pragma runopts(HEAP(8M,500K,ANYWHERE,KEEP,8K,4K) STACK(,,ANY,) ALL31(ON))
2255745691Smillert #else
2355745691Smillert #pragma runopts(HEAP(2M,500K,ANYWHERE,KEEP,8K,4K) STACK(,,ANY,) ALL31(ON))
2455745691Smillert #endif
2555745691Smillert #endif
2655745691Smillert
2755745691Smillert
2855745691Smillert #include "EXTERN.h"
2955745691Smillert #include "perl.h"
3055745691Smillert
3155745691Smillert static void xs_init (pTHX);
3255745691Smillert static PerlInterpreter *my_perl;
3355745691Smillert
3455745691Smillert ULONG PERLEXPORTALL(PCSZ name, LONG rargc, const RXSTRING *rargv, PCSZ queuename, PRXSTRING retstr);
3555745691Smillert ULONG PERLDROPALL(PCSZ name, LONG rargc, const RXSTRING *rargv, PCSZ queuename, PRXSTRING retstr);
3655745691Smillert ULONG PERLDROPALLEXIT(PCSZ name, LONG rargc, const RXSTRING *rargv, PCSZ queuename, PRXSTRING retstr);
3755745691Smillert
3855745691Smillert /* Register any extra external extensions */
3955745691Smillert
4055745691Smillert /* Do not delete this line--writemain depends on it */
4155745691Smillert EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);
4255745691Smillert
4355745691Smillert static void
xs_init(pTHX)4455745691Smillert xs_init(pTHX)
4555745691Smillert {
4655745691Smillert char *file = __FILE__;
4755745691Smillert dXSUB_SYS;
4855745691Smillert newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
4955745691Smillert }
5055745691Smillert
5155745691Smillert int perlos2_is_inited;
5255745691Smillert
5355745691Smillert static void
init_perlos2(void)5455745691Smillert init_perlos2(void)
5555745691Smillert {
5655745691Smillert /* static char *env[1] = {NULL}; */
5755745691Smillert
5855745691Smillert Perl_OS2_init3(0, 0, 0);
5955745691Smillert }
6055745691Smillert
6155745691Smillert static int
init_perl(int doparse)6255745691Smillert init_perl(int doparse)
6355745691Smillert {
6455745691Smillert char *argv[3] = {"perl_in_REXX", "-e", ""};
6555745691Smillert
6655745691Smillert if (!perlos2_is_inited) {
6755745691Smillert perlos2_is_inited = 1;
6855745691Smillert init_perlos2();
6955745691Smillert }
7055745691Smillert if (my_perl)
7155745691Smillert return 1;
7255745691Smillert if (!PL_do_undump) {
7355745691Smillert my_perl = perl_alloc();
7455745691Smillert if (!my_perl)
7555745691Smillert return 0;
7655745691Smillert perl_construct(my_perl);
77*f2a19305Safresh1 PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
7855745691Smillert PL_perl_destruct_level = 1;
7955745691Smillert }
8055745691Smillert if (!doparse)
8155745691Smillert return 1;
825759b3d2Safresh1 return !perl_parse(my_perl, xs_init, 3, argv, (char **)NULL);
8355745691Smillert }
8455745691Smillert
8555745691Smillert static char last_error[4096];
8655745691Smillert
8755745691Smillert static int
seterr(char * format,...)8855745691Smillert seterr(char *format, ...)
8955745691Smillert {
9055745691Smillert va_list va;
9155745691Smillert char *s = last_error;
9255745691Smillert
9355745691Smillert va_start(va, format);
9455745691Smillert if (s[0]) {
9555745691Smillert s += strlen(s);
9655745691Smillert if (s[-1] != '\n') {
9755745691Smillert snprintf(s, sizeof(last_error) - (s - last_error), "\n");
9855745691Smillert s += strlen(s);
9955745691Smillert }
10055745691Smillert }
10155745691Smillert vsnprintf(s, sizeof(last_error) - (s - last_error), format, va);
10255745691Smillert return 1;
10355745691Smillert }
10455745691Smillert
10555745691Smillert /* The REXX-callable entrypoints ... */
10655745691Smillert
PERL(PCSZ name,LONG rargc,const RXSTRING * rargv,PCSZ queuename,PRXSTRING retstr)10755745691Smillert ULONG PERL (PCSZ name, LONG rargc, const RXSTRING *rargv,
10855745691Smillert PCSZ queuename, PRXSTRING retstr)
10955745691Smillert {
11055745691Smillert int exitstatus;
11155745691Smillert char buf[256];
11255745691Smillert char *argv[3] = {"perl_from_REXX", "-e", buf};
11355745691Smillert ULONG ret;
11455745691Smillert
11555745691Smillert if (rargc != 1)
11655745691Smillert return seterr("one argument expected, got %ld", rargc);
11755745691Smillert if (rargv[0].strlength >= sizeof(buf))
11855745691Smillert return seterr("length of the argument %ld exceeds the maximum %ld",
11955745691Smillert rargv[0].strlength, (long)sizeof(buf) - 1);
12055745691Smillert
12155745691Smillert if (!init_perl(0))
12255745691Smillert return 1;
12355745691Smillert
12455745691Smillert memcpy(buf, rargv[0].strptr, rargv[0].strlength);
12555745691Smillert buf[rargv[0].strlength] = 0;
12655745691Smillert
1275759b3d2Safresh1 if (!perl_parse(my_perl, xs_init, 3, argv, (char **)NULL))
1285759b3d2Safresh1 perl_run(my_perl);
12955745691Smillert
1305759b3d2Safresh1 exitstatus = perl_destruct(my_perl);
13155745691Smillert perl_free(my_perl);
13255745691Smillert my_perl = 0;
13355745691Smillert
13455745691Smillert if (exitstatus)
13555745691Smillert ret = 1;
13655745691Smillert else {
13755745691Smillert ret = 0;
13855745691Smillert sprintf(retstr->strptr, "%s", "ok");
13955745691Smillert retstr->strlength = strlen (retstr->strptr);
14055745691Smillert }
14155745691Smillert PERL_SYS_TERM1(0);
14255745691Smillert return ret;
14355745691Smillert }
14455745691Smillert
PERLEXIT(PCSZ name,LONG rargc,const RXSTRING * rargv,PCSZ queuename,PRXSTRING retstr)14555745691Smillert ULONG PERLEXIT (PCSZ name, LONG rargc, const RXSTRING *rargv,
14655745691Smillert PCSZ queuename, PRXSTRING retstr)
14755745691Smillert {
14855745691Smillert if (rargc != 0)
14955745691Smillert return seterr("no arguments expected, got %ld", rargc);
15055745691Smillert PERL_SYS_TERM1(0);
15155745691Smillert return 0;
15255745691Smillert }
15355745691Smillert
PERLTERM(PCSZ name,LONG rargc,const RXSTRING * rargv,PCSZ queuename,PRXSTRING retstr)15455745691Smillert ULONG PERLTERM (PCSZ name, LONG rargc, const RXSTRING *rargv,
15555745691Smillert PCSZ queuename, PRXSTRING retstr)
15655745691Smillert {
15755745691Smillert if (rargc != 0)
15855745691Smillert return seterr("no arguments expected, got %ld", rargc);
15955745691Smillert if (!my_perl)
16055745691Smillert return seterr("no perl interpreter present");
16155745691Smillert perl_destruct(my_perl);
16255745691Smillert perl_free(my_perl);
16355745691Smillert my_perl = 0;
16455745691Smillert
16555745691Smillert sprintf(retstr->strptr, "%s", "ok");
16655745691Smillert retstr->strlength = strlen (retstr->strptr);
16755745691Smillert return 0;
16855745691Smillert }
16955745691Smillert
17055745691Smillert
PERLINIT(PCSZ name,LONG rargc,const RXSTRING * rargv,PCSZ queuename,PRXSTRING retstr)17155745691Smillert ULONG PERLINIT (PCSZ name, LONG rargc, const RXSTRING *rargv,
17255745691Smillert PCSZ queuename, PRXSTRING retstr)
17355745691Smillert {
17455745691Smillert if (rargc != 0)
17555745691Smillert return seterr("no argument expected, got %ld", rargc);
17655745691Smillert if (!init_perl(1))
17755745691Smillert return 1;
17855745691Smillert
17955745691Smillert sprintf(retstr->strptr, "%s", "ok");
18055745691Smillert retstr->strlength = strlen (retstr->strptr);
18155745691Smillert return 0;
18255745691Smillert }
18355745691Smillert
18455745691Smillert ULONG
PERLLASTERROR(PCSZ name,LONG rargc,const RXSTRING * rargv,PCSZ queuename,PRXSTRING retstr)18555745691Smillert PERLLASTERROR (PCSZ name, LONG rargc, const RXSTRING *rargv, PCSZ queuename, PRXSTRING retstr)
18655745691Smillert {
18755745691Smillert int len = strlen(last_error);
18855745691Smillert
18955745691Smillert if (len <= 256 /* Default buffer is 256-char long */
19055745691Smillert || !DosAllocMem((PPVOID)&retstr->strptr, len,
19155745691Smillert PAG_READ|PAG_WRITE|PAG_COMMIT)) {
19255745691Smillert memcpy(retstr->strptr, last_error, len);
19355745691Smillert retstr->strlength = len;
19455745691Smillert } else {
19555745691Smillert strcpy(retstr->strptr, "[Not enough memory to copy the errortext]");
19655745691Smillert retstr->strlength = strlen(retstr->strptr);
19755745691Smillert }
19855745691Smillert return 0;
19955745691Smillert }
20055745691Smillert
20155745691Smillert ULONG
PERLEVAL(PCSZ name,LONG rargc,const RXSTRING * rargv,PCSZ queuename,PRXSTRING retstr)20255745691Smillert PERLEVAL (PCSZ name, LONG rargc, const RXSTRING *rargv, PCSZ queuename, PRXSTRING retstr)
20355745691Smillert {
20455745691Smillert SV *res, *in;
20555745691Smillert STRLEN len, n_a;
20655745691Smillert char *str;
20755745691Smillert
20855745691Smillert last_error[0] = 0;
20955745691Smillert if (rargc != 1)
21055745691Smillert return seterr("one argument expected, got %ld", rargc);
21155745691Smillert
21255745691Smillert if (!init_perl(1))
21355745691Smillert return seterr("error initializing perl");
21455745691Smillert
21555745691Smillert {
21655745691Smillert dSP;
21755745691Smillert int ret;
21855745691Smillert
21955745691Smillert ENTER;
22055745691Smillert SAVETMPS;
22155745691Smillert
22255745691Smillert PUSHMARK(SP);
22355745691Smillert in = sv_2mortal(newSVpvn(rargv[0].strptr, rargv[0].strlength));
22455745691Smillert eval_sv(in, G_SCALAR);
22555745691Smillert SPAGAIN;
22655745691Smillert res = POPs;
22755745691Smillert PUTBACK;
22855745691Smillert
22955745691Smillert ret = 0;
23055745691Smillert if (SvTRUE(ERRSV))
23155745691Smillert ret = seterr(SvPV(ERRSV, n_a));
23255745691Smillert if (!SvOK(res))
23355745691Smillert ret = seterr("undefined value returned by Perl-in-REXX");
23455745691Smillert str = SvPV(res, len);
23555745691Smillert if (len <= 256 /* Default buffer is 256-char long */
23655745691Smillert || !DosAllocMem((PPVOID)&retstr->strptr, len,
23755745691Smillert PAG_READ|PAG_WRITE|PAG_COMMIT)) {
23855745691Smillert memcpy(retstr->strptr, str, len);
23955745691Smillert retstr->strlength = len;
24055745691Smillert } else
24155745691Smillert ret = seterr("Not enough memory for the return string of Perl-in-REXX");
24255745691Smillert
24355745691Smillert FREETMPS;
24455745691Smillert LEAVE;
24555745691Smillert
24655745691Smillert return ret;
24755745691Smillert }
24855745691Smillert }
24955745691Smillert
25055745691Smillert ULONG
PERLEVALSUBCOMMAND(const RXSTRING * command,PUSHORT flags,PRXSTRING retstr)25155745691Smillert PERLEVALSUBCOMMAND(
25255745691Smillert const RXSTRING *command, /* command to issue */
25355745691Smillert PUSHORT flags, /* error/failure flags */
25455745691Smillert PRXSTRING retstr ) /* return code */
25555745691Smillert {
25655745691Smillert ULONG rc = PERLEVAL(NULL, 1, command, NULL, retstr);
25755745691Smillert
25855745691Smillert if (rc)
25955745691Smillert *flags = RXSUBCOM_ERROR; /* raise error condition */
26055745691Smillert
26155745691Smillert return 0; /* finished */
26255745691Smillert }
26355745691Smillert
26455745691Smillert #define ArrLength(a) (sizeof(a)/sizeof(*(a)))
26555745691Smillert
26655745691Smillert static const struct {
26755745691Smillert char *name;
26855745691Smillert RexxFunctionHandler *f;
26955745691Smillert } funcs[] = {
27055745691Smillert {"PERL", (RexxFunctionHandler *)&PERL},
27155745691Smillert {"PERLTERM", (RexxFunctionHandler *)&PERLTERM},
27255745691Smillert {"PERLINIT", (RexxFunctionHandler *)&PERLINIT},
27355745691Smillert {"PERLEXIT", (RexxFunctionHandler *)&PERLEXIT},
27455745691Smillert {"PERLEVAL", (RexxFunctionHandler *)&PERLEVAL},
27555745691Smillert {"PERLLASTERROR", (RexxFunctionHandler *)&PERLLASTERROR},
27655745691Smillert {"PERLDROPALL", (RexxFunctionHandler *)&PERLDROPALL},
27755745691Smillert {"PERLDROPALLEXIT", (RexxFunctionHandler *)&PERLDROPALLEXIT},
27855745691Smillert /* Should be the last entry */
27955745691Smillert {"PERLEXPORTALL", (RexxFunctionHandler *)&PERLEXPORTALL}
28055745691Smillert };
28155745691Smillert
28255745691Smillert ULONG
PERLEXPORTALL(PCSZ name,LONG rargc,const RXSTRING * rargv,PCSZ queuename,PRXSTRING retstr)28355745691Smillert PERLEXPORTALL(PCSZ name, LONG rargc, const RXSTRING *rargv, PCSZ queuename, PRXSTRING retstr)
28455745691Smillert {
28555745691Smillert int i = -1;
28655745691Smillert
28755745691Smillert while (++i < ArrLength(funcs) - 1)
28855745691Smillert RexxRegisterFunctionExe(funcs[i].name, funcs[i].f);
28955745691Smillert RexxRegisterSubcomExe("EVALPERL", (PFN)&PERLEVALSUBCOMMAND, NULL);
29055745691Smillert retstr->strlength = 0;
29155745691Smillert return 0;
29255745691Smillert }
29355745691Smillert
29455745691Smillert ULONG
PERLDROPALL(PCSZ name,LONG rargc,const RXSTRING * rargv,PCSZ queuename,PRXSTRING retstr)29555745691Smillert PERLDROPALL(PCSZ name, LONG rargc, const RXSTRING *rargv, PCSZ queuename, PRXSTRING retstr)
29655745691Smillert {
29755745691Smillert int i = -1;
29855745691Smillert
29955745691Smillert while (++i < ArrLength(funcs))
30055745691Smillert RexxDeregisterFunction(funcs[i].name);
30155745691Smillert RexxDeregisterSubcom("EVALPERL", NULL /* Not a DLL version */);
30255745691Smillert retstr->strlength = 0;
30355745691Smillert return 0;
30455745691Smillert }
30555745691Smillert
30655745691Smillert ULONG
PERLDROPALLEXIT(PCSZ name,LONG rargc,const RXSTRING * rargv,PCSZ queuename,PRXSTRING retstr)30755745691Smillert PERLDROPALLEXIT(PCSZ name, LONG rargc, const RXSTRING *rargv, PCSZ queuename, PRXSTRING retstr)
30855745691Smillert {
30955745691Smillert int i = -1;
31055745691Smillert
31155745691Smillert while (++i < ArrLength(funcs))
31255745691Smillert RexxDeregisterFunction(funcs[i].name);
31355745691Smillert RexxDeregisterSubcom("EVALPERL", NULL /* Not a DLL version */);
31455745691Smillert PERL_SYS_TERM1(0);
31555745691Smillert retstr->strlength = 0;
31655745691Smillert return 0;
31755745691Smillert }
318