xref: /openbsd/gnu/usr.bin/perl/os2/perlrexx.c (revision f2a19305)
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