about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Doc/Zsh/builtins.yo19
-rw-r--r--Src/Builtins/rlimits.c25
3 files changed, 35 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index 8254e9647..a8628c79b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2010-01-05  Peter Stephenson  <pws@csr.com>
 
+	* 27566: Src/Builtins/rlimits.c: add ulimit -c hard and immediate
+	return on argument error
+
 	* 27565: Src/Builtins/rlimits.c: ulimit didn't sanity check
 	numeric arguments.
 
@@ -12542,5 +12545,5 @@
 
 *****************************************************
 * This is used by the shell to define $ZSH_PATCHLEVEL
-* $Revision: 1.4853 $
+* $Revision: 1.4854 $
 *****************************************************
diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index 5ca4ae612..cc771096a 100644
--- a/Doc/Zsh/builtins.yo
+++ b/Doc/Zsh/builtins.yo
@@ -1710,13 +1710,18 @@ cindex(limits, resource)
 item(tt(ulimit) [ [ tt(-SHacdfilmnpqstvx) | tt(-N) var(resource) [ var(limit) ] ... ])(
 Set or display resource limits of the shell and the processes started by
 the shell.  The value of var(limit) can be a number in the unit specified
-below or the value `tt(unlimited)'.  By default, only soft limits are
-manipulated. If the tt(-H) flag is given use
-hard limits instead of soft limits.  If the tt(-S) flag is given
-together with the tt(-H) flag set both hard and soft limits.  If no
-options are used, the file size limit (tt(-f)) is assumed.  If
-var(limit) is omitted the current value of the specified resources are
-printed.  When more than one resource values are printed the limit name and
+below or one of the values `tt(unlimited)', which removes the limit on the
+resource, or `tt(hard)', which uses the current value of the hard limit on
+the resource.
+
+By default, only soft limits are manipulated. If the tt(-H) flag
+is given use hard limits instead of soft limits.  If the tt(-S) flag is given
+together with the tt(-H) flag set both hard and soft limits.
+
+If no options are used, the file size limit (tt(-f)) is assumed.
+
+If var(limit) is omitted the current value of the specified resources are
+printed.  When more than one resource value is printed, the limit name and
 unit is printed before each value.
 
 When looping over multiple resources, the shell will abort immediately if
diff --git a/Src/Builtins/rlimits.c b/Src/Builtins/rlimits.c
index 8843fb1db..7ee0de012 100644
--- a/Src/Builtins/rlimits.c
+++ b/Src/Builtins/rlimits.c
@@ -836,11 +836,24 @@ bin_ulimit(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
 	    /* set limit to specified value */
 	    rlim_t limit;
 
-	    limit = zstrtorlimt(*argv, &eptr, 10);
-	    if (*eptr) {
-		zwarnnam(name, "invalid number: %s", *argv);
-		ret++;
+	    if (!strcmp(*argv, "hard")) {
+		struct rlimit vals;
+
+		if (getrlimit(res, &vals) < 0)
+		{
+		    zwarnnam(name, "can't read limit: %e", errno);
+		    return 1;
+		}
+		else
+		{
+		    limit = vals.rlim_max;
+		}
 	    } else {
+		limit = zstrtorlimt(*argv, &eptr, 10);
+		if (*eptr) {
+		    zwarnnam(name, "invalid number: %s", *argv);
+		    return 1;
+		}
 		/* scale appropriately */
 		switch (res) {
 		case RLIMIT_FSIZE:
@@ -870,9 +883,9 @@ bin_ulimit(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
 		    limit *= 1024;
 		    break;
 		}
-		if (do_limit(name, res, limit, hard, soft, 1))
-		    ret++;
 	    }
+	    if (do_limit(name, res, limit, hard, soft, 1))
+		ret++;
 	} else {
 	    if (do_unlimit(name, res, hard, soft, 1, geteuid()))
 		ret++;