zsh-workers
 help / color / mirror / code / Atom feed
* Is there a way to put a timeout on a function?
@ 2020-08-31 14:59 Rudi C
  2020-09-04 21:14 ` Bart Schaefer
  0 siblings, 1 reply; 2+ messages in thread
From: Rudi C @ 2020-08-31 14:59 UTC (permalink / raw)
  To: zsh-workers

[-- Attachment #1: Type: text/plain, Size: 552 bytes --]

I need to limit the execution time of arbitrary zsh functions. Is there a
way to achieve this? I'm ok with just adding a time limit to all the
external commands, but I do not know how to do that. (I don't want to
manually prefix all my commands with the GNU timeout command.)

On a sidenote, I would also like to make the shell stop forcefully (like
when a glob fails) if it doesn't find an external command. I thought maybe
these two problems might have similar solutions. Is prexec viable for them?
Does preexec even work for noninteractive scripts?

[-- Attachment #2: Type: text/html, Size: 610 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Is there a way to put a timeout on a function?
  2020-08-31 14:59 Is there a way to put a timeout on a function? Rudi C
@ 2020-09-04 21:14 ` Bart Schaefer
  0 siblings, 0 replies; 2+ messages in thread
From: Bart Schaefer @ 2020-09-04 21:14 UTC (permalink / raw)
  To: Rudi C; +Cc: zsh-workers

On Mon, Aug 31, 2020 at 8:00 AM Rudi C <rudiwillalwaysloveyou@gmail.com> wrote:
>
> I need to limit the execution time of arbitrary zsh functions. Is there a way to achieve this? I'm ok with just adding a time limit to all the external commands, but I do not know how to do that. (I don't want to manually prefix all my commands with the GNU timeout command.)

Here's a basic outline; you'll have to fiddle with it to get the
details as you want:

# This is the default, but for clarity
setopt DEBUG_BEFORE_CMD
TRAPDEBUG() {
 #  Prevent the command from running twice
 setopt localoptions ERR_EXIT
 # Set up the timeout
 sleep $DESIRED_TIMEOUT &
 timer=$!
 # Background so parent can wait for timer
 (){ eval "${ZSH_DEBUG_CMD}"; kill $timer } &
 victim=$!
 wait $timer && kill $victim
}

Note that this prevents anything from changing the state of the
current shell, so be careful experimenting with it.  One of the things
you probably need to "fiddle with" is to have this function return
BEFORE it sets ERR_EXIT for any command that SHOULD run in the current
shell.  Another is that this buries the exit status of the command, so
you need a way to capture it.

> On a sidenote, I would also like to make the shell stop forcefully (like when a glob fails) if it doesn't find an external command. I thought maybe these two problems might have similar solutions. Is prexec viable for them? Does preexec even work for noninteractive scripts?

Preexec and precmd are strictly for interactive shells.

Another potentially dangerous solution:

command_not_found_handler() {
 builtin print "command not found: $*"
 builtin kill -USR1 $$
}
TRAPUSR1() { exit 1 }

Aside to -workers:  I've had this go into an infinite recursion if the
TRAPUSR1 definition precedes the command_not_found_handler definition
and/or the "builtin" prefix is not used.  This seems odd, but is not
reliably reproducible.


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-09-04 21:15 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-31 14:59 Is there a way to put a timeout on a function? Rudi C
2020-09-04 21:14 ` Bart Schaefer

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).