1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-02-15 04:32:24 +00:00

Use dynamic maximum configuration values when necessary (#370)

This commit fixes an issue with how ksh was obtaining the value of
NGROUPS_MAX. On some systems this setting can be changed (e.g., on
illumos adding 'set ngroups_max=32' to /etc/system then rebooting
changes NGROUPS_MAX from 16 to 32). Ksh was using NGROUPS_MAX with
the assumption it's a static value, which could cause issues on
systems where it isn't static. This bugfix is inspired by the one
from <https://github.com/lkujaw/ast/commit/b1362c3a5>, although it
has been expanded a bit to account for OPEN_MAX as well.

src/cmd/ksh93/sh/init.c, src/lib/libcmd/fds.c:
- Rename the getconf() macro to astconf_long() and move it to ast.h
  to prevent redundancy. Other sections of the code have been
  modified to use this macro for astconf() to account for
  dynamic settings.
- An equivalent macro for unsigned long values (astconf_ulong) has
  been added.
- Prefer sysconf(3) where available. It has better performance as it
  returns a numeric value directly instead of via string
  conversion.
- The astconf_long and astconf_ulong macros have been documented in
  the ast(3) man page.
This commit is contained in:
Johnothan King 2021-12-12 22:51:59 -08:00 committed by Martijn Dekker
parent fc752b574a
commit c2ac69b2d5
15 changed files with 81 additions and 27 deletions

View file

@ -666,7 +666,7 @@ skip:
if((maxgroups=getgroups(0,(gid_t*)0)) <= 0) if((maxgroups=getgroups(0,(gid_t*)0)) <= 0)
{ {
/* pre-POSIX system */ /* pre-POSIX system */
maxgroups=NGROUPS_MAX; maxgroups = (int)astconf_long(CONF_NGROUPS_MAX);
} }
} }
groups = (gid_t*)stakalloc((maxgroups+1)*sizeof(gid_t)); groups = (gid_t*)stakalloc((maxgroups+1)*sizeof(gid_t));

View file

@ -46,7 +46,7 @@ tst note{ determining extra bytes per argument for arguments list }end output{
for(i=0; environ[i]; i++) for(i=0; environ[i]; i++)
envlen += strlen(environ[i]) + 1 + extra_bytes; envlen += strlen(environ[i]) + 1 + extra_bytes;
envlen += 1 + extra_bytes; /* final null element */ envlen += 1 + extra_bytes; /* final null element */
argmax = strtoimax(astconf("ARG_MAX",NiL,NiL),NiL,0) - envlen; argmax = (int)astconf_long(CONF_ARG_MAX) - envlen;
if (argmax < 2048) if (argmax < 2048)
{ {
error(ERROR_ERROR|2, "argmax too small"); error(ERROR_ERROR|2, "argmax too small");

View file

@ -144,9 +144,6 @@ char e_version[] = "\n@(#)$Id: Version "
extern char **environ; extern char **environ;
#endif #endif
#undef getconf
#define getconf(x) strtol(astconf(x,NiL,NiL),NiL,0)
struct seconds struct seconds
{ {
Namfun_t hdr; Namfun_t hdr;
@ -1223,9 +1220,9 @@ Shell_t *sh_init(register int argc,register char *argv[], Shinit_f userinit)
shgd->euserid=geteuid(); shgd->euserid=geteuid();
shgd->groupid=getgid(); shgd->groupid=getgid();
shgd->egroupid=getegid(); shgd->egroupid=getegid();
shgd->lim.clk_tck = getconf("CLK_TCK"); shgd->lim.arg_max = astconf_long(CONF_ARG_MAX);
shgd->lim.arg_max = getconf("ARG_MAX"); shgd->lim.child_max = (int)astconf_long(CONF_CHILD_MAX);
shgd->lim.child_max = getconf("CHILD_MAX"); shgd->lim.clk_tck = (int)astconf_long(CONF_CLK_TCK);
if(shgd->lim.arg_max <=0) if(shgd->lim.arg_max <=0)
shgd->lim.arg_max = ARG_MAX; shgd->lim.arg_max = ARG_MAX;
if(shgd->lim.child_max <=0) if(shgd->lim.child_max <=0)

View file

@ -403,7 +403,7 @@ int sh_iovalidfd(Shell_t *shp, int fd)
return(0); return(0);
if(fd < shp->gd->lim.open_max) if(fd < shp->gd->lim.open_max)
return(1); return(1);
max = strtol(astconf("OPEN_MAX",NiL,NiL),NiL,0); max = (int)astconf_long(CONF_OPEN_MAX);
if(fd >= max) if(fd >= max)
{ {
errno = EBADF; errno = EBADF;

View file

@ -329,7 +329,7 @@ int eaccess(register const char *name, register int mode)
if((maxgroups=getgroups(0,groups)) < 0) if((maxgroups=getgroups(0,groups)) < 0)
{ {
/* pre-POSIX system */ /* pre-POSIX system */
maxgroups=NGROUPS_MAX; maxgroups = (int)astconf_long(CONF_NGROUPS_MAX);
} }
} }
groups = (gid_t*)malloc((maxgroups+1)*sizeof(gid_t)); groups = (gid_t*)malloc((maxgroups+1)*sizeof(gid_t));

View file

@ -110,7 +110,7 @@ eaccess(const char* path, register int flags)
if (ngroups == -2) if (ngroups == -2)
{ {
if ((ngroups = getgroups(0, (gid_t*)0)) <= 0) if ((ngroups = getgroups(0, (gid_t*)0)) <= 0)
ngroups = NGROUPS_MAX; ngroups = (int)astconf_long(CONF_NGROUPS_MAX);
if (!(groups = newof(0, gid_t, ngroups + 1, 0))) if (!(groups = newof(0, gid_t, ngroups + 1, 0)))
ngroups = -1; ngroups = -1;
else else

View file

@ -283,6 +283,27 @@ extern off_t astcopy(int, int, off_t);
extern int astlicense(char*, int, char*, char*, int, int, int); extern int astlicense(char*, int, char*, char*, int, int, int);
extern int astquery(int, const char*, ...); extern int astquery(int, const char*, ...);
extern void astwinsize(int, int*, int*); extern void astwinsize(int, int*, int*);
#if _lib_sysconf
/* prefer sysconf for astconf_long and astconf_ulong to improve performance */
#define CONF_ARG_MAX _SC_ARG_MAX
#define CONF_CHILD_MAX _SC_CHILD_MAX
#define CONF_CLK_TCK _SC_CLK_TCK
#define CONF_NGROUPS_MAX _SC_NGROUPS_MAX
#define CONF_OPEN_MAX _SC_OPEN_MAX
#define CONF_PAGESIZE _SC_PAGESIZE
#define astconf_long(x) sysconf(x)
#define astconf_ulong(x) (unsigned long)sysconf(x)
#else
/* fallback in case sysconf isn't available */
#define CONF_ARG_MAX "ARG_MAX"
#define CONF_CHILD_MAX "CHILD_MAX"
#define CONF_CLK_TCK "CLK_TCK"
#define CONF_NGROUPS_MAX "NGROUPS_MAX"
#define CONF_OPEN_MAX "OPEN_MAX"
#define CONF_PAGESIZE "PAGESIZE"
#define astconf_long(x) strtol(astconf(x,NiL,NiL),NiL,0)
#define astconf_ulong(x) strtoul(astconf(x,NiL,NiL),NiL,0)
#endif
extern ssize_t base64encode(const void*, size_t, void**, void*, size_t, void**); extern ssize_t base64encode(const void*, size_t, void**, void*, size_t, void**);
extern ssize_t base64decode(const void*, size_t, void**, void*, size_t, void**); extern ssize_t base64decode(const void*, size_t, void**, void*, size_t, void**);

View file

@ -44,6 +44,8 @@ ast \- miscellaneous libast support
#include <ast.h> #include <ast.h>
char* astconf(const char* \fIname\fP, const char* \fIpath\fP, const char* \fIvalue\fP); char* astconf(const char* \fIname\fP, const char* \fIpath\fP, const char* \fIvalue\fP);
long astconf_long(\fIarg\fP);
unsigned long astconf_ulong(\fIarg\fP);
Ast_confdisc_t astconfdisc(Ast_confdisc_t new_notify); Ast_confdisc_t astconfdisc(Ast_confdisc_t new_notify);
void astconflist(Sfio_t* stream, const char* path, int flags); void astconflist(Sfio_t* stream, const char* path, int flags);
off_t astcopy(int \fIrfd\fP, int \fIwfd\fP, off_t \fIn\fP); off_t astcopy(int \fIrfd\fP, int \fIwfd\fP, off_t \fIn\fP);
@ -155,6 +157,30 @@ User defined
values may also be set and queried, but these should probably have values may also be set and queried, but these should probably have
some form of vendor prefix to avoid being stomped by future standards. some form of vendor prefix to avoid being stomped by future standards.
.PP .PP
.L astconf_long
and
.L astconf_ulong
are macros that call either
.I sysconf
or
.LR astconf ,
preferring
.I sysconf
if it's available.
.L astconf_long
returns a signed long value while
.L astconf_ulong
returns an unsigned long value.
The argument passed to these macros may be one of the following:
.EX
CONF_ARG_MAX
CONF_CHILD_MAX
CONF_CLK_TCK
CONF_NGROUPS_MAX
CONF_OPEN_MAX
CONF_PAGESIZE
.EE
.PP
.L astconfdisc .L astconfdisc
registers a discipline function registers a discipline function
.EX .EX
@ -259,7 +285,7 @@ and
are set to are set to
.LR 0 . .LR 0 .
If If
.I ioctl (2) .IR ioctl (2)
methods fail then the environment variable methods fail then the environment variable
.L LINES .L LINES
is used to set is used to set

View file

@ -128,7 +128,7 @@ cmdopen_20120411(char** argv, int argmax, int size, const char* argpat, Cmddisc_
argc = 0; argc = 0;
for (p = environ; *p; p++) for (p = environ; *p; p++)
n += sizeof(char**) + strlen(*p) + 1; n += sizeof(char**) + strlen(*p) + 1;
if ((x = strtol(astconf("ARG_MAX", NiL, NiL), NiL, 0)) <= 0) if ((x = astconf_long(CONF_ARG_MAX)) <= 0)
x = ARG_MAX; x = ARG_MAX;
if (size <= 0 || size > x) if (size <= 0 || size > x)
size = x; size = x;

View file

@ -90,7 +90,7 @@ static inline int xaccess(const char *path, int mode)
int ret; int ret;
if (!pgsz) if (!pgsz)
pgsz = strtoul(astconf("PAGESIZE",NiL,NiL),NiL,0); pgsz = astconf_ulong(CONF_PAGESIZE);
if (!path || !*path) if (!path || !*path)
{ {

View file

@ -92,7 +92,7 @@ vfwscanf(Sfio_t* f, const wchar_t* fmt, va_list args)
n = wcstombs(NiL, fmt, 0); n = wcstombs(NiL, fmt, 0);
if (w = newof(0, Wide_t, 1, n)) if (w = newof(0, Wide_t, 1, n))
{ {
if (t = sfnew(NiL, buf, sizeof(buf), OPEN_MAX+1, SF_READ)) if (t = sfnew(NiL, buf, sizeof(buf), (int)astconf_long(CONF_OPEN_MAX)+1, SF_READ))
{ {
w->sfdisc.exceptf = wideexcept; w->sfdisc.exceptf = wideexcept;
w->sfdisc.readf = wideread; w->sfdisc.readf = wideread;

View file

@ -36,16 +36,16 @@ fmtclock(register Sfulong_t t)
char* buf; char* buf;
int z; int z;
static unsigned int clk_tck; static unsigned long clk_tck;
if (!clk_tck) if (!clk_tck)
{ {
#ifdef CLOCKS_PER_SEC #ifdef CLOCKS_PER_SEC
clk_tck = CLOCKS_PER_SEC; clk_tck = CLOCKS_PER_SEC;
#else #else
if (!(clk_tck = (unsigned int)strtoul(astconf("CLK_TCK", NiL, NiL), NiL, 10))) if (!(clk_tck = astconf_ulong(CONF_CLK_TCK)))
clk_tck = 60; clk_tck = 60;
#endif #endif /* CLOCKS_PER_SEC */
} }
if (t == 0) if (t == 0)
return "0"; return "0";

View file

@ -1124,8 +1124,6 @@ char* ends;
return begs; return begs;
} }
#define FD_PRIVATE (3*OPEN_MAX/4)
#if __STD_C #if __STD_C
int _vmfd(int fd) int _vmfd(int fd)
#else #else
@ -1134,10 +1132,19 @@ int fd;
#endif #endif
{ {
int pd; int pd;
int fd_private = (int)(3 * astconf_long(CONF_OPEN_MAX) / 4);
if (fd_private <= 0)
{
#if defined(OPEN_MAX)
fd_private = 3 * OPEN_MAX / 4;
#else
fd_private = 3 * FOPEN_MAX / 4;
#endif
}
if (fd >= 0) if (fd >= 0)
{ {
if (fd < FD_PRIVATE && (pd = fcntl(fd, F_DUPFD, FD_PRIVATE)) >= 0) if (fd < fd_private && (pd = fcntl(fd, F_DUPFD, fd_private)) >= 0)
{ {
close(fd); close(fd);
fd = pd; fd = pd;

View file

@ -54,9 +54,6 @@ static const char usage[] =
#define major(x) (int)(((unsigned int)(x)>>8)&0xff) #define major(x) (int)(((unsigned int)(x)>>8)&0xff)
#endif #endif
#undef getconf
#define getconf(x) strtol(astconf(x,NiL,NiL),NiL,0)
#ifdef S_IFSOCK #ifdef S_IFSOCK
typedef struct NV_s typedef struct NV_s
@ -214,8 +211,14 @@ b_fds(int argc, char** argv, Shbltin_t* context)
error(ERROR_usage(2), "%s", optusage(NiL)); error(ERROR_usage(2), "%s", optusage(NiL));
UNREACHABLE(); UNREACHABLE();
} }
if ((open_max = getconf("OPEN_MAX")) <= 0) if ((open_max = (int)astconf_long(CONF_OPEN_MAX)) <= 0)
{
#if defined(OPEN_MAX)
open_max = OPEN_MAX; open_max = OPEN_MAX;
#else
open_max = FOPEN_MAX;
#endif
}
if (unit == 1) if (unit == 1)
sp = sfstdout; sp = sfstdout;
else if (fstat(unit, &st) || !(sp = sfnew(NiL, NiL, SF_UNBOUND, unit, SF_WRITE))) else if (fstat(unit, &st) || !(sp = sfnew(NiL, NiL, SF_UNBOUND, unit, SF_WRITE)))

View file

@ -231,7 +231,7 @@ getids(Sfio_t* sp, const char* name, register int flags)
*/ */
if ((maxgroups = getgroups(0, groups)) <= 0) if ((maxgroups = getgroups(0, groups)) <= 0)
maxgroups = NGROUPS_MAX; maxgroups = (int)astconf_long(CONF_NGROUPS_MAX);
if (!(groups = newof(0, gid_t, maxgroups + 1, 0))) if (!(groups = newof(0, gid_t, maxgroups + 1, 0)))
{ {
error(ERROR_SYSTEM|ERROR_PANIC, "out of memory [group array]"); error(ERROR_SYSTEM|ERROR_PANIC, "out of memory [group array]");