Hi! ----
While trying to figure out why Solaris still have problems with (realtime) signal handling I found another issue related to |errno|: It seems that if syscalls are waiting and are then interrupted by a signal the value of |errno| returned by the syscall looks different than the errno value returned by the kernel for that syscall... ... after some digging I figured out that some platforms do not save |errno| before calling the signal handler function and then restore it when that function returns. Attached (as "astksh20131010_sighandler_saverestore_errno001.diff") is a simple patch which fixes that issue (and therefore fixes some sporadic failures in ksh93 related to signal handling) ... ---- Bye, Roland -- __ . . __ (o.\ \/ /.o) roland.ma...@nrubsig.org \__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer /O /==\ O\ TEL +49 641 3992797 (;O/ \/ \O;)
diff -r -u build_i386_64bit_debug/src/cmd/ksh93/sh/fault.c build_sigerrno/src/cmd/ksh93/sh/fault.c --- src/cmd/ksh93/sh/fault.c 2013-08-14 23:31:23.000000000 +0200 +++ src/cmd/ksh93/sh/fault.c 2014-01-23 21:22:08.081397145 +0100 @@ -112,6 +112,7 @@ void sh_fault(register int sig) #endif { + int saved_errno = errno; /* many platforms do not save/restore errno for signal handlers */ register Shell_t *shp = sh_getinterp(); register int flag=0; register char *trap; @@ -135,21 +136,21 @@ /* critical region, save and process later */ if(!(shp->sigflag[sig]&SH_SIGIGNORE)) shp->savesig = sig; - return; + goto done; } /* handle ignored signals */ if(trap && *trap==0) - return; + goto done; flag = shp->sigflag[sig]&~SH_SIGOFF; if(!trap) { if(sig==SIGINT && (shp->trapnote&SH_SIGIGNORE)) - return; + goto done; if(flag&SH_SIGIGNORE) { if(shp->subshell) shp->ignsig = sig; - return; + goto done; } if(flag&SH_SIGDONE) { @@ -161,7 +162,7 @@ /* check for TERM signal between fork/exec */ if(sig==SIGTERM && job.in_critical) shp->trapnote |= SH_SIGTERM; - return; + goto done; } shp->lastsig = sig; sigrelease(sig); @@ -194,7 +195,7 @@ dp->exceptf = malloc_done; } #endif - return; + goto done; } } errno = 0; @@ -224,7 +225,7 @@ { sigrelease(sig); sh_exit(shp,SH_EXITSIG); - return; + goto done; } } #endif /* SIGTSTP */ @@ -232,7 +233,7 @@ if(shp->bltinfun) action = notify_builtin(shp,sig); if(action>0) - return; + goto done; shp->trapnote |= flag; #ifdef AST_SERIAL_RESTART if(flag&(SH_SIGSET|SH_SIGTRAP)) @@ -243,10 +244,12 @@ if(pp->mode==SH_JMPCMD && sh_isstate(shp,SH_STOPOK)) { if(action<0) - return; + goto done; sigrelease(sig); sh_exit(shp,SH_EXITSIG); } +done: + errno = saved_errno; } /* diff -r -u build_i386_64bit_debug/src/cmd/ksh93/sh/jobs.c build_sigerrno/src/cmd/ksh93/sh/jobs.c --- src/cmd/ksh93/sh/jobs.c 2013-10-04 17:25:25.000000000 +0200 +++ src/cmd/ksh93/sh/jobs.c 2014-01-23 22:05:24.830307582 +0100 @@ -367,6 +367,8 @@ static void job_waitsafe(int sig) #endif { + int saved_errno = errno; /* many platforms do not save/restore errno for signal handlers */ + if(job.in_critical || vmbusy()) { job.savesig = sig; @@ -374,6 +376,8 @@ } else job_reap(sig); + + errno = saved_errno; } /*
_______________________________________________ ast-developers mailing list ast-developers@lists.research.att.com http://lists.research.att.com/mailman/listinfo/ast-developers