From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from euclid.skiles.gatech.edu (euclid.skiles.gatech.edu [130.207.146.50]) by werple.net.au (8.7/8.7.1) with ESMTP id FAA00642 for ; Tue, 9 Jan 1996 05:16:28 +1100 (EST) Received: (from list@localhost) by euclid.skiles.gatech.edu (8.7.3/8.7.3) id MAA24535; Mon, 8 Jan 1996 12:41:01 -0500 (EST) Resent-Date: Mon, 8 Jan 1996 12:41:01 -0500 (EST) From: Zefram Message-Id: <21002.199601081739@stone.dcs.warwick.ac.uk> Subject: -M option for limit To: zsh-workers@math.gatech.edu (Z Shell workers mailing list) Date: Mon, 8 Jan 1996 17:39:40 +0000 (GMT) X-Loop: zefram@dcs.warwick.ac.uk X-Stardate: [-31]6868.67 MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Resent-Message-ID: <"c10cc2.0.H_5.jSLym"@euclid> Resent-From: zsh-workers@math.gatech.edu X-Mailing-List: archive/latest/723 X-Loop: zsh-workers@math.gatech.edu Precedence: list Resent-Sender: zsh-workers-request@math.gatech.edu -----BEGIN PGP SIGNED MESSAGE----- The patch below adds the -M option to limit. To make this a little easier, it also modifies limit so that it accepts the hh:mm:ss form to set the cputime limit. This is the form already used for output, and silently misinterpreted if used to set the limit. I also improved error detection. Finally, it moves the test for attempts to remove hard limits in unlimit, so that "unlimit -h foosize" is not an error if run by a mere mortal, provided the foosize resource is already unlimited. I think the limit syntax would be much more consistent if it were changed from "limit resource value" to "limit resource=value". This would allow arbitrary mixtures of setting and examining resource limits, as is already possible with things like typeset and alias. The limit builtin is rather well-established, though, so if it's going to be changed it really can't be delayed. Any opinions? -zefram *** 1.7 1996/01/08 12:43:57 --- Src/builtin.c 1996/01/08 17:03:56 *************** *** 3538,3544 **** } /* without arguments, display limits */ if (!*argv) { ! showlimits(hard, -1); return 0; } while ((s = *argv++)) { --- 3538,3544 ---- } /* without arguments, display limits */ if (!*argv) { ! showlimits(hard, ops['M'], -1); return 0; } while ((s = *argv++)) { *************** *** 3562,3584 **** } /* without value for limit, display the current limit */ if (!(s = *argv++)) { ! showlimits(hard, lim); return 0; } if (lim==RLIMIT_CPU) { ! /* time-type resource -- may be specified as seconds, or minutes or * ! * hours with the `m' and `h' modifiers, and `:' may be used to add * ! * together more than one of these. It's easier to understand from * ! * the code: */ val = zstrtol(s, &s, 10); if (*s) if ((*s == 'h' || *s == 'H') && !s[1]) val *= 3600L; else if ((*s == 'm' || *s == 'M') && !s[1]) val *= 60L; ! else if (*s == ':') val = val * 60 + zstrtol(s + 1, &s, 10); ! else { zwarnnam("limit", "unknown scaling factor: %s", s, 0); return 1; } --- 3562,3589 ---- } /* without value for limit, display the current limit */ if (!(s = *argv++)) { ! showlimits(hard, ops['M'], lim); return 0; } if (lim==RLIMIT_CPU) { ! /* time-type resource -- may be specified as seconds, or minutes * ! * or hours with the `m' and `h' modifiers, and `:' may be used * ! * to add together more than one of these. It's easier to * ! * understand from the code: */ val = zstrtol(s, &s, 10); if (*s) if ((*s == 'h' || *s == 'H') && !s[1]) val *= 3600L; else if ((*s == 'm' || *s == 'M') && !s[1]) val *= 60L; ! else if (*s == ':') { val = val * 60 + zstrtol(s + 1, &s, 10); ! if(*s == ':') ! val = val * 60 + zstrtol(s + 1, &s, 10); ! if(*s) ! goto badscaling; ! } else { ! badscaling: zwarnnam("limit", "unknown scaling factor: %s", s, 0); return 1; } *************** *** 3642,3659 **** zwarnnam(nam, "not available on this system", NULL, 0); return 1; #else ! int hard, limnum, lim; - hard = ops['h']; - /* can only remove hard limits if running as root */ - if (hard && geteuid()) { - zwarnnam(nam, "can't remove hard limits", NULL, 0); - return 1; - } /* Without arguments, remove all limits. */ if (!*argv) { for (limnum = 0; limnum != RLIM_NLIMITS; limnum++) { ! if (hard) limits[limnum].rlim_max = RLIM_INFINITY; else limits[limnum].rlim_cur = limits[limnum].rlim_max; --- 3647,3661 ---- zwarnnam(nam, "not available on this system", NULL, 0); return 1; #else ! int hard=ops['h'], limnum, lim; /* Without arguments, remove all limits. */ if (!*argv) { for (limnum = 0; limnum != RLIM_NLIMITS; limnum++) { ! if (hard && geteuid() && limits[limnum].rlim_max != RLIM_INFINITY) { ! zwarnnam(nam, "can't remove hard limits", NULL, 0); ! return 1; ! } else if (hard) limits[limnum].rlim_max = RLIM_INFINITY; else limits[limnum].rlim_cur = limits[limnum].rlim_max; *************** *** 3680,3686 **** return 1; } /* remove specified limit */ ! if (hard) limits[lim].rlim_max = RLIM_INFINITY; else limits[lim].rlim_cur = limits[lim].rlim_max; --- 3682,3691 ---- return 1; } /* remove specified limit */ ! if (hard && geteuid() && limits[lim].rlim_max != RLIM_INFINITY) { ! zwarnnam(nam, "can't remove hard limits", NULL, 0); ! return 1; ! } else if (hard) limits[lim].rlim_max = RLIM_INFINITY; else limits[lim].rlim_cur = limits[lim].rlim_max; *************** *** 3820,3836 **** #ifdef HAVE_GETRLIMIT /**/ void ! showlimits(int hard, int lim) { int rt; ! RLIM_T val; /* main loop over resource types */ for (rt = 0; rt != RLIM_NLIMITS; rt++) if (rt == lim || lim == -1) { /* display limit for resource number rt */ printf("%-16s", recs[rt]); - val = (hard) ? limits[rt].rlim_max : limits[rt].rlim_cur; if (val == RLIM_INFINITY) printf("unlimited\n"); else if (rt==RLIMIT_CPU) --- 3825,3848 ---- #ifdef HAVE_GETRLIMIT /**/ void ! showlimits(int hard, int list, int lim) { int rt; ! char *H = hard ? " -h" : ""; ! char *B = list ? "" : "B"; /* main loop over resource types */ for (rt = 0; rt != RLIM_NLIMITS; rt++) if (rt == lim || lim == -1) { /* display limit for resource number rt */ + RLIM_T val = (hard) ? limits[rt].rlim_max : limits[rt].rlim_cur; + if(list && val == RLIM_INFINITY) { + printf("unlimit%s %s\n", H, recs[rt]); + continue; + } + if(list) + printf("limit %s ", H); printf("%-16s", recs[rt]); if (val == RLIM_INFINITY) printf("unlimited\n"); else if (rt==RLIMIT_CPU) *************** *** 3851,3863 **** else if (val >= 1024L * 1024L) /* memory resource -- display with `K' or `M' modifier */ # ifdef RLIM_T_IS_QUAD_T ! printf("%qdMB\n", val / (1024L * 1024L)); else ! printf("%qdkB\n", val / 1024L); # else ! printf("%ldMB\n", val / (1024L * 1024L)); else ! printf("%ldkB\n", val / 1024L); # endif /* RLIM_T_IS_QUAD_T */ } } --- 3863,3875 ---- else if (val >= 1024L * 1024L) /* memory resource -- display with `K' or `M' modifier */ # ifdef RLIM_T_IS_QUAD_T ! printf("%qdM%s\n", val / (1024L * 1024L), B); else ! printf("%qdk%s\n", val / 1024L, B); # else ! printf("%ldM%s\n", val / (1024L * 1024L), B); else ! printf("%ldk%s\n", val / 1024L, B); # endif /* RLIM_T_IS_QUAD_T */ } } *** 1.5 1996/01/08 12:43:57 --- Src/hashtable.h 1996/01/08 16:37:20 *************** *** 278,284 **** {NULL, "jobs", 0, bin_fg, 0, -1, BIN_JOBS, "lpZrs", NULL}, {NULL, "kill", 0, bin_kill, 0, -1, 0, NULL, NULL}, {NULL, "let", 0, bin_let, 1, -1, 0, NULL, NULL}, ! {NULL, "limit", 0, bin_limit, 0, -1, 0, "sh", NULL}, {NULL, "local", BINF_TYPEOPTS | BINF_MAGICEQUALS, bin_typeset, 0, -1, 0, "LRZilrtu", NULL}, {NULL, "log", 0, bin_log, 0, 0, 0, NULL, NULL}, {NULL, "logout", 0, bin_break, 0, 1, BIN_LOGOUT, NULL, NULL}, --- 278,284 ---- {NULL, "jobs", 0, bin_fg, 0, -1, BIN_JOBS, "lpZrs", NULL}, {NULL, "kill", 0, bin_kill, 0, -1, 0, NULL, NULL}, {NULL, "let", 0, bin_let, 1, -1, 0, NULL, NULL}, ! {NULL, "limit", 0, bin_limit, 0, -1, 0, "shM", NULL}, {NULL, "local", BINF_TYPEOPTS | BINF_MAGICEQUALS, bin_typeset, 0, -1, 0, "LRZilrtu", NULL}, {NULL, "log", 0, bin_log, 0, 0, 0, NULL, NULL}, {NULL, "logout", 0, bin_break, 0, 1, BIN_LOGOUT, NULL, NULL}, *** 1.5 1996/01/08 12:43:57 --- Doc/zshbuiltins.man 1996/01/08 17:24:47 *************** *** 491,508 **** value of the last expression is nonzero, and 1 otherwise. .TP .PD 0 ! \fBlimit\fP [ \-\fBh\fP ] [ \fIresource\fP [ \fIlimit\fP ] ] ... .TP \fBlimit\fP \-\fBs\fP .PD Limit the resource consumption of the current shell and its children. If \fIlimit\fP is not specified, print the current limit placed ! on \fIresource\fP; otherwise ! set the limit to the specified value. If the \-\fBh\fP flag ! is given, use hard limits instead of soft limits. If no \fIresource\fP is given, print all limits. .RS .PP \fIresource\fP is one of: .PP .PD 0 --- 491,518 ---- value of the last expression is nonzero, and 1 otherwise. .TP .PD 0 ! \fBlimit\fP [ \-\fBhM\fP ] [ \fIresource\fP [ \fIlimit\fP ] ] ... .TP \fBlimit\fP \-\fBs\fP .PD Limit the resource consumption of the current shell and its children. If \fIlimit\fP is not specified, print the current limit placed ! on \fIresource\fP; otherwise set the limit to the specified value. ! Multiple resources with limits may be specified. If no \fIresource\fP is given, print all limits. + When printing limits, the \-\fBM\fP flag causes the limits to be + printed in the form of + .B limit + and + .B unlimit + commands. + If the \-\fBh\fP flag is given, use hard limits instead of soft limits. .RS .PP + If the \-\fBs\fP flag is used, arguments are ignored, and the currently + selected limits are applied to the shell itself. Otherwise, the limits + only apply to child processes. + .PP \fIresource\fP is one of: .PP .PD 0 *************** *** 546,563 **** .PP .PD 0 .TP ! \fIn\fPh hours. .TP ! \fIn\fPk kilobytes. This is the default for all but cputime. .TP ! \fIn\fPm megabytes or minutes. .TP ! \fImm\fP:\fIss\fP minutes and seconds. .PD .RE .TP --- 556,576 ---- .PP .PD 0 .TP ! .IR n h hours. .TP ! .IR n k kilobytes. This is the default for all but cputime. .TP ! .IR n m megabytes or minutes. .TP ! .IR mm : ss minutes and seconds. + .TP + .IR hh : mm : ss + hours, minutes and seconds. .PD .RE .TP -----BEGIN PGP SIGNATURE----- Version: 2.6.i iQCVAgUBMPFWtHD/+HJTpU/hAQHP2gP+NPlKWKS+oqYD/ofZaENQBgbUdiX7m9+R aniAYbAiMefptbWVj+WtUry9KOEAoa8jY+pY/x3T1CExGBuKqIeM1pNcNM3UgzxD 99U7tHkuPOQjfK+x35uDzCa3JRPVEwqEMfPcPJt4zf8mhrjwtBK0wbAd7yfe1bLI X9zDIBv+Nhc= =y6ER -----END PGP SIGNATURE-----