1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00
cde/src/cmd/ksh93/features/externs
Johnothan King c2ac69b2d5 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 <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.
2021-12-13 07:53:14 +01:00

121 lines
2.9 KiB
Text

set prototyped
hdr nc,exec_attr
mem exception.name,_exception.name math.h
lib setreuid,setregid,nice,fork,spawnveg,fchdir
lib pathnative,pathposix,uwin_path,uwin_unpath,fts_notify
lib memcntl sys/mman.h
lib getexecuser,free_execattr exec_attr.h -lsecdb
reference unistd.h
extern nice int (int)
extern setreuid int (uid_t,uid_t)
extern setregid int (gid_t,gid_t)
tst note{ determining extra bytes per argument for arguments list }end output{
/*
* Figure out if this OS requires extra bytes per argument
* in the arguments list of a process.
* Outputs an appropriate #define ARG_EXTRA_BYTES.
* Without this, 'command -x' failed with E2BIG on macOS, Linux and Solaris
* even if all the arguments should fit in ARG_MAX based on their length.
*/
/* AST includes */
#include <ast.h>
#include <error.h>
#include <sfio.h>
#include <stak.h>
#include <wait.h>
/* Standard includes */
#include <errno.h>
int main(int argc,char *argv[])
{
int extra_bytes = 0, envlen, argmax, i;
pid_t childpid;
error_info.id="ARG_EXTRA_BYTES test (parent)";
while(1)
{
envlen = 0;
for(i=0; argv[i]; i++)
envlen += strlen(argv[i]) + 1 + extra_bytes;
envlen += 1 + extra_bytes; /* final null element */
for(i=0; environ[i]; i++)
envlen += strlen(environ[i]) + 1 + extra_bytes;
envlen += 1 + extra_bytes; /* final null element */
argmax = (int)astconf_long(CONF_ARG_MAX) - envlen;
if (argmax < 2048)
{
error(ERROR_ERROR|2, "argmax too small");
return 1;
}
if(!(childpid = fork()))
{
/* child */
int bytec;
error_info.id="ARG_EXTRA_BYTES test (child)";
argv = (char **)stakalloc((argmax / 2 + 1) * sizeof(char*));
argc = bytec = 0;
while(bytec < argmax)
{
if(argc==0)
argv[argc] = "/usr/bin/env";
else if(argc==1)
argv[argc] = "true";
else
argv[argc] = "x";
/* also add 1 for terminating zero byte */
bytec += strlen(argv[argc]) + 1 + extra_bytes;
argc++;
}
argv[argc] = (char*)0;
if(execve(argv[0], argv, environ) < 0)
{
if(errno == E2BIG)
return 1;
else
{
error(ERROR_SYSTEM|2, "execve failed");
return 2;
}
}
error(ERROR_SYSTEM|2, "[BUG] we should never get here!");
return 2;
}
else
{
/* parent */
int exitstatus;
if (waitpid(childpid,&i,0) < 0)
{
error(ERROR_SYSTEM|2, "waitpid failed");
return 1;
}
if (!WIFEXITED(i) || (exitstatus = WEXITSTATUS(i)) > 1)
{
error(ERROR_ERROR|2, "child process exited abnormally");
return 1;
}
if (exitstatus == 0)
break; /* yay :) */
extra_bytes++;
if (extra_bytes > 256)
{
error(ERROR_ERROR|2, "giving up");
return 1;
}
}
}
sfprintf(sfstdout,
"#define ARG_EXTRA_BYTES\t%d\t/* extra bytes per argument for arguments list */\n",
extra_bytes);
return 0;
}
}end fail{
echo "#define ARG_EXTRA_BYTES 16 /* BUG: test failed; assuming 16 */"
}end