{
if (!perl)
{
- temp_environ temp_environ(rxvt_environ);
+ perl_environ = rxvt_environ;
+ swap (perl_environ, environ);
char *argv[] = {
"",
perl_free (perl);
perl = 0;
}
+
+ swap (perl_environ, environ);
}
}
return false;
}
- temp_environ temp_environ(rxvt_environ);
-
- dSP;
- va_list ap;
-
- va_start (ap, htype);
-
- ENTER;
- SAVETMPS;
-
- PUSHMARK (SP);
-
- XPUSHs (sv_2mortal (newSVterm (term)));
- XPUSHs (sv_2mortal (newSViv (htype)));
-
- for (;;) {
- data_type dt = (data_type)va_arg (ap, int);
+ swap (perl_environ, environ);
- switch (dt)
- {
- case DT_INT:
- XPUSHs (sv_2mortal (newSViv (va_arg (ap, int))));
- break;
+ try
+ {
+ dSP;
+ va_list ap;
- case DT_LONG:
- XPUSHs (sv_2mortal (newSViv (va_arg (ap, long))));
- break;
+ va_start (ap, htype);
- case DT_STR:
- XPUSHs (taint (sv_2mortal (newSVpv (va_arg (ap, char *), 0))));
- break;
+ ENTER;
+ SAVETMPS;
- case DT_STR_LEN:
- {
- char *str = va_arg (ap, char *);
- int len = va_arg (ap, int);
+ PUSHMARK (SP);
- XPUSHs (taint (sv_2mortal (newSVpvn (str, len))));
- }
- break;
-
- case DT_WCS_LEN:
- {
- wchar_t *wstr = va_arg (ap, wchar_t *);
- int wlen = va_arg (ap, int);
+ XPUSHs (sv_2mortal (newSVterm (term)));
+ XPUSHs (sv_2mortal (newSViv (htype)));
- XPUSHs (taint (sv_2mortal (wcs2sv (wstr, wlen))));
- }
- break;
+ for (;;) {
+ data_type dt = (data_type)va_arg (ap, int);
- case DT_XEVENT:
+ switch (dt)
{
- XEvent *xe = va_arg (ap, XEvent *);
- HV *hv = newHV ();
+ case DT_INT:
+ XPUSHs (sv_2mortal (newSViv (va_arg (ap, int))));
+ break;
-# define set(name, sv) hv_store (hv, # name, sizeof (# name) - 1, sv, 0)
-# define setiv(name, val) hv_store (hv, # name, sizeof (# name) - 1, newSViv (val), 0)
-# undef set
+ case DT_LONG:
+ XPUSHs (sv_2mortal (newSViv (va_arg (ap, long))));
+ break;
- setiv (type, xe->type);
- setiv (send_event, xe->xany.send_event);
- setiv (serial, xe->xany.serial);
+ case DT_STR:
+ XPUSHs (taint (sv_2mortal (newSVpv (va_arg (ap, char *), 0))));
+ break;
- switch (xe->type)
+ case DT_STR_LEN:
{
- case KeyPress:
- case KeyRelease:
- case ButtonPress:
- case ButtonRelease:
- case MotionNotify:
- setiv (time, xe->xmotion.time);
- setiv (x, xe->xmotion.x);
- setiv (y, xe->xmotion.y);
- setiv (row, xe->xmotion.y / term->fheight);
- setiv (col, xe->xmotion.x / term->fwidth);
- setiv (x_root, xe->xmotion.x_root);
- setiv (y_root, xe->xmotion.y_root);
- setiv (state, xe->xmotion.state);
- break;
+ char *str = va_arg (ap, char *);
+ int len = va_arg (ap, int);
+
+ XPUSHs (taint (sv_2mortal (newSVpvn (str, len))));
}
+ break;
- switch (xe->type)
+ case DT_WCS_LEN:
{
- case KeyPress:
- case KeyRelease:
- setiv (keycode, xe->xkey.keycode);
- break;
+ wchar_t *wstr = va_arg (ap, wchar_t *);
+ int wlen = va_arg (ap, int);
- case ButtonPress:
- case ButtonRelease:
- setiv (button, xe->xbutton.button);
- break;
-
- case MotionNotify:
- setiv (is_hint, xe->xmotion.is_hint);
- break;
+ XPUSHs (taint (sv_2mortal (wcs2sv (wstr, wlen))));
}
+ break;
- XPUSHs (sv_2mortal (newRV_noinc ((SV *)hv)));
- }
- break;
-
- case DT_END:
- {
- va_end (ap);
-
- PUTBACK;
- int count = call_pv ("urxvt::invoke", G_ARRAY | G_EVAL);
- SPAGAIN;
-
- if (count)
+ case DT_XEVENT:
{
- SV *status = POPs;
- count = SvTRUE (status);
- }
+ XEvent *xe = va_arg (ap, XEvent *);
+ HV *hv = newHV ();
- PUTBACK;
- FREETMPS;
- LEAVE;
+# define set(name, sv) hv_store (hv, # name, sizeof (# name) - 1, sv, 0)
+# define setiv(name, val) hv_store (hv, # name, sizeof (# name) - 1, newSViv (val), 0)
+# undef set
- if (SvTRUE (ERRSV))
- {
- rxvt_warn ("perl hook %d evaluation error: %s", htype, SvPV_nolen (ERRSV));
- ungrab (term); // better lose the grab than the session
+ setiv (type, xe->type);
+ setiv (send_event, xe->xany.send_event);
+ setiv (serial, xe->xany.serial);
+
+ switch (xe->type)
+ {
+ case KeyPress:
+ case KeyRelease:
+ case ButtonPress:
+ case ButtonRelease:
+ case MotionNotify:
+ setiv (time, xe->xmotion.time);
+ setiv (x, xe->xmotion.x);
+ setiv (y, xe->xmotion.y);
+ setiv (row, xe->xmotion.y / term->fheight);
+ setiv (col, xe->xmotion.x / term->fwidth);
+ setiv (x_root, xe->xmotion.x_root);
+ setiv (y_root, xe->xmotion.y_root);
+ setiv (state, xe->xmotion.state);
+ break;
+ }
+
+ switch (xe->type)
+ {
+ case KeyPress:
+ case KeyRelease:
+ setiv (keycode, xe->xkey.keycode);
+ break;
+
+ case ButtonPress:
+ case ButtonRelease:
+ setiv (button, xe->xbutton.button);
+ break;
+
+ case MotionNotify:
+ setiv (is_hint, xe->xmotion.is_hint);
+ break;
+ }
+
+ XPUSHs (sv_2mortal (newRV_noinc ((SV *)hv)));
}
+ break;
- if (htype == HOOK_DESTROY)
+ case DT_END:
{
- clearSVptr ((SV *)term->perl.self);
- SvREFCNT_dec ((SV *)term->perl.self);
+ va_end (ap);
+
+ PUTBACK;
+ int count = call_pv ("urxvt::invoke", G_ARRAY | G_EVAL);
+ SPAGAIN;
+
+ if (count)
+ {
+ SV *status = POPs;
+ count = SvTRUE (status);
+ }
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+
+ if (SvTRUE (ERRSV))
+ {
+ rxvt_warn ("perl hook %d evaluation error: %s", htype, SvPV_nolen (ERRSV));
+ ungrab (term); // better lose the grab than the session
+ }
+
+ if (htype == HOOK_DESTROY)
+ {
+ clearSVptr ((SV *)term->perl.self);
+ SvREFCNT_dec ((SV *)term->perl.self);
+ }
+
+ swap (perl_environ, environ);
+ return count;
}
- return count;
+ default:
+ rxvt_fatal ("FATAL: unable to pass data type %d\n", dt);
}
-
- default:
- rxvt_fatal ("FATAL: unable to pass data type %d\n", dt);
}
- }
+ }
+ catch (...)
+ {
+ swap (perl_environ, environ);
+ throw;
+ }
}
/////////////////////////////////////////////////////////////////////////////