2015-04-20 14:17 GMT-03:00 Paulo César Pereira de Andrade
<paulo.cesar.pereira.de.andr...@gmail.com>:

[...]
>> So, after following the code enough, I learned that at places
>> it handles SH_JMPEXIT, there was almost non existing
>> handling of SH_JMPERREXIT.
>>
>> ksh would evently cause a crash due to the struct
>> subshell allocated on stack, in sh/subshell.c:sh_subshell
>> kept set to the global subshell_data, after it siglongjmp
>> back the stack due to, not fully handling the out of disk
>> space errors. It would print a few messages, everytime
>> a pipe was created, e.g.:
>>
>> /etc/profile: line 28: write to 3 failed [No space left on device]
>>
>> until eventually crashing due to corrupted memory; e.g. the
>> references to stack data from sh_subsell in the global
>> subshell_data. One strange thing to me in coredump analysis
>> was that subshell_data prev field was pointing to itself when
>> it eventually crashed, what later was understood and expected...

  I think it may be better to pass 0 to sh_done, because otherwise
it would pass 255 as an argument to sigaction.

Passing 0 would cause it to exit immediately, like a
normal shell execution.

I just noticed the issue while debugging a problem
in tcsh, and ksh would fallback in the pause(), instead
of exiting, if ^C was pressed during:

eval sleep 10

Patch inlined in case it could get removed from email:

---8<---
diff -up ksh-20120801/src/cmd/ksh93/sh/main.c.orig
ksh-20120801/src/cmd/ksh93/sh/main.c
--- ksh-20120801/src/cmd/ksh93/sh/main.c.orig    2015-04-29
16:49:11.502958000 -0300
+++ ksh-20120801/src/cmd/ksh93/sh/main.c    2015-05-08 18:19:55.688776922 -0300
@@ -423,7 +423,7 @@ static void    exfile(register Shell_t *shp
         sfsync(shp->outpool);
         shp->st.execbrk = shp->st.breakcnt = 0;
         /* check for return from profile or env file */
-        if(sh_isstate(SH_PROFILE) && (jmpval==SH_JMPFUN || jmpval==SH_JMPEXIT))
+        if(sh_isstate(SH_PROFILE) && (jmpval==SH_JMPFUN ||
jmpval==SH_JMPEXIT || jmpval==SH_JMPERREXIT))
         {
             sh_setstate(states);
             goto done;
@@ -598,7 +598,7 @@ done:
     }
     if(jmpval == SH_JMPSCRIPT)
         siglongjmp(*shp->jmplist,jmpval);
-    else if(jmpval == SH_JMPEXIT)
+    else if(jmpval == SH_JMPEXIT || jmpval == SH_JMPERREXIT)
         sh_done(shp,0);
     if(fno>0)
         sh_close(fno);
---8<---

Thanks,
Paulo
_______________________________________________
ast-users mailing list
ast-users@lists.research.att.com
http://lists.research.att.com/mailman/listinfo/ast-users

Reply via email to