Compare commits
No commits in common. 'c9' and 'i10c-beta' have entirely different histories.
@ -1 +1 @@
|
||||
SOURCES/ksh-1.0.6.tar.gz
|
||||
SOURCES/ksh-1.0.10.tar.gz
|
||||
|
@ -1 +1 @@
|
||||
9d3e1fb4406fa31a888a3599e1cfb54713df1e03 SOURCES/ksh-1.0.6.tar.gz
|
||||
5d93d4b817790af672d9a3e81b08e1ca05c5d268 SOURCES/ksh-1.0.10.tar.gz
|
||||
|
@ -1,541 +0,0 @@
|
||||
diff --git a/src/cmd/ksh93/Mamfile b/src/cmd/ksh93/Mamfile
|
||||
index f6e6ac8..9d72d87 100644
|
||||
--- a/src/cmd/ksh93/Mamfile
|
||||
+++ b/src/cmd/ksh93/Mamfile
|
||||
@@ -220,30 +220,18 @@ make install
|
||||
done pmain.o generated
|
||||
make libshell.a archive
|
||||
prev shell.req
|
||||
- make cd_pwd.o
|
||||
- make bltins/cd_pwd.c
|
||||
- make include/test.h implicit
|
||||
- prev include/shtable.h implicit
|
||||
- make include/defs.h implicit
|
||||
- prev include/regress.h implicit dontcare
|
||||
- prev include/shtable.h
|
||||
- prev include/shell.h
|
||||
- prev ${PACKAGE_ast_INCLUDE}/endian.h
|
||||
- prev include/name.h
|
||||
- prev include/argnod.h implicit
|
||||
- prev ${PACKAGE_ast_INCLUDE}/cdt.h
|
||||
- prev ${PACKAGE_ast_INCLUDE}/error.h
|
||||
- prev ${PACKAGE_ast_INCLUDE}/sfio.h
|
||||
+ make alarm.o
|
||||
+ make bltins/alarm.c
|
||||
+ make FEATURE/time implicit
|
||||
+ prev features/time
|
||||
+ exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/time
|
||||
+ make ${PACKAGE_ast_INCLUDE}/times.h implicit
|
||||
+ prev ${PACKAGE_ast_INCLUDE}/ast_time.h implicit
|
||||
prev ${PACKAGE_ast_INCLUDE}/ast.h
|
||||
- done include/defs.h
|
||||
- done include/test.h
|
||||
- make ${PACKAGE_ast_INCLUDE}/ls.h implicit
|
||||
- prev ${PACKAGE_ast_INCLUDE}/ast_mode.h implicit dontcare
|
||||
- prev ${PACKAGE_ast_INCLUDE}/ast_fs.h
|
||||
- prev ${PACKAGE_ast_INCLUDE}/ast_std.h
|
||||
- done ${PACKAGE_ast_INCLUDE}/ls.h
|
||||
+ done ${PACKAGE_ast_INCLUDE}/times.h
|
||||
+ done FEATURE/time generated
|
||||
make include/builtins.h implicit
|
||||
- prev include/shtable.h
|
||||
+ prev include/shtable.h implicit
|
||||
make FEATURE/dynamic implicit
|
||||
prev features/dynamic
|
||||
exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/dynamic
|
||||
@@ -251,6 +239,36 @@ make install
|
||||
done FEATURE/dynamic generated
|
||||
prev ${PACKAGE_ast_INCLUDE}/option.h
|
||||
done include/builtins.h
|
||||
+ prev ${PACKAGE_ast_INCLUDE}/error.h
|
||||
+ make include/defs.h implicit
|
||||
+ prev include/regress.h implicit
|
||||
+ prev include/shtable.h
|
||||
+ prev include/shell.h
|
||||
+ prev ${PACKAGE_ast_INCLUDE}/endian.h
|
||||
+ prev include/name.h
|
||||
+ prev include/argnod.h implicit
|
||||
+ prev ${PACKAGE_ast_INCLUDE}/cdt.h
|
||||
+ prev FEATURE/externs
|
||||
+ prev ${PACKAGE_ast_INCLUDE}/error.h
|
||||
+ prev ${PACKAGE_ast_INCLUDE}/sfio.h
|
||||
+ prev ${PACKAGE_ast_INCLUDE}/ast.h
|
||||
+ done include/defs.h
|
||||
+ prev shopt.h
|
||||
+ done bltins/alarm.c
|
||||
+ exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c bltins/alarm.c
|
||||
+ done alarm.o generated
|
||||
+ make cd_pwd.o
|
||||
+ make bltins/cd_pwd.c
|
||||
+ make include/test.h implicit
|
||||
+ prev include/shtable.h
|
||||
+ prev include/defs.h
|
||||
+ done include/test.h
|
||||
+ make ${PACKAGE_ast_INCLUDE}/ls.h implicit
|
||||
+ prev ${PACKAGE_ast_INCLUDE}/ast_mode.h implicit
|
||||
+ prev ${PACKAGE_ast_INCLUDE}/ast_fs.h
|
||||
+ prev ${PACKAGE_ast_INCLUDE}/ast_std.h
|
||||
+ done ${PACKAGE_ast_INCLUDE}/ls.h
|
||||
+ prev include/builtins.h
|
||||
prev include/name.h
|
||||
make include/path.h implicit
|
||||
make FEATURE/acct implicit
|
||||
@@ -341,14 +359,7 @@ make install
|
||||
make misc.o
|
||||
make bltins/misc.c
|
||||
prev ${PACKAGE_ast_INCLUDE}/times.h
|
||||
- make FEATURE/time implicit
|
||||
- prev features/time
|
||||
- exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/time
|
||||
- make ${PACKAGE_ast_INCLUDE}/times.h implicit
|
||||
- prev ${PACKAGE_ast_INCLUDE}/ast_time.h implicit dontcare
|
||||
- prev ${PACKAGE_ast_INCLUDE}/ast.h
|
||||
- done ${PACKAGE_ast_INCLUDE}/times.h dontcare
|
||||
- done FEATURE/time generated
|
||||
+ prev FEATURE/time
|
||||
prev FEATURE/locale
|
||||
make include/jobs.h implicit
|
||||
prev ${PACKAGE_ast_INCLUDE}/vmalloc.h
|
||||
@@ -1175,7 +1186,7 @@ make install
|
||||
done edit/hexpand.c
|
||||
exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c edit/hexpand.c
|
||||
done hexpand.o generated
|
||||
- exec - ${AR} rc libshell.a cd_pwd.o cflow.o enum.o getopts.o hist.o misc.o mkservice.o print.o read.o sleep.o trap.o test.o typeset.o ulimit.o umask.o whence.o main.o nvdisc.o nvtype.o arith.o args.o array.o completion.o defs.o edit.o expand.o regress.o fault.o fcin.o
|
||||
+ exec - ${AR} rc libshell.a alarm.o cd_pwd.o cflow.o enum.o getopts.o hist.o misc.o mkservice.o print.o read.o sleep.o trap.o test.o typeset.o ulimit.o umask.o whence.o main.o nvdisc.o nvtype.o arith.o args.o array.o completion.o defs.o edit.o expand.o regress.o fault.o fcin.o
|
||||
exec - ${AR} rc libshell.a history.o init.o io.o jobs.o lex.o macro.o name.o nvtree.o parse.o path.o string.o streval.o subshell.o tdump.o timers.o trestore.o waitevent.o xec.o limits.o msg.o strdata.o testops.o keywords.o options.o signals.o aliases.o builtins.o variables.o lexstates.o emacs.o vi.o hexpand.o
|
||||
exec - (ranlib libshell.a) >/dev/null 2>&1 || true
|
||||
done libshell.a generated
|
||||
diff --git a/src/cmd/ksh93/bltins/alarm.c b/src/cmd/ksh93/bltins/alarm.c
|
||||
new file mode 100644
|
||||
index 0000000..f31bed7
|
||||
--- /dev/null
|
||||
+++ b/src/cmd/ksh93/bltins/alarm.c
|
||||
@@ -0,0 +1,277 @@
|
||||
+/***********************************************************************
|
||||
+* *
|
||||
+* This software is part of the ast package *
|
||||
+* Copyright (c) 1982-2012 AT&T Intellectual Property *
|
||||
+* Copyright (c) 2020-2023 Contributors to ksh 93u+m *
|
||||
+* and is licensed under the *
|
||||
+* Eclipse Public License, Version 2.0 *
|
||||
+* *
|
||||
+* A copy of the License is available at *
|
||||
+* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
|
||||
+* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
|
||||
+* *
|
||||
+* David Korn <dgk@research.att.com> *
|
||||
+* Martijn Dekker <martijn@inlv.org> *
|
||||
+* Johnothan King <johnothanking@protonmail.com> *
|
||||
+* *
|
||||
+***********************************************************************/
|
||||
+/*
|
||||
+ * alarm [-r] [varname [+]when]
|
||||
+ *
|
||||
+ * David Korn
|
||||
+ * AT&T Labs
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * TODO: 2014 email from David Korn cited at <https://bugzilla.redhat.com/1176670>:
|
||||
+ *
|
||||
+ * > I never documented the alarm builtin because it is problematic. The
|
||||
+ * > problem is that traps can't safely be handled asynchronously. What should
|
||||
+ * > happen is that the trap is marked for execution (sh.trapnote) and run after
|
||||
+ * > the current command completes. The time trap should wake up the shell if
|
||||
+ * > it is blocked and it should return and then handle the trap.
|
||||
+ */
|
||||
+
|
||||
+#include "shopt.h"
|
||||
+#include "defs.h"
|
||||
+#include <error.h>
|
||||
+#include "builtins.h"
|
||||
+#include "FEATURE/time"
|
||||
+
|
||||
+#define R_FLAG 1
|
||||
+#define L_FLAG 2
|
||||
+
|
||||
+struct tevent
|
||||
+{
|
||||
+ Namfun_t fun;
|
||||
+ Namval_t *node;
|
||||
+ Namval_t *action;
|
||||
+ struct tevent *next;
|
||||
+ long milli;
|
||||
+ int flags;
|
||||
+ void *timeout;
|
||||
+};
|
||||
+
|
||||
+static const char ALARM[] = "alarm";
|
||||
+
|
||||
+static void trap_timeout(void*);
|
||||
+
|
||||
+/*
|
||||
+ * insert timeout item on current given list in sorted order
|
||||
+ */
|
||||
+static void *time_add(struct tevent *item, void *list)
|
||||
+{
|
||||
+ struct tevent *tp = (struct tevent*)list;
|
||||
+ if(!tp || item->milli < tp->milli)
|
||||
+ {
|
||||
+ item->next = tp;
|
||||
+ list = item;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ while(tp->next && item->milli > tp->next->milli)
|
||||
+ tp = tp->next;
|
||||
+ item->next = tp->next;
|
||||
+ tp->next = item;
|
||||
+ }
|
||||
+ tp = item;
|
||||
+ tp->timeout = sh_timeradd(tp->milli,tp->flags&R_FLAG,trap_timeout,tp);
|
||||
+ return list;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * delete timeout item from current given list, delete timer
|
||||
+ */
|
||||
+static void *time_delete(struct tevent *item, void *list)
|
||||
+{
|
||||
+ struct tevent *tp = (struct tevent*)list;
|
||||
+ if(item==tp)
|
||||
+ list = tp->next;
|
||||
+ else
|
||||
+ {
|
||||
+ while(tp && tp->next != item)
|
||||
+ tp = tp->next;
|
||||
+ if(tp)
|
||||
+ tp->next = item->next;
|
||||
+ }
|
||||
+ if(item->timeout)
|
||||
+ sh_timerdel(item->timeout);
|
||||
+ return list;
|
||||
+}
|
||||
+
|
||||
+static void print_alarms(void *list)
|
||||
+{
|
||||
+ struct tevent *tp = (struct tevent*)list;
|
||||
+ while(tp)
|
||||
+ {
|
||||
+ if(tp->timeout)
|
||||
+ {
|
||||
+ char *name = nv_name(tp->node);
|
||||
+ if(tp->flags&R_FLAG)
|
||||
+ {
|
||||
+ double d = tp->milli;
|
||||
+ sfprintf(sfstdout,e_alrm1,name,d/1000.);
|
||||
+ }
|
||||
+ else
|
||||
+ sfprintf(sfstdout,e_alrm2,name,nv_getnum(tp->node));
|
||||
+ }
|
||||
+ tp = tp->next;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void trap_timeout(void* handle)
|
||||
+{
|
||||
+ struct tevent *tp = (struct tevent*)handle;
|
||||
+ sh.trapnote |= SH_SIGALRM;
|
||||
+ if(!(tp->flags&R_FLAG))
|
||||
+ tp->timeout = 0;
|
||||
+ tp->flags |= L_FLAG;
|
||||
+ sh.sigflag[SIGALRM] |= SH_SIGALRM;
|
||||
+ if(sh_isstate(SH_TTYWAIT))
|
||||
+ sh_timetraps();
|
||||
+}
|
||||
+
|
||||
+void sh_timetraps(void)
|
||||
+{
|
||||
+ struct tevent *tp, *tpnext;
|
||||
+ struct tevent *tptop;
|
||||
+ while(1)
|
||||
+ {
|
||||
+ sh.sigflag[SIGALRM] &= ~SH_SIGALRM;
|
||||
+ tptop= (struct tevent*)sh.st.timetrap;
|
||||
+ for(tp=tptop;tp;tp=tpnext)
|
||||
+ {
|
||||
+ tpnext = tp->next;
|
||||
+ if(tp->flags&L_FLAG)
|
||||
+ {
|
||||
+ tp->flags &= ~L_FLAG;
|
||||
+ if(tp->action)
|
||||
+ sh_fun(tp->action,tp->node,NULL);
|
||||
+ tp->flags &= ~L_FLAG;
|
||||
+ if(!tp->flags)
|
||||
+ nv_unset(tp->node);
|
||||
+ }
|
||||
+ }
|
||||
+ if(!(sh.sigflag[SIGALRM]&SH_SIGALRM))
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * This trap function catches "alarm" actions only
|
||||
+ */
|
||||
+static char *setdisc(Namval_t *np, const char *event, Namval_t* action, Namfun_t *fp)
|
||||
+{
|
||||
+ struct tevent *tp = (struct tevent*)fp;
|
||||
+ if(!event)
|
||||
+ return action ? Empty : (char*)ALARM;
|
||||
+ if(strcmp(event,ALARM)!=0)
|
||||
+ {
|
||||
+ /* try the next level */
|
||||
+ return nv_setdisc(np, event, action, fp);
|
||||
+ }
|
||||
+ if(action==np)
|
||||
+ action = tp->action;
|
||||
+ else
|
||||
+ tp->action = action;
|
||||
+ return action ? (char*)action : Empty;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * catch assignments and set alarm traps
|
||||
+ */
|
||||
+static void putval(Namval_t* np, const char* val, int flag, Namfun_t* fp)
|
||||
+{
|
||||
+ struct tevent *tp = (struct tevent*)fp;
|
||||
+ double d;
|
||||
+ if(val)
|
||||
+ {
|
||||
+ double now;
|
||||
+#ifdef timeofday
|
||||
+ struct timeval tmp;
|
||||
+ timeofday(&tmp);
|
||||
+ now = tmp.tv_sec + 1.e-6*tmp.tv_usec;
|
||||
+#else
|
||||
+ now = (double)time(NULL);
|
||||
+#endif /* timeofday */
|
||||
+ nv_putv(np,val,flag,fp);
|
||||
+ d = nv_getnum(np);
|
||||
+ if(*val=='+')
|
||||
+ {
|
||||
+ double x = d + now;
|
||||
+ nv_putv(np,(char*)&x,NV_INTEGER|NV_DOUBLE,fp);
|
||||
+ }
|
||||
+ else
|
||||
+ d -= now;
|
||||
+ tp->milli = 1000*(d+.0005);
|
||||
+ if(tp->timeout)
|
||||
+ sh.st.timetrap = time_delete(tp,sh.st.timetrap);
|
||||
+ if(tp->milli > 0)
|
||||
+ sh.st.timetrap = time_add(tp,sh.st.timetrap);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ tp = (struct tevent*)nv_stack(np, NULL);
|
||||
+ sh.st.timetrap = time_delete(tp,sh.st.timetrap);
|
||||
+ nv_unset(np);
|
||||
+ free(fp);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static const Namdisc_t alarmdisc =
|
||||
+{
|
||||
+ sizeof(struct tevent),
|
||||
+ putval,
|
||||
+ 0,
|
||||
+ 0,
|
||||
+ setdisc,
|
||||
+};
|
||||
+
|
||||
+int b_alarm(int argc,char *argv[],Shbltin_t *context)
|
||||
+{
|
||||
+ int n,rflag=0;
|
||||
+ Namval_t *np;
|
||||
+ struct tevent *tp;
|
||||
+ while (n = optget(argv, sh_optalarm)) switch (n)
|
||||
+ {
|
||||
+ case 'r':
|
||||
+ rflag = R_FLAG;
|
||||
+ break;
|
||||
+ case ':':
|
||||
+ errormsg(SH_DICT,2, "%s", opt_info.arg);
|
||||
+ break;
|
||||
+ case '?':
|
||||
+ errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
|
||||
+ UNREACHABLE();
|
||||
+ }
|
||||
+ argc -= opt_info.index;
|
||||
+ argv += opt_info.index;
|
||||
+ if(error_info.errors)
|
||||
+ {
|
||||
+ errormsg(SH_DICT,ERROR_usage(2),optusage(NULL));
|
||||
+ UNREACHABLE();
|
||||
+ }
|
||||
+ if(argc==0)
|
||||
+ {
|
||||
+ print_alarms(sh.st.timetrap);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ if(argc!=2)
|
||||
+ {
|
||||
+ errormsg(SH_DICT,ERROR_usage(2),optusage(NULL));
|
||||
+ UNREACHABLE();
|
||||
+ }
|
||||
+ np = nv_open(argv[0],sh.var_tree,NV_NOARRAY|NV_VARNAME);
|
||||
+ if(!nv_isnull(np))
|
||||
+ nv_unset(np);
|
||||
+ nv_setattr(np, NV_DOUBLE);
|
||||
+ tp = sh_newof(NULL,struct tevent,1,0);
|
||||
+ tp->fun.disc = &alarmdisc;
|
||||
+ tp->flags = rflag;
|
||||
+ tp->node = np;
|
||||
+ nv_stack(np,(Namfun_t*)tp);
|
||||
+ nv_putval(np, argv[1], 0);
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/src/cmd/ksh93/bltins/sleep.c b/src/cmd/ksh93/bltins/sleep.c
|
||||
index b34e62d..3bb55b1 100644
|
||||
--- a/src/cmd/ksh93/bltins/sleep.c
|
||||
+++ b/src/cmd/ksh93/bltins/sleep.c
|
||||
@@ -127,6 +127,8 @@ skip:
|
||||
if(tloc < (now=time(NULL)))
|
||||
break;
|
||||
d = (double)(tloc-now);
|
||||
+ if(sh.sigflag[SIGALRM]&SH_SIGTRAP)
|
||||
+ sh_timetraps();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
diff --git a/src/cmd/ksh93/data/builtins.c b/src/cmd/ksh93/data/builtins.c
|
||||
index 760b7ce..22ea156 100644
|
||||
--- a/src/cmd/ksh93/data/builtins.c
|
||||
+++ b/src/cmd/ksh93/data/builtins.c
|
||||
@@ -116,6 +116,7 @@ const struct shtable3 shtab_builtins[] =
|
||||
"pwd", NV_BLTIN|BLT_ENV, bltin(pwd),
|
||||
"read", NV_BLTIN|BLT_ENV, bltin(read),
|
||||
"sleep", NV_BLTIN, bltin(sleep),
|
||||
+ "alarm", NV_BLTIN|BLT_ENV, bltin(alarm),
|
||||
"times", NV_BLTIN|BLT_ENV|BLT_SPC, bltin(times),
|
||||
"ulimit", NV_BLTIN|BLT_ENV, bltin(ulimit),
|
||||
"umask", NV_BLTIN|BLT_ENV, bltin(umask),
|
||||
@@ -2170,6 +2171,8 @@ const char sh_optwhence[] =
|
||||
;
|
||||
|
||||
|
||||
+const char e_alrm1[] = "alarm -r %s +%.3g\n";
|
||||
+const char e_alrm2[] = "alarm %s %.3f\n";
|
||||
const char e_baddisc[] = "%s: invalid discipline function";
|
||||
const char e_nofork[] = "cannot fork";
|
||||
const char e_nosignal[] = "%s: unknown signal name";
|
||||
diff --git a/src/cmd/ksh93/include/builtins.h b/src/cmd/ksh93/include/builtins.h
|
||||
index 34c697c..f6b3f59 100644
|
||||
--- a/src/cmd/ksh93/include/builtins.h
|
||||
+++ b/src/cmd/ksh93/include/builtins.h
|
||||
@@ -115,6 +115,8 @@ extern int b_times(int, char*[],Shbltin_t*);
|
||||
|
||||
extern short b_enum_nelem(Namfun_t*);
|
||||
|
||||
+extern const char e_alrm1[];
|
||||
+extern const char e_alrm2[];
|
||||
extern const char e_badfun[];
|
||||
extern const char e_baddisc[];
|
||||
extern const char e_nofork[];
|
||||
diff --git a/src/cmd/ksh93/include/defs.h b/src/cmd/ksh93/include/defs.h
|
||||
index 306ea7e..b5bfb67 100644
|
||||
--- a/src/cmd/ksh93/include/defs.h
|
||||
+++ b/src/cmd/ksh93/include/defs.h
|
||||
@@ -143,6 +143,7 @@ extern void sh_subjobcheck(pid_t);
|
||||
extern int sh_subsavefd(int);
|
||||
extern void sh_subtmpfile(void);
|
||||
extern char *sh_substitute(const char*,const char*,char*);
|
||||
+extern void sh_timetraps(void);
|
||||
extern const char *_sh_translate(const char*);
|
||||
extern int sh_trace(char*[],int);
|
||||
extern void sh_trim(char*);
|
||||
diff --git a/src/cmd/ksh93/include/fault.h b/src/cmd/ksh93/include/fault.h
|
||||
index b57a0ab..7750f80 100644
|
||||
--- a/src/cmd/ksh93/include/fault.h
|
||||
+++ b/src/cmd/ksh93/include/fault.h
|
||||
@@ -58,6 +58,7 @@ typedef void (*SH_SIGTYPE)(int,void(*)(int));
|
||||
#define SH_SIGIGNORE 040 /* default is ignore signal */
|
||||
#define SH_SIGINTERACTIVE 0100 /* handle interactive specially */
|
||||
#define SH_SIGTSTP 0200 /* tstp signal received */
|
||||
+#define SH_SIGALRM 0200 /* timer alarm received */
|
||||
#define SH_SIGTERM SH_SIGOFF /* term signal received */
|
||||
#define SH_SIGRUNTIME 0400 /* runtime value */
|
||||
|
||||
diff --git a/src/cmd/ksh93/include/shell.h b/src/cmd/ksh93/include/shell.h
|
||||
index 57c402d..9794995 100644
|
||||
--- a/src/cmd/ksh93/include/shell.h
|
||||
+++ b/src/cmd/ksh93/include/shell.h
|
||||
@@ -211,6 +211,7 @@ struct sh_scoped
|
||||
char **otrap; /* save parent pseudosignals for v=$(trap) */
|
||||
char **trapcom; /* EXIT and signals */
|
||||
char **otrapcom; /* save parent EXIT and signals for v=$(trap) */
|
||||
+ void *timetrap;
|
||||
struct Ufunction *real_fun; /* current 'function name' function */
|
||||
int repl_index;
|
||||
char *repl_arg;
|
||||
diff --git a/src/cmd/ksh93/sh/fault.c b/src/cmd/ksh93/sh/fault.c
|
||||
index 3409a6c..510bf56 100644
|
||||
--- a/src/cmd/ksh93/sh/fault.c
|
||||
+++ b/src/cmd/ksh93/sh/fault.c
|
||||
@@ -447,6 +447,8 @@ void sh_chktrap(void)
|
||||
sh_exit(sh.exitval);
|
||||
}
|
||||
}
|
||||
+ if(sh.sigflag[SIGALRM]&SH_SIGALRM)
|
||||
+ sh_timetraps();
|
||||
#if SHOPT_BGX
|
||||
if((sh.sigflag[SIGCHLD]&SH_SIGTRAP) && sh.st.trapcom[SIGCHLD])
|
||||
job_chldtrap(1);
|
||||
diff --git a/src/cmd/ksh93/sh/jobs.c b/src/cmd/ksh93/sh/jobs.c
|
||||
index 116ae3b..be333b2 100644
|
||||
--- a/src/cmd/ksh93/sh/jobs.c
|
||||
+++ b/src/cmd/ksh93/sh/jobs.c
|
||||
@@ -1466,6 +1466,8 @@ int job_wait(pid_t pid)
|
||||
continue;
|
||||
if(nochild)
|
||||
break;
|
||||
+ if(sh.sigflag[SIGALRM]&SH_SIGTRAP)
|
||||
+ sh_timetraps();
|
||||
if((intr && sh.trapnote) || (pid==1 && !intr))
|
||||
break;
|
||||
}
|
||||
diff --git a/src/cmd/ksh93/tests/builtins.sh b/src/cmd/ksh93/tests/builtins.sh
|
||||
index 83b4086..92d2708 100755
|
||||
--- a/src/cmd/ksh93/tests/builtins.sh
|
||||
+++ b/src/cmd/ksh93/tests/builtins.sh
|
||||
@@ -1222,6 +1222,28 @@ function test_usage
|
||||
done 3< <(builtin)
|
||||
}; test_usage
|
||||
|
||||
+# ======
|
||||
+# The 'alarm' builtin could make 'read' crash due to IFS table corruption caused by unsafe asynchronous execution.
|
||||
+# https://bugzilla.redhat.com/1176670
|
||||
+if (builtin alarm) 2>/dev/null
|
||||
+then got=$( { "$SHELL" -c '
|
||||
+ builtin alarm
|
||||
+ alarm -r alarm_handler +.005
|
||||
+ i=0
|
||||
+ function alarm_handler.alarm
|
||||
+ {
|
||||
+ let "(++i) > 20" && exit
|
||||
+ }
|
||||
+ while :; do
|
||||
+ echo cargo,odds and ends,jetsam,junk,wreckage,castoffs,sea-drift
|
||||
+ done | while IFS="," read arg1 arg2 arg3 arg4 junk; do
|
||||
+ :
|
||||
+ done
|
||||
+ '; } 2>&1)
|
||||
+ ((!(e = $?))) || err_exit 'crash with alarm and IFS' \
|
||||
+ "(got status $e$( ((e>128)) && print -n /SIG && kill -l "$e"), $(printf %q "$got"))"
|
||||
+fi
|
||||
+
|
||||
# ======
|
||||
# Verify that the POSIX 'test' builtin exits with status 2 when given an invalid binary operator.
|
||||
for operator in '===' ']]'
|
||||
@@ -1581,7 +1603,7 @@ let Errors+=$?
|
||||
# Most built-ins should handle --version
|
||||
while IFS= read -r bltin <&3
|
||||
do case $bltin in
|
||||
- echo | test | true | false | \[ | : | catclose | catgets | catopen | Dt* | _Dt* | X* | login | newgrp )
|
||||
+ alarm | echo | test | true | false | \[ | : | catclose | catgets | catopen | Dt* | _Dt* | X* | login | newgrp )
|
||||
continue ;;
|
||||
fc | hist )
|
||||
((SHOPT_SCRIPTONLY)) && continue ;;
|
@ -1,162 +0,0 @@
|
||||
diff --git a/src/cmd/ksh93/Mamfile b/src/cmd/ksh93/Mamfile
|
||||
index abc9ee1a5..d266f2178 100644
|
||||
--- a/src/cmd/ksh93/Mamfile
|
||||
+++ b/src/cmd/ksh93/Mamfile
|
||||
@@ -222,6 +222,10 @@ make install
|
||||
prev shell.req
|
||||
make alarm.o
|
||||
make bltins/alarm.c
|
||||
+ make include/io.h implicit
|
||||
+ prev ${PACKAGE_ast_INCLUDE}/sfio.h
|
||||
+ prev ${PACKAGE_ast_INCLUDE}/ast.h
|
||||
+ done include/io.h
|
||||
make FEATURE/time implicit
|
||||
prev features/time
|
||||
exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/time
|
||||
@@ -239,6 +243,22 @@ make install
|
||||
done FEATURE/dynamic generated
|
||||
prev ${PACKAGE_ast_INCLUDE}/option.h
|
||||
done include/builtins.h
|
||||
+ make include/shlex.h implicit
|
||||
+ make include/lexstates.h implicit
|
||||
+ prev ${PACKAGE_ast_INCLUDE}/wctype.h
|
||||
+ prev ${PACKAGE_ast_INCLUDE}/wchar.h
|
||||
+ make FEATURE/locale implicit
|
||||
+ prev features/locale
|
||||
+ exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/locale
|
||||
+ done FEATURE/locale generated
|
||||
+ done include/lexstates.h
|
||||
+ prev include/shtable.h
|
||||
+ make include/shnodes.h implicit
|
||||
+ prev include/argnod.h implicit
|
||||
+ prev ${PACKAGE_ast_INCLUDE}/ast.h
|
||||
+ done include/shnodes.h
|
||||
+ prev ${PACKAGE_ast_INCLUDE}/cdt.h
|
||||
+ done include/shlex.h
|
||||
prev ${PACKAGE_ast_INCLUDE}/error.h
|
||||
make include/defs.h implicit
|
||||
prev include/regress.h implicit
|
||||
@@ -246,7 +266,7 @@ make install
|
||||
prev include/shell.h
|
||||
prev ${PACKAGE_ast_INCLUDE}/endian.h
|
||||
prev include/name.h
|
||||
- prev include/argnod.h implicit
|
||||
+ prev include/argnod.h
|
||||
prev ${PACKAGE_ast_INCLUDE}/cdt.h
|
||||
prev FEATURE/externs
|
||||
prev ${PACKAGE_ast_INCLUDE}/error.h
|
||||
@@ -292,10 +312,7 @@ make install
|
||||
make cflow.o
|
||||
make bltins/cflow.c
|
||||
prev include/builtins.h
|
||||
- make include/shnodes.h implicit
|
||||
- prev include/argnod.h
|
||||
- prev ${PACKAGE_ast_INCLUDE}/ast.h
|
||||
- done include/shnodes.h
|
||||
+ prev include/shnodes.h
|
||||
prev ${PACKAGE_ast_INCLUDE}/error.h
|
||||
prev ${PACKAGE_ast_INCLUDE}/ast.h
|
||||
prev include/defs.h
|
||||
@@ -341,10 +358,7 @@ make install
|
||||
done FEATURE/ttys generated
|
||||
done include/terminal.h
|
||||
prev ${PACKAGE_ast_INCLUDE}/sig.h
|
||||
- make FEATURE/locale implicit
|
||||
- prev features/locale
|
||||
- exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/locale
|
||||
- done FEATURE/locale generated
|
||||
+ prev FEATURE/locale
|
||||
make FEATURE/cmds implicit
|
||||
prev features/cmds
|
||||
exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/cmds
|
||||
@@ -353,6 +367,7 @@ make install
|
||||
prev include/builtins.h
|
||||
prev include/history.h
|
||||
prev include/name.h
|
||||
+ prev include/io.h
|
||||
make include/io.h implicit
|
||||
prev ${PACKAGE_ast_INCLUDE}/sfio.h
|
||||
prev ${PACKAGE_ast_INCLUDE}/ast.h
|
||||
@@ -443,11 +458,7 @@ make install
|
||||
prev include/builtins.h
|
||||
prev include/name.h
|
||||
prev include/io.h
|
||||
- make include/lexstates.h implicit
|
||||
- prev ${PACKAGE_ast_INCLUDE}/wctype.h
|
||||
- prev ${PACKAGE_ast_INCLUDE}/wchar.h
|
||||
- prev FEATURE/locale
|
||||
- done include/lexstates.h
|
||||
+ prev include/lexstates.h
|
||||
prev include/variables.h
|
||||
prev include/defs.h
|
||||
prev ${PACKAGE_ast_INCLUDE}/error.h
|
||||
@@ -545,12 +556,7 @@ make install
|
||||
make whence.o
|
||||
make bltins/whence.c
|
||||
prev include/builtins.h
|
||||
- make include/shlex.h implicit
|
||||
- prev include/lexstates.h
|
||||
- prev include/shtable.h
|
||||
- prev include/shnodes.h
|
||||
- prev ${PACKAGE_ast_INCLUDE}/cdt.h
|
||||
- done include/shlex.h
|
||||
+ prev include/shlex.h
|
||||
prev include/path.h
|
||||
prev include/name.h
|
||||
prev include/shtable.h
|
||||
diff --git a/src/cmd/ksh93/bltins/alarm.c b/src/cmd/ksh93/bltins/alarm.c
|
||||
index f31bed711..63d4d6cbf 100644
|
||||
--- a/src/cmd/ksh93/bltins/alarm.c
|
||||
+++ b/src/cmd/ksh93/bltins/alarm.c
|
||||
@@ -23,21 +23,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
-/*
|
||||
- * TODO: 2014 email from David Korn cited at <https://bugzilla.redhat.com/1176670>:
|
||||
- *
|
||||
- * > I never documented the alarm builtin because it is problematic. The
|
||||
- * > problem is that traps can't safely be handled asynchronously. What should
|
||||
- * > happen is that the trap is marked for execution (sh.trapnote) and run after
|
||||
- * > the current command completes. The time trap should wake up the shell if
|
||||
- * > it is blocked and it should return and then handle the trap.
|
||||
- */
|
||||
-
|
||||
#include "shopt.h"
|
||||
#include "defs.h"
|
||||
#include <error.h>
|
||||
+#include <shlex.h>
|
||||
#include "builtins.h"
|
||||
#include "FEATURE/time"
|
||||
+#include "io.h"
|
||||
|
||||
#define R_FLAG 1
|
||||
#define L_FLAG 2
|
||||
@@ -147,7 +139,26 @@ void sh_timetraps(void)
|
||||
{
|
||||
tp->flags &= ~L_FLAG;
|
||||
if(tp->action)
|
||||
- sh_fun(tp->action,tp->node,NULL);
|
||||
+ {
|
||||
+ /* Call the alarm discipline function. This may occur at any time including parse time,
|
||||
+ * so save the lexer state and push/pop context to make sure we can restore it. */
|
||||
+ struct checkpt checkpoint;
|
||||
+ int jmpval;
|
||||
+ int savexit = sh.savexit;
|
||||
+ Lex_t *lexp = (Lex_t*)sh.lex_context, savelex = *lexp;
|
||||
+ sh_lexopen(lexp, 0); /* needs full init (0), not what it calls reinit (1) */
|
||||
+ sh_pushcontext(&checkpoint, 1);
|
||||
+ jmpval = sigsetjmp(checkpoint.buff,0);
|
||||
+ if(!jmpval)
|
||||
+ sh_fun(tp->action,tp->node,NULL);
|
||||
+ sh_popcontext(&checkpoint);
|
||||
+ if(sh.topfd != checkpoint.topfd)
|
||||
+ sh_iorestore(checkpoint.topfd,jmpval);
|
||||
+ *lexp = savelex;
|
||||
+ sh.savexit = savexit; /* avoid influencing $? */
|
||||
+ if(jmpval)
|
||||
+ siglongjmp(*sh.jmplist,jmpval);
|
||||
+ }
|
||||
tp->flags &= ~L_FLAG;
|
||||
if(!tp->flags)
|
||||
nv_unset(tp->node);
|
@ -1,99 +0,0 @@
|
||||
From 2075b2b96208ac8b989ca316dcdd674c3f488e2b Mon Sep 17 00:00:00 2001
|
||||
From: Martijn Dekker <martijn@inlv.org>
|
||||
Date: Thu, 28 Dec 2023 04:02:28 +0000
|
||||
Subject: [PATCH] Fix crash on failure to trim ~/.sh_history
|
||||
|
||||
@vmihalko writes:
|
||||
> We were able to reproduce an old issue mentioned in
|
||||
> https://bugzilla.redhat.com/show_bug.cgi?id=1885399 using the
|
||||
> latest version of ksh. The corresponding code has not changed
|
||||
> much in the past few years.
|
||||
>
|
||||
> To provide further explanation, the problem arises when a user's
|
||||
> .sh_history file grows to a size that triggers the hist_trim
|
||||
> function, but the user lacks (after the creation of .sh_history)
|
||||
> the necessary write permissions to their $HOME directory. As a
|
||||
> result, ksh becomes stuck in a recursive loop between the
|
||||
> sh_histinit(src/cmd/ksh93/edit/history.c#L203) function and the
|
||||
> hist_trim(src/cmd/ksh93/edit/history.c#L417) function.
|
||||
>
|
||||
> Conditions for reproduction:
|
||||
>
|
||||
> 1. The size of the .sh_history file is larger than the HIST_MAX
|
||||
> limit. (src/cmd/ksh93/edit/history.c, line 325)
|
||||
> 2. .sh_history file has not been changed in the HIST_RECENT
|
||||
> seconds (src/cmd/ksh93/edit/history.c, line 406)
|
||||
> 3. The user does not have permission to write to the $HOME
|
||||
> directory.
|
||||
|
||||
src/cmd/ksh93/edit/history.c: hist_trim():
|
||||
- Print a warning and return if unlink(2) fails. The warning tells
|
||||
the user to check the history file's parent directory is
|
||||
writable. This is the best I realistically do for now, because
|
||||
this function's basic method assumes a writable parent directory.
|
||||
- The temp file fallback is deleted because it's fundamentally
|
||||
flawed: it assumes the temp file is made on the same volume as
|
||||
the history file and can simply be rename(2)'d in place. Even
|
||||
on systems where this is the case, it doesn't appear to be
|
||||
working correctly, but this is not worth looking into.
|
||||
|
||||
Resolves: https://github.com/ksh93/ksh/issues/695
|
||||
---
|
||||
src/cmd/ksh93/edit/history.c | 34 ++++------------------------------
|
||||
1 files changed, 4 insertions(+), 30 deletions(-)
|
||||
|
||||
diff --git a/src/cmd/ksh93/edit/history.c b/src/cmd/ksh93/edit/history.c
|
||||
index c49c23244d00..f3672bf6e220 100644
|
||||
--- a/src/cmd/ksh93/edit/history.c
|
||||
+++ b/src/cmd/ksh93/edit/history.c
|
||||
@@ -419,34 +419,13 @@ static History_t* hist_trim(History_t *hp, int n)
|
||||
char *cp;
|
||||
int incmd=1, c=0;
|
||||
History_t *hist_new, *hist_old = hp;
|
||||
- char *buff, *endbuff, *tmpname=0;
|
||||
+ char *buff, *endbuff;
|
||||
off_t oldp,newp;
|
||||
struct stat statb;
|
||||
- unlink(hist_old->histname);
|
||||
- if(access(hist_old->histname,F_OK) >= 0)
|
||||
+ if(unlink(hist_old->histname) < 0)
|
||||
{
|
||||
- /* The unlink can fail on Windows 95 */
|
||||
- int fd;
|
||||
- char *last, *name=hist_old->histname;
|
||||
- sh_close(sffileno(hist_old->histfp));
|
||||
- tmpname = (char*)sh_malloc(strlen(name)+14);
|
||||
- if(last = strrchr(name,'/'))
|
||||
- {
|
||||
- *last = 0;
|
||||
- pathtmp(tmpname,name,"hist",NULL);
|
||||
- *last = '/';
|
||||
- }
|
||||
- else
|
||||
- pathtmp(tmpname,e_dot,"hist",NULL);
|
||||
- if(rename(name,tmpname) < 0)
|
||||
- {
|
||||
- free(tmpname);
|
||||
- tmpname = name;
|
||||
- }
|
||||
- fd = open(tmpname,O_RDONLY|O_cloexec);
|
||||
- sfsetfd(hist_old->histfp,fd);
|
||||
- if(tmpname==name)
|
||||
- tmpname = 0;
|
||||
+ errormsg(SH_DICT,ERROR_warn(0),"cannot trim history file %s; make sure parent directory is writable",hist_old->histname);
|
||||
+ return hist_ptr = hist_old;
|
||||
}
|
||||
hist_ptr = 0;
|
||||
if(fstat(sffileno(hist_old->histfp),&statb)>=0)
|
||||
@@ -501,11 +480,6 @@ static History_t* hist_trim(History_t *hp, int n)
|
||||
}
|
||||
hist_cancel(hist_new);
|
||||
sfclose(hist_old->histfp);
|
||||
- if(tmpname)
|
||||
- {
|
||||
- unlink(tmpname);
|
||||
- free(tmpname);
|
||||
- }
|
||||
free((char*)hist_old);
|
||||
return hist_ptr = hist_new;
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
From 9eb8532ccacf1cfdb7ba18f51eba68776852ef7c Mon Sep 17 00:00:00 2001
|
||||
From: Vincent Mihalkovic <vmihalko@redhat.com>
|
||||
Date: Thu, 8 Feb 2024 22:10:58 +0100
|
||||
Subject: [PATCH] Re-fix use of strdup on a NULL pointer (re: 9a9da2c2) (#718)
|
||||
|
||||
Thank you @lzaoral for debugging this issue and creating this
|
||||
reproducer:
|
||||
|
||||
$ tty # check that the shell is connected to a pseudoterminal
|
||||
/dev/pts/4
|
||||
$ mkdir /var/tmp/chroottest
|
||||
$ dnf --releasever=39 --installroot=/var/tmp/chroottest install ksh
|
||||
$ echo "/dev/udp/127.0.0.1/514;0;104" |
|
||||
sudo tee /var/tmp/chroottest/etc/ksh_audit
|
||||
$ sudo chroot /var/tmp/chroottest /bin/ksh -lic 'exit 0'
|
||||
(ksh segfaults)
|
||||
|
||||
Analysis: On Linux, ttyname(3)[*] may fail if:
|
||||
|
||||
* EBADF Bad file descriptor.
|
||||
* ENODEV fd refers to a slave pseudoterminal device but the
|
||||
corresponding pathname could not be found [...].
|
||||
* ENOTTY fd does not refer to a terminal device.
|
||||
|
||||
Calling isatty(3) before ttyname(3) only prevents the first and
|
||||
third cases.
|
||||
|
||||
src/cmd/ksh93/edit/history.c: sh_histinit():
|
||||
- To catch the second case, let's call ttyname(2) directly, check
|
||||
for NULL and remove the redundant isatty() call.
|
||||
|
||||
[*] https://man7.org/linux/man-pages/man3/ttyname.3.html
|
||||
---
|
||||
src/cmd/ksh93/edit/history.c | 4 +++-
|
||||
1 files changed, 3 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/src/cmd/ksh93/edit/history.c b/src/cmd/ksh93/edit/history.c
|
||||
index a7b084e5c16f..25832a59265b 100644
|
||||
--- a/src/cmd/ksh93/edit/history.c
|
||||
+++ b/src/cmd/ksh93/edit/history.c
|
||||
@@ -15,6 +15,7 @@
|
||||
* Johnothan King <johnothanking@protonmail.com> *
|
||||
* hyenias <58673227+hyenias@users.noreply.github.com> *
|
||||
* Govind Kamat <govind_kamat@yahoo.com> *
|
||||
+* Vincent Mihalkovic <vmihalko@redhat.com> *
|
||||
* *
|
||||
***********************************************************************/
|
||||
/*
|
||||
@@ -353,7 +354,8 @@ int sh_histinit(void)
|
||||
if(fd>=0)
|
||||
{
|
||||
fcntl(fd,F_SETFD,FD_CLOEXEC);
|
||||
- hp->tty = sh_strdup(isatty(2)?ttyname(2):"notty");
|
||||
+ const char* tty = ttyname(2);
|
||||
+ hp->tty = sh_strdup(tty?tty:"notty");
|
||||
hp->auditfp = sfnew(NULL,NULL,-1,fd,SF_WRITE);
|
||||
}
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
diff --git a/src/cmd/ksh93/bltins/cflow.c b/src/cmd/ksh93/bltins/cflow.c
|
||||
index b7cfd19..66e0f70 100644
|
||||
--- a/src/cmd/ksh93/bltins/cflow.c
|
||||
+++ b/src/cmd/ksh93/bltins/cflow.c
|
||||
@@ -67,8 +67,12 @@ done:
|
||||
{
|
||||
long l = strtol(*argv, NULL, 10);
|
||||
if(do_exit)
|
||||
+ {
|
||||
n = (int)(l & SH_EXITMASK); /* exit: apply bitmask before conversion to avoid undefined int overflow */
|
||||
- else if((long)(n = (int)l) != l) /* return: convert to int and check for overflow (should be safe enough) */
|
||||
+ if (sh.intrap)
|
||||
+ sh.intrap_exit_n = 1;
|
||||
+ }
|
||||
+ else if((long)(n = (int)l) != l) /* return: convert to int and check for overflow (should be safe enough) */
|
||||
{
|
||||
errormsg(SH_DICT,ERROR_warn(0),"%s: out of range",*argv);
|
||||
n = 128; /* overflow is undefined, so use a consistent status for this */
|
||||
diff --git a/src/cmd/ksh93/include/shell.h b/src/cmd/ksh93/include/shell.h
|
||||
index 9794995..58e2f2a 100644
|
||||
--- a/src/cmd/ksh93/include/shell.h
|
||||
+++ b/src/cmd/ksh93/include/shell.h
|
||||
@@ -308,6 +308,7 @@ struct Shell_s
|
||||
int savesig;
|
||||
unsigned char *sigflag; /* pointer to signal states */
|
||||
char intrap;
|
||||
+ char intrap_exit_n; /* set if 'exit n' within trap */
|
||||
char forked;
|
||||
char binscript;
|
||||
char funload;
|
||||
diff --git a/src/cmd/ksh93/sh/fault.c b/src/cmd/ksh93/sh/fault.c
|
||||
index 510bf56..8222a9d 100644
|
||||
--- a/src/cmd/ksh93/sh/fault.c
|
||||
+++ b/src/cmd/ksh93/sh/fault.c
|
||||
@@ -528,11 +528,7 @@ int sh_trap(const char *trap, int mode)
|
||||
if(jmpval==SH_JMPSCRIPT)
|
||||
indone=0;
|
||||
else
|
||||
- {
|
||||
- if(jmpval==SH_JMPEXIT)
|
||||
- savxit = sh.exitval;
|
||||
jmpval=SH_JMPTRAP;
|
||||
- }
|
||||
}
|
||||
sh_popcontext(&buff);
|
||||
/* re-allow last-command exec optimisation unless the command we executed set a trap */
|
||||
@@ -541,8 +537,10 @@ int sh_trap(const char *trap, int mode)
|
||||
sh.intrap--;
|
||||
sfsync(sh.outpool);
|
||||
savxit_return = sh.exitval;
|
||||
- if(jmpval!=SH_JMPEXIT && jmpval!=SH_JMPFUN)
|
||||
- sh.exitval=savxit;
|
||||
+ if(sh.intrap_exit_n)
|
||||
+ sh.intrap_exit_n = 0;
|
||||
+ else
|
||||
+ sh.exitval = savxit;
|
||||
stkset(sh.stk,savptr,staktop);
|
||||
fcrestore(&savefc);
|
||||
if(was_history)
|
||||
diff --git a/src/cmd/ksh93/tests/return.sh b/src/cmd/ksh93/tests/return.sh
|
||||
index 25e4c7a..8db197b 100755
|
||||
--- a/src/cmd/ksh93/tests/return.sh
|
||||
+++ b/src/cmd/ksh93/tests/return.sh
|
||||
@@ -247,5 +247,15 @@ foo && err_exit "'exit' within { block; } with redirection does not preserve exi
|
||||
foo() { false; (exit); }
|
||||
foo && err_exit "'exit' within subshell does not preserve exit status"
|
||||
|
||||
+# ======
|
||||
+# old AT&T bug reintroduced in v1.0.8 (commit aea99158)
|
||||
+f() { true; return; }
|
||||
+trap 'f; echo $? >out' USR1
|
||||
+(exit 13)
|
||||
+kill -s USR1 ${.sh.pid}
|
||||
+trap - USR1
|
||||
+unset -f f
|
||||
+[[ $(<out) == 0 ]] || err_exit "default return status in traps is broken (expected 0, got $(<out))"
|
||||
+
|
||||
# ======
|
||||
exit $((Errors<125?Errors:125))
|
Loading…
Reference in new issue