mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Fix 'ps' output for hashbangless scripts on Linux/macOS
When invoking a script without an interpreter (#!hashbang) path, ksh forks, but there is no exec syscall in the child. The existing command line is overwritten in fixargs() with the name of the new script and associated arguments. In the generic/fallback version of fixargs() which is used on Linux and macOS, if the new command line is longer than the existing one, it is truncated. This works well when calling a script with a shorter name. However, it generates a misleading name in the common scenario where a script is invoked from an interactive shell, which typically has a short command line. For instance, if "/tmp/script" is invoked, "ksh" gets replaced with "/tm" in "ps" output. A solution is found in the fact that, on these systems, the environment is stored immediately after the command line arguments. This space can be made available for use by a longer command line by moving the environment strings out of the way. src/cmd/ksh93/sh/main.c: fixargs(): - Refactor BSD setproctitle(3) version to be more self-contained. - In the generic (Linux/macOS) version, on init (i.e. mode==0), if the command line is smaller than 128 bytes and the environment strings have not yet been moved (i.e. if they still immediately follow the command line arguments in memory), then strdup the environment strings, pointing the *environment[] members to the new strings and adding the length of the strings to the maximum command line buffer size. Reported-by: @gkamat Resolves: https://github.com/ksh93/ksh/pull/300
This commit is contained in:
parent
c3f7cf0314
commit
bdc3069bfd
3 changed files with 62 additions and 23 deletions
|
@ -56,6 +56,7 @@ static void exfile(Shell_t*, Sfio_t*,int);
|
|||
static void chkmail(Shell_t *shp, char*);
|
||||
#if !defined(_NEXT_SOURCE) && !defined(__sun)
|
||||
static void fixargs(char**,int);
|
||||
# undef fixargs_disabled
|
||||
#else
|
||||
# define fixargs(a,b)
|
||||
# define fixargs_disabled 1
|
||||
|
@ -715,12 +716,13 @@ static void chkmail(Shell_t *shp, char *files)
|
|||
*/
|
||||
static void fixargs(char **argv, int mode)
|
||||
{
|
||||
#if EXECARGS
|
||||
# if EXECARGS
|
||||
if(mode==0)
|
||||
return;
|
||||
*execargs=(char *)argv;
|
||||
#else
|
||||
register char *cp;
|
||||
# elif PSTAT
|
||||
char *cp;
|
||||
int offset=0,size;
|
||||
# ifdef PSTAT
|
||||
static int command_len;
|
||||
char *buff;
|
||||
union pstun un;
|
||||
|
@ -735,21 +737,6 @@ static void fixargs(char **argv, int mode)
|
|||
}
|
||||
stakseek(command_len+2);
|
||||
buff = stakseek(0);
|
||||
# elif _lib_setproctitle
|
||||
# define command_len 255
|
||||
char buff[command_len + 1];
|
||||
if(mode==0)
|
||||
return;
|
||||
# else
|
||||
static int command_len;
|
||||
static char *buff;
|
||||
if(mode==0)
|
||||
{
|
||||
buff = argv[0];
|
||||
command_len = environ[0] - buff - 1;
|
||||
return;
|
||||
}
|
||||
# endif /* PSTAT */
|
||||
if(command_len==0)
|
||||
return;
|
||||
while((cp = *argv++) && offset < command_len)
|
||||
|
@ -762,12 +749,59 @@ static void fixargs(char **argv, int mode)
|
|||
}
|
||||
offset--;
|
||||
memset(&buff[offset], 0, command_len - offset + 1);
|
||||
# ifdef PSTAT
|
||||
un.pst_command = stakptr(0);
|
||||
pstat(PSTAT_SETCMD,un,0,0,0);
|
||||
# elif _lib_setproctitle
|
||||
# define CMDMAXLEN 255
|
||||
char *cp;
|
||||
int offset=0,size;
|
||||
char buff[CMDMAXLEN + 1];
|
||||
if(mode==0)
|
||||
return;
|
||||
while((cp = *argv++) && offset < CMDMAXLEN)
|
||||
{
|
||||
if(offset + (size=strlen(cp)) >= CMDMAXLEN)
|
||||
size = CMDMAXLEN - offset;
|
||||
memcpy(buff+offset,cp,size);
|
||||
offset += size;
|
||||
buff[offset++] = ' ';
|
||||
}
|
||||
buff[--offset] = '\0';
|
||||
setproctitle("%s",buff);
|
||||
# endif /* PSTAT */
|
||||
#endif /* EXECARGS */
|
||||
# undef CMDMAXLEN
|
||||
# else
|
||||
/* Generic version, works on at least Linux and macOS */
|
||||
char *cp;
|
||||
int offset=0,size;
|
||||
static int buffsize;
|
||||
static char *buff;
|
||||
if(mode==0)
|
||||
{
|
||||
int i;
|
||||
buff = argv[0];
|
||||
for(i=0; argv[i]; i++)
|
||||
buffsize += strlen(argv[i]) + 1;
|
||||
if(buffsize < 128 && buff + buffsize == *environ)
|
||||
{
|
||||
/* Move the environment to make space for a larger command line buffer */
|
||||
for(i=0; environ[i]; i++)
|
||||
{
|
||||
buffsize += strlen(environ[i]) + 1;;
|
||||
environ[i] = sh_strdup(environ[i]);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
while((cp = *argv++) && offset < buffsize)
|
||||
{
|
||||
if(offset + (size=strlen(cp)) >= buffsize)
|
||||
size = buffsize - offset;
|
||||
memcpy(buff+offset,cp,size);
|
||||
offset += size;
|
||||
buff[offset++] = ' ';
|
||||
}
|
||||
offset--;
|
||||
memset(&buff[offset], 0, buffsize - offset + 1);
|
||||
# endif
|
||||
}
|
||||
#endif /* !fixargs_disabled */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue