NetBSD Problem Report #31377
From sjg@juniper.net Fri Sep 23 16:40:26 2005
Return-Path: <sjg@juniper.net>
Received: from colo-dns-ext1.juniper.net (colo-dns-ext1.juniper.net [207.17.137.57])
by narn.netbsd.org (Postfix) with ESMTP id 6F80E63B852
for <gnats-bugs@gnats.NetBSD.org>; Fri, 23 Sep 2005 16:40:26 +0000 (UTC)
Message-Id: <20050923164020.6841BEF10@ran.juniper.net>
Date: Fri, 23 Sep 2005 09:40:20 -0700 (PDT)
From: sjg@juniper.net
Reply-To: sjg@juniper.net
To: gnats-bugs@netbsd.org
Subject: ksh: cannot set limit indicated by ulimit -H
X-Send-Pr-Version: 3.95
>Number: 31377
>Category: bin
>Synopsis: ksh: cannot set limit indicated by ulimit -H
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Sep 23 16:41:00 +0000 2005
>Last-Modified: Mon Oct 09 22:40:01 +0000 2006
>Originator: sjg@juniper.net
>Release: NetBSD 3.99.9
>Organization:
>Environment:
NetBSD frodo 3.99.9 NetBSD 3.99.9 (GENERIC) #1: Mon Sep 19 10:38:07 PDT 2005 sjg@swift.juniper.net:/c/sjg/work/NetBSD/current/obj/i386/obj/c/sjg/work/NetBSD/current/src/sys/arch/i386/compile/GENERIC i386
Architecture: i386
Machine: i386
>Description:
My .profile uses a function to maximize certain limits, this function
works on all previous NetBSD as well as many other systems. The idea
is to set a limit to the value reported by ulimit -H as in:
max_limit() {
# Linux uses bash as /bin/sh and unlike
# every other sh like shell it does not
# handle -<x>H but does handle -H<x>
# -H -<x> works on some but not all bash versions <grrr/>
for _ul in `IFS=" -"; echo $*`
do
_ulmax=`ulimit -H$_ul`
ulimit -$_ul $_ulmax
done
}
On 3.99.9 calling
max_limit -d
fails because:
: sjg:131; umlimit -Hd
2097152
: sjg:132; ulimit -d 2097152
ksh: ulimit: bad limit: Invalid argument
: sjg:133; ulimit -d 2097151
: sjg:134;
>How-To-Repeat:
: sjg:131; umlimit -Hd
2097152
: sjg:132; ulimit -d 2097152
ksh: ulimit: bad limit: Invalid argument
: sjg:133; ulimit -d 2097151
: sjg:134;
>Fix:
>Audit-Trail:
From: Simon Gerraty <sjg@juniper.net>
To: tech-userland@netbsd.org
Cc: gnats-bugs@netbsd.org, sjg@juniper.net
Subject: Re: bin/31377: ksh: cannot set limit indicated by ulimit -H
Date: Sat, 24 Sep 2005 20:24:57 -0700 (PDT)
Ok, the problem here is that the limit for -d happens to be
2147483648, but because ksh munges that to/from kbyte units (factor of
1024) and is using a signed value (rlim_t), when we try to set that
limit (after multiplying by 1024 again) we get -2147483648 which is why
it fails.
I'm not sure why rlim_t is signed, but the simple patch below avoids the
above:
Index: c_ulimit.c
===================================================================
RCS file: /cvsroot/src/bin/ksh/c_ulimit.c,v
retrieving revision 1.7
diff -u -p -r1.7 c_ulimit.c
--- c_ulimit.c 7 Jul 2004 19:20:09 -0000 1.7
+++ c_ulimit.c 25 Sep 2005 03:13:29 -0000
@@ -194,6 +194,8 @@ c_ulimit(wp)
return 1;
}
val = rval * l->factor;
+ if (val < 0)
+ val = -val;
}
}
if (all) {
FWIW, the problem didn't show up in earlier NetBSD releases because the
limit was lower (1/2 the limit in 3.99)
--sjg
From: Frederick Bruckman <fredb@immanent.net>
To: Simon Gerraty <sjg@juniper.net>
Cc: gnats-bugs@netbsd.org
Subject: Re: bin/31377: ksh: cannot set limit indicated by ulimit -H
Date: Sun, 8 Oct 2006 19:05:06 -0500 (CDT)
Hi,
The problem seems to be that rlim_t is a "quad_t" (i.e., 64-bits),
while pdksh's evaluate() only works for "long" (which is, of course,
only 32-bits on i386). I suggest that the right fix is to "promote"
evaluate() to 64-bits, adjusting all of its callers, as below...
Frederick
Index: ./bin/ksh/c_ksh.c
===================================================================
RCS file: /cvsroot/src/bin/ksh/c_ksh.c,v
retrieving revision 1.15
diff -u -r1.15 c_ksh.c
--- ./bin/ksh/c_ksh.c 24 Apr 2006 20:00:31 -0000 1.15
+++ ./bin/ksh/c_ksh.c 17 Sep 2006 19:39:01 -0000
@@ -1083,7 +1083,7 @@
char **wp;
{
int rv = 1;
- long val;
+ int64_t val;
if (wp[1] == (char *) 0) /* at&t ksh does this */
bi_errorf("no arguments");
Index: ./bin/ksh/c_sh.c
===================================================================
RCS file: /cvsroot/src/bin/ksh/c_sh.c,v
retrieving revision 1.12
diff -u -r1.12 c_sh.c
--- ./bin/ksh/c_sh.c 1 Apr 2006 23:39:58 -0000 1.12
+++ ./bin/ksh/c_sh.c 17 Sep 2006 19:39:01 -0000
@@ -32,7 +32,7 @@
{
register struct block *l = e->loc;
register int n;
- long val;
+ int64_t val;
char *arg;
if (ksh_getopt(wp, &builtin_opt, null) == '?')
Index: ./bin/ksh/c_test.c
===================================================================
RCS file: /cvsroot/src/bin/ksh/c_test.c,v
retrieving revision 1.6
diff -u -r1.6 c_test.c
--- ./bin/ksh/c_test.c 26 Jun 2005 19:09:00 -0000 1.6
+++ ./bin/ksh/c_test.c 17 Sep 2006 19:39:01 -0000
@@ -369,7 +369,7 @@
case TO_INTLE: /* -le */
case TO_INTLT: /* -lt */
{
- long v1, v2;
+ int64_t v1, v2;
if (!evaluate(opnd1, &v1, KSH_RETURN_ERROR)
|| !evaluate(opnd2, &v2, KSH_RETURN_ERROR))
Index: ./bin/ksh/c_ulimit.c
===================================================================
RCS file: /cvsroot/src/bin/ksh/c_ulimit.c,v
retrieving revision 1.7
diff -u -r1.7 c_ulimit.c
--- ./bin/ksh/c_ulimit.c 7 Jul 2004 19:20:09 -0000 1.7
+++ ./bin/ksh/c_ulimit.c 17 Sep 2006 19:39:01 -0000
@@ -178,7 +178,7 @@
if (strcmp(wp[0], "unlimited") == 0)
val = KSH_RLIM_INFINITY;
else {
- long rval;
+ rlim_t rval;
if (!evaluate(wp[0], &rval, KSH_RETURN_ERROR))
return 1;
Index: ./bin/ksh/expr.c
===================================================================
RCS file: /cvsroot/src/bin/ksh/expr.c,v
retrieving revision 1.8
diff -u -r1.8 expr.c
--- ./bin/ksh/expr.c 26 Jun 2005 19:09:00 -0000 1.8
+++ ./bin/ksh/expr.c 17 Sep 2006 19:39:01 -0000
@@ -151,7 +151,7 @@
int
evaluate(expr, rval, error_ok)
const char *expr;
- long *rval;
+ int64_t *rval;
int error_ok;
{
struct tbl v;
Index: ./bin/ksh/proto.h
===================================================================
RCS file: /cvsroot/src/bin/ksh/proto.h,v
retrieving revision 1.7
diff -u -r1.7 proto.h
--- ./bin/ksh/proto.h 26 Jun 2005 19:09:00 -0000 1.7
+++ ./bin/ksh/proto.h 17 Sep 2006 19:39:01 -0000
@@ -78,7 +78,7 @@
int pr_menu ARGS((char *const *));
int pr_list ARGS((char *const *));
/* expr.c */
-int evaluate ARGS((const char *, long *, int));
+int evaluate ARGS((const char *, int64_t *, int));
int v_evaluate ARGS((struct tbl *, const char *, volatile int));
/* history.c */
void init_histvec ARGS((void));
Index: ./bin/ksh/var.c
===================================================================
RCS file: /cvsroot/src/bin/ksh/var.c,v
retrieving revision 1.14
diff -u -r1.14 var.c
--- ./bin/ksh/var.c 29 Mar 2006 15:51:00 -0000 1.14
+++ ./bin/ksh/var.c 17 Sep 2006 19:39:02 -0000
@@ -148,7 +148,7 @@
p = skip_varname(n, FALSE);
if (p != n && *p == '[' && (len = array_ref_len(p))) {
char *sub, *tmp;
- long rval;
+ int64_t rval;
/* Calculate the value of the subscript */
*arrayp = TRUE;
From: Simon Gerraty <sjg@juniper.net>
To: Frederick Bruckman <fredb@immanent.net>
Cc: gnats-bugs@netbsd.org
Subject: Re: bin/31377: ksh: cannot set limit indicated by ulimit -H
Date: Mon, 09 Oct 2006 15:39:03 -0700
Sounds reasonable.
Thanks
--sjg
On Sun, 8 Oct 2006 19:05:06 -0500 (CDT), Frederick Bruckman wri
tes:
>Hi,
>
>The problem seems to be that rlim_t is a "quad_t" (i.e., 64-bi
>ts),
>while pdksh's evaluate() only works for "long" (which is, of c
>ourse,
>only 32-bits on i386). I suggest that the right fix is to "pro
>mote"
>evaluate() to 64-bits, adjusting all of its callers, as below.
>..
>
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.