1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-02-14 20:22:21 +00:00

[v1.0] remove alarm builtin

It's undocumented, it's broken and can crash the shell, and it's
unclear if it can ever be fixed. So with a 1.0 release (hopefully)
not very far off, it's time to remove it from the 1.0 branch.

Related: https://github.com/ksh93/ksh/issues/422
This commit is contained in:
Martijn Dekker 2022-06-21 05:45:53 +01:00
parent cae9af5eec
commit 4d50b69cbd
8 changed files with 38 additions and 341 deletions

View file

@ -218,18 +218,34 @@ make install
done pmain.o generated
make libshell.a archive
prev shell.req
make alarm.o
make bltins/alarm.c
make FEATURE/time implicit
make features/time
done 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
make ${PACKAGE_ast_INCLUDE}/ast_time.h implicit
done ${PACKAGE_ast_INCLUDE}/ast_time.h dontcare
make cd_pwd.o
make bltins/cd_pwd.c
make include/test.h implicit
prev include/shtable.h implicit
make include/defs.h implicit
make include/regress.h implicit
done include/regress.h dontcare
prev include/shtable.h implicit
prev include/shell.h implicit
prev ${PACKAGE_ast_INCLUDE}/endian.h implicit
prev include/name.h implicit
make include/argnod.h implicit
prev ${PACKAGE_ast_INCLUDE}/stak.h implicit
done include/argnod.h dontcare
prev ${PACKAGE_ast_INCLUDE}/cdt.h implicit
prev FEATURE/options implicit
prev ${PACKAGE_ast_INCLUDE}/error.h implicit
prev ${PACKAGE_ast_INCLUDE}/sfio.h implicit
prev ${PACKAGE_ast_INCLUDE}/ast.h implicit
done ${PACKAGE_ast_INCLUDE}/times.h dontcare
done FEATURE/time generated
done include/defs.h
prev FEATURE/options implicit
done include/test.h
make ${PACKAGE_ast_INCLUDE}/ls.h implicit
make ${PACKAGE_ast_INCLUDE}/ast_mode.h implicit
done ${PACKAGE_ast_INCLUDE}/ast_mode.h dontcare
prev ${PACKAGE_ast_INCLUDE}/ast_fs.h implicit
prev ${PACKAGE_ast_INCLUDE}/ast_std.h implicit
done ${PACKAGE_ast_INCLUDE}/ls.h
make include/builtins.h implicit
make include/shtable.h implicit
done include/shtable.h dontcare
@ -246,44 +262,6 @@ make install
done FEATURE/options dontcare generated
prev ${PACKAGE_ast_INCLUDE}/option.h implicit
done include/builtins.h
prev ${PACKAGE_ast_INCLUDE}/stak.h implicit
prev ${PACKAGE_ast_INCLUDE}/error.h implicit
make include/defs.h implicit
make include/regress.h implicit
done include/regress.h dontcare
prev include/shtable.h implicit
prev include/shell.h implicit
prev ${PACKAGE_ast_INCLUDE}/endian.h implicit
prev include/name.h implicit
make include/argnod.h implicit
prev ${PACKAGE_ast_INCLUDE}/stak.h implicit
done include/argnod.h dontcare
prev ${PACKAGE_ast_INCLUDE}/cdt.h implicit
prev FEATURE/options implicit
prev FEATURE/externs implicit
prev ${PACKAGE_ast_INCLUDE}/error.h implicit
prev ${PACKAGE_ast_INCLUDE}/sfio.h implicit
prev ${PACKAGE_ast_INCLUDE}/ast.h implicit
done include/defs.h
prev shopt.h implicit
done bltins/alarm.c
prev bltins/alarm.c
exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -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 implicit
prev include/defs.h implicit
prev FEATURE/options implicit
done include/test.h
make ${PACKAGE_ast_INCLUDE}/ls.h implicit
make ${PACKAGE_ast_INCLUDE}/ast_mode.h implicit
done ${PACKAGE_ast_INCLUDE}/ast_mode.h dontcare
prev ${PACKAGE_ast_INCLUDE}/ast_fs.h implicit
prev ${PACKAGE_ast_INCLUDE}/ast_std.h implicit
done ${PACKAGE_ast_INCLUDE}/ls.h
prev include/builtins.h implicit
prev include/name.h implicit
make include/path.h implicit
make FEATURE/acct implicit
@ -383,7 +361,16 @@ make install
make misc.o
make bltins/misc.c
prev ${PACKAGE_ast_INCLUDE}/times.h implicit
prev FEATURE/time implicit
make FEATURE/time implicit
make features/time
done 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
make ${PACKAGE_ast_INCLUDE}/ast_time.h implicit
done ${PACKAGE_ast_INCLUDE}/ast_time.h dontcare
prev ${PACKAGE_ast_INCLUDE}/ast.h implicit
done ${PACKAGE_ast_INCLUDE}/times.h dontcare
done FEATURE/time generated
prev FEATURE/locale implicit
make include/jobs.h implicit
prev ${PACKAGE_ast_INCLUDE}/vmalloc.h implicit
@ -1302,7 +1289,7 @@ make install
prev edit/hexpand.c
exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c edit/hexpand.c
done hexpand.o generated
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 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

View file

@ -1,281 +0,0 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1982-2012 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* http://www.eclipse.org/org/documents/epl-v10.html *
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* David Korn <dgk@research.att.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 <stak.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)
{
register struct tevent *tp = (struct tevent*)list;
if(!tp || item->milli < tp->milli)
{
item->next = tp;
list = (void*)item;
}
else
{
while(tp->next && item->milli > tp->next->milli)
tp = tp->next;
item->next = tp->next;
tp->next = item;
}
tp = item;
tp->timeout = (void*)sh_timeradd(tp->milli,tp->flags&R_FLAG,trap_timeout,(void*)tp);
return(list);
}
/*
* delete timeout item from current given list, delete timer
*/
static void *time_delete(register struct tevent *item, void *list)
{
register struct tevent *tp = (struct tevent*)list;
if(item==tp)
list = (void*)tp->next;
else
{
while(tp && tp->next != item)
tp = tp->next;
if(tp)
tp->next = item->next;
}
if(item->timeout)
timerdel((void*)item->timeout);
return(list);
}
static void print_alarms(void *list)
{
register struct tevent *tp = (struct tevent*)list;
while(tp)
{
if(tp->timeout)
{
register 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)
{
register 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)
{
register struct tevent *tp, *tpnext;
register 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,(char**)0);
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)
{
register 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)
{
register struct tevent *tp = (struct tevent*)fp;
register 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(NIL(time_t*));
#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, (Namfun_t*)0);
sh.st.timetrap = time_delete(tp,sh.st.timetrap);
nv_unset(np);
free((void*)fp);
}
}
static const Namdisc_t alarmdisc =
{
sizeof(struct tevent),
putval,
0,
0,
setdisc,
};
int b_alarm(int argc,char *argv[],Shbltin_t *context)
{
register int n,rflag=0;
register Namval_t *np;
register 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((char*)0));
UNREACHABLE();
}
if(argc==0)
{
print_alarms(sh.st.timetrap);
return(0);
}
if(argc!=2)
{
errormsg(SH_DICT,ERROR_usage(2),optusage((char*)0));
UNREACHABLE();
}
np = nv_open(argv[0],sh.var_tree,NV_NOARRAY|NV_VARNAME|NV_NOASSIGN);
if(!nv_isnull(np))
nv_unset(np);
nv_setattr(np, NV_DOUBLE);
tp = sh_newof(NIL(struct tevent*),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);
}

View file

@ -129,8 +129,6 @@ skip:
if(tloc < (now=time(NIL(time_t*))))
break;
d = (double)(tloc-now);
if(sh.sigflag[SIGALRM]&SH_SIGTRAP)
sh_timetraps();
}
return(0);
}

View file

@ -125,7 +125,6 @@ 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),

View file

@ -151,7 +151,6 @@ 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*);

View file

@ -62,7 +62,6 @@ 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 */

View file

@ -425,8 +425,6 @@ 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);

View file

@ -1527,8 +1527,6 @@ int job_wait(register pid_t pid)
continue;
if(nochild)
break;
if(sh.sigflag[SIGALRM]&SH_SIGTRAP)
sh_timetraps();
if((intr && sh.trapnote) || (pid==1 && !intr))
break;
}