Hi Chet,

The sleep command is often used in loops and using the external sleep
is expensive.  Perhaps we can add the sleep builtin but have it
disabled by default to avoid syntax conflict with the external one.
Users who would want the builtin version can simply run:

[[ BASH_VERSINFO -ge 5 ]] && enable sleep

I have patch attached as file, and also uploaded in
https://github.com/konsolebox/bash/tree/builtin_sleep.

-- 
konsolebox
commit 14203764a208279d213d2b4c0babf52abca6078b
Author: konsolebox <konsole...@gmail.com>
Date:   Sun Jul 29 07:58:32 2018 +0800

    Add sleep as a static builtin that is disabled by default.

diff --git a/Makefile.in b/Makefile.in
index 5fcb44b..b56af30 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -505,7 +505,7 @@ BUILTIN_DEFS = $(DEFSRC)/alias.def $(DEFSRC)/bind.def $(DEFSRC)/break.def \
 	       $(DEFSRC)/ulimit.def $(DEFSRC)/umask.def $(DEFSRC)/wait.def \
 	       $(DEFSRC)/getopts.def $(DEFSRC)/reserved.def \
 	       $(DEFSRC)/pushd.def $(DEFSRC)/shopt.def $(DEFSRC)/printf.def \
-	       $(DEFSRC)/mapfile.def
+	       $(DEFSRC)/mapfile.def $(DEFSRC)/sleep.def
 BUILTIN_C_SRC  = $(DEFSRC)/mkbuiltins.c $(DEFSRC)/common.c \
 		 $(DEFSRC)/evalstring.c $(DEFSRC)/evalfile.c \
 		 $(DEFSRC)/bashgetopt.c $(GETOPT_SOURCE)
@@ -1650,4 +1650,5 @@ builtins/trap.o: $(DEFSRC)/trap.def
 builtins/type.o: $(DEFSRC)/type.def
 builtins/ulimit.o: $(DEFSRC)/ulimit.def
 builtins/umask.o: $(DEFSRC)/umask.def
+builtins/sleep.o: $(DEFSRC)/sleep.def
 builtins/wait.o: $(DEFSRC)/wait.def
diff --git a/builtins/Makefile.in b/builtins/Makefile.in
index 388ca4e..7514a44 100644
--- a/builtins/Makefile.in
+++ b/builtins/Makefile.in
@@ -143,7 +143,8 @@ DEFSRC =  $(srcdir)/alias.def $(srcdir)/bind.def $(srcdir)/break.def \
 	  $(srcdir)/times.def $(srcdir)/trap.def $(srcdir)/type.def \
 	  $(srcdir)/ulimit.def $(srcdir)/umask.def $(srcdir)/wait.def \
 	  $(srcdir)/reserved.def $(srcdir)/pushd.def $(srcdir)/shopt.def \
-	  $(srcdir)/printf.def $(srcdir)/complete.def $(srcdir)/mapfile.def
+	  $(srcdir)/printf.def $(srcdir)/complete.def $(srcdir)/mapfile.def \
+	  $(srcdir)/sleep.def
 
 STATIC_SOURCE = common.c evalstring.c evalfile.c getopt.c bashgetopt.c \
 		getopt.h 
@@ -152,7 +153,7 @@ OFILES = builtins.o \
 	alias.o bind.o break.o builtin.o caller.o cd.o colon.o command.o \
 	common.o declare.o echo.o enable.o eval.o evalfile.o \
 	evalstring.o exec.o exit.o fc.o fg_bg.o hash.o help.o history.o \
-	jobs.o kill.o let.o mapfile.o \
+	jobs.o kill.o let.o mapfile.o sleep.o \
 	pushd.o read.o return.o set.o setattr.o shift.o source.o \
 	suspend.o test.o times.o trap.o type.o ulimit.o umask.o \
 	wait.o getopts.o shopt.o printf.o getopt.o bashgetopt.o complete.o
@@ -315,6 +316,7 @@ trap.o: trap.def
 type.o: type.def
 ulimit.o: ulimit.def
 umask.o: umask.def
+sleep.o: sleep.def
 wait.o: wait.def
 getopts.o: getopts.def
 reserved.o: reserved.def
diff --git a/builtins/mkbuiltins.c b/builtins/mkbuiltins.c
index 4f51201..b912d49 100644
--- a/builtins/mkbuiltins.c
+++ b/builtins/mkbuiltins.c
@@ -73,6 +73,7 @@ extern char *strcpy ();
 #define BUILTIN_FLAG_ASSIGNMENT 0x02
 #define BUILTIN_FLAG_LOCALVAR	0x04
 #define BUILTIN_FLAG_POSIX_BUILTIN 0x08
+#define BUILTIN_FLAG_INITIALLY_DISABLED 0x10
 
 #define BASE_INDENT	4
 
@@ -173,11 +174,18 @@ char *posix_builtins[] =
   (char *)NULL
 };
 
+/* Initially disabled builtins */
+char *initially_disabled_builtins[] =
+{
+  "sleep"
+};
+
 /* Forward declarations. */
 static int is_special_builtin ();
 static int is_assignment_builtin ();
 static int is_localvar_builtin ();
 static int is_posix_builtin ();
+static int is_initially_disabled ();
 
 #if !defined (HAVE_RENAME)
 static int rename ();
@@ -831,6 +839,8 @@ builtin_handler (self, defs, arg)
     new->flags |= BUILTIN_FLAG_LOCALVAR;
   if (is_posix_builtin (name))
     new->flags |= BUILTIN_FLAG_POSIX_BUILTIN;
+  if (is_initially_disabled (name))
+    new->flags |= BUILTIN_FLAG_INITIALLY_DISABLED;
 
   array_add ((char *)new, defs->builtins);
   building_builtin = 1;
@@ -1250,8 +1260,9 @@ write_builtins (defs, structfile, externfile)
 		  else
 		    fprintf (structfile, "(sh_builtin_func_t *)0x0, ");
 
-		  fprintf (structfile, "%s%s%s%s%s, %s_doc,\n",
-		    "BUILTIN_ENABLED | STATIC_BUILTIN",
+		  fprintf (structfile, "%s%s%s%s%s%s, %s_doc,\n",
+		    "STATIC_BUILTIN",
+		    (builtin->flags & BUILTIN_FLAG_INITIALLY_DISABLED) ? "" : " | BUILTIN_ENABLED",
 		    (builtin->flags & BUILTIN_FLAG_SPECIAL) ? " | SPECIAL_BUILTIN" : "",
 		    (builtin->flags & BUILTIN_FLAG_ASSIGNMENT) ? " | ASSIGNMENT_BUILTIN" : "",
 		    (builtin->flags & BUILTIN_FLAG_LOCALVAR) ? " | LOCALVAR_BUILTIN" : "",
@@ -1645,6 +1656,13 @@ is_posix_builtin (name)
   return (_find_in_table (name, posix_builtins));
 }
 
+static int
+is_initially_disabled (name)
+     char *name;
+{
+  return (_find_in_table (name, initially_disabled_builtins));
+}
+
 #if !defined (HAVE_RENAME)
 static int
 rename (from, to)
diff --git a/builtins/sleep.def b/builtins/sleep.def
new file mode 100644
index 0000000..4054e87
--- /dev/null
+++ b/builtins/sleep.def
@@ -0,0 +1,71 @@
+This file is sleep.def, from which is created sleep.c.
+It implements the builtin "sleep" in Bash.
+
+Copyright (C) 1987-2018 Free Software Foundation, Inc.
+
+This file is part of GNU Bash, the Bourne Again SHell.
+
+Bash is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Bash is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Bash.  If not, see <http://www.gnu.org/licenses/>.
+
+$PRODUCES sleep.c
+
+$BUILTIN sleep
+$FUNCTION sleep_builtin
+$SHORT_DOC sleep seconds[.fraction]
+Suspend execution for approximately SECONDS[.FRACTION] seconds.
+
+This builtin is disabled by default.  Enable it with `enable sleep'.
+
+Exit Status:
+Returns success unless aborted.
+$END
+
+#include <config.h>
+
+#if defined (HAVE_UNISTD_H)
+#  ifdef _MINIX
+#    include <sys/types.h>
+#  endif
+#  include <unistd.h>
+#endif
+
+#include "../bashansi.h"
+#include "../bashintl.h"
+#include "../shell.h"
+#include "common.h"
+
+int
+sleep_builtin (list)
+     WORD_LIST *list;
+{
+  long sec, usec;
+
+  if (list && list->word && ISOPTION (list->word->word, '-'))
+    list = list->next;
+
+  if (!list)
+    {
+      builtin_usage ();
+      return (EX_USAGE);
+    }
+
+  if (uconvert (list->word->word, &sec, &usec))
+    {
+      fsleep (sec, usec);
+      return (EXECUTION_SUCCESS);
+    }
+
+  builtin_error ("%s: bad sleep interval", list->word->word);
+  return (EXECUTION_FAILURE);
+}

Reply via email to