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:
parent
cae9af5eec
commit
4d50b69cbd
8 changed files with 38 additions and 341 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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*);
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue