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/sh/shcomp.c
Johnothan King beccb93fd4 Fix various compiler warnings and minor issues (#362)
List of changes:
- Fixed some -Wuninitialized warnings and removed some unused variables.

- Removed the unused extern for B_login (re: d8eba9d1).

- The libcmd builtins and the vmalloc memfatal function now handle
  memory errors with 'ERROR_SYSTEM|ERROR_PANIC' for consistency with how
  ksh itself handles out of memory errors.

- Added usage of UNREACHABLE() where it was missing from error handling.

- Extend many variables from short to int to prevent overflows (most
  variables involve file descriptors).

- Backported a ksh2020 patch to fix unused value Coverity issues
  (https://github.com/att/ast/pull/740).

- Note in src/cmd/ksh93/README that ksh compiles with Cygwin on
  Windows 10 and Windows 11, albeit with many test failures.

- Add comments to detail some sections of code. Extensive list of
  commits related to this change:
  ca2443b5, 7e7f1372, 2db9953a, 7003aba4, 6f50ff64, b1a41311,
  222515bf, a0dcdeea, 0aa9e03f, 61437b27, 352e68da, 88e8fa67,
  bc8b36fa, 6e515f1d, 017d088c, 035a4cb3, 588a1ff7, 6d63b57d,
  a2f13c19, 794d1c86, ab98ec65, 1026006d

- Removed a lot of dead ifdef code.

- edit/emacs.c: Hide an assignment to avoid a -Wunused warning. (See
  also https://github.com/att/ast/pull/753, which removed the assignment
  because ksh2020 removed the !SHOPT_MULTIBYTE code.)

- sh/nvdisc.c: The sh_newof macro cannot return a null pointer because
  it will instead cause the shell to exit if memory cannot be allocated.
  That makes the if statement here a no-op, so remove it.

- sh/xec.c: Fixed one unused variable warning in sh_funscope().

- sh/xec.c: Remove a fallthrough comment added in commit ed478ab7
  because the TFORK code doesn't fall through (GCC also produces no
  -Wimplicit-fallthrough warning here).

- data/builtins.c: The cd and pwd man pages state that these builtins
  default to -P if PATH_RESOLVE is 'physical', which isn't accurate:
     $ /opt/ast/bin/getconf PATH_RESOLVE
     physical
     $ mkdir /tmp/dir; ln -s /tmp/dir /tmp/sym
     $ cd /tmp/sym
     $ pwd
     /tmp/sym
     $ cd -P /tmp/sym
     $ pwd
     /tmp/dir
  The behavior described by these man pages isn't specified in the ksh
  man page or by POSIX, so to avoid changing these builtin's behavior
  the inaccurate PATH_RESOLVE information has been removed.

- Mamfiles: Preserve multi-line errors by quoting the $x variable.
  This fix was backported from 93v-.
  (See also <a7e9cc82>.)

- sh/subshell.c: Remove set but not used sp->errcontext variable.
2021-12-09 06:42:59 +01:00

223 lines
6.6 KiB
C

/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1982-2011 AT&T Intellectual Property *
* Copyright (c) 2020-2021 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* http://www.eclipse.org/org/documents/epl-v10.html *
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* David Korn <dgk@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
/*
* David Korn
* AT&T Labs
*
* shell script to shell binary converter
*
*/
#include "version.h"
static const char usage[] =
"[-?\n@(#)$Id: shcomp (AT&T Research) " SH_RELEASE " $\n]"
"[-author?David Korn <dgk@research.att.com>]"
"[-copyright?(c) 1982-2012 AT&T Intellectual Property]"
"[-copyright?" SH_RELEASE_CPYR "]"
"[-license?http://www.eclipse.org/org/documents/epl-v10.html]"
"[--catalog?" SH_DICT "]"
"[+NAME?shcomp - compile a shell script]"
"[+DESCRIPTION?Unless \b-D\b is specified, \b\f?\f\b takes a shell script, "
"\ainfile\a, and creates a binary format file, \aoutfile\a, that "
"\bksh\b can read and execute with the same effect as the original "
"script.]"
"[+?Since aliases are processed as the script is read, alias definitions "
"whose value requires variable expansion will not work correctly.]"
"[+?If \b-D\b is specified, all double quoted strings that are preceded by "
"\b$\b are output. These are the messages that need to be "
"translated to locale specific versions for internationalization.]"
"[+?If \ainfile\a is a simple command name, the shell script will be searched "
"on \b$PATH\b. It does not need execute permission to be found.]"
"[+?If \aoutfile\a is omitted, then the results will be written to "
"standard output. If \ainfile\a is also omitted, the shell script "
"will be read from standard input. However, \b\f?\f\b will not read "
"a script from your keyboard unless \ainfile\a is given as "
"\b/dev/stdin\b, and will refuse to write binary data to a terminal "
"in any case.]"
"[D:dictionary?Generate a list of strings that need to be placed in a message "
"catalog for internationalization.]"
"[n:noexec?Displays warning messages for obsolete or non-conforming "
"constructs.] "
"[v:verbose?Displays input from \ainfile\a onto standard error as it "
"reads it.]"
"\n"
"\n[infile [outfile]]\n"
"\n"
"[+EXIT STATUS?]{"
"[+0?Successful completion.]"
"[+>0?An error occurred.]"
"}"
"[+SEE ALSO?\bksh\b(1)]"
;
#include <shell.h>
#include "defs.h"
#include "path.h"
#include "shnodes.h"
#include "sys/stat.h"
#include "terminal.h"
#define CNTL(x) ((x)&037)
static const char header[6] = { CNTL('k'),CNTL('s'),CNTL('h'),0,SHCOMP_HDR_VERSION,0 };
int main(int argc, char *argv[])
{
Sfio_t *in, *out;
Shell_t *shp;
Namval_t *np;
Shnode_t *t;
char *cp, *shcomp_id, *script_id;
int n, nflag=0, vflag=0, dflag=0;
shcomp_id = error_info.id = path_basename(argv[0]);
while(n = optget(argv, usage )) switch(n)
{
case 'D':
dflag=1;
break;
case 'v':
vflag=1;
break;
case 'n':
nflag=1;
break;
case ':':
errormsg(SH_DICT,2,"%s",opt_info.arg);
break;
case '?':
errormsg(SH_DICT,ERROR_usage(2),"%s",opt_info.arg);
UNREACHABLE();
}
shp = sh_init(argc,argv,(Shinit_f)0);
script_id = error_info.id; /* set by sh_init() */
error_info.id = shcomp_id;
shp->shcomp = 1;
argv += opt_info.index;
argc -= opt_info.index;
if(argc==0 && tty_check(0))
{
errormsg(SH_DICT,ERROR_exit(0),"refusing to read script from terminal");
error_info.errors++;
}
if(error_info.errors || argc>2)
{
errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
UNREACHABLE();
}
if(cp= *argv)
{
argv++;
in = sh_pathopen(cp);
}
else
{
script_id = "(stdin)";
in = sfstdin;
}
if(cp= *argv)
{
struct stat statb;
if(!(out = sfopen((Sfio_t*)0,cp,"w")))
{
errormsg(SH_DICT,ERROR_system(1),"%s: cannot create",cp);
UNREACHABLE();
}
if(fstat(sffileno(out),&statb) >=0)
chmod(cp,(statb.st_mode&~S_IFMT)|S_IXUSR|S_IXGRP|S_IXOTH);
}
else
out = sfstdout;
if(tty_check(sffileno(out)))
{
errormsg(SH_DICT,ERROR_exit(1),"refusing to write binary data to terminal",cp);
UNREACHABLE();
}
if(dflag)
{
sh_onoption(SH_DICTIONARY);
sh_onoption(SH_NOEXEC);
}
if(nflag)
sh_onoption(SH_NOEXEC);
if(vflag)
sh_onoption(SH_VERBOSE);
if(!dflag)
sfwrite(out,header,sizeof(header)); /* write binary shcomp header */
sh_offoption(SH_MULTILINE);
shp->inlineno = 1;
#if SHOPT_BRACEPAT
sh_onoption(SH_BRACEEXPAND);
#endif
error_info.id = script_id;
while(1)
{
stakset((char*)0,0);
if(t = (Shnode_t*)sh_parse(shp,in,0))
{
if((t->tre.tretyp&(COMMSK|COMSCAN))==0 && t->com.comnamp && strcmp(nv_name((Namval_t*)t->com.comnamp),"alias")==0)
/* Create aliases found in the script to prevent syntax errors */
sh_exec(t,0);
if(!dflag && sh_tdump(out,t) < 0)
{
error_info.id = shcomp_id;
errormsg(SH_DICT,ERROR_exit(1),"dump failed");
UNREACHABLE();
}
}
else if(sfeof(in))
break;
if(sferror(in))
{
error_info.id = shcomp_id;
errormsg(SH_DICT,ERROR_system(1),"I/O error");
UNREACHABLE();
}
if(t && ((t->tre.tretyp&COMMSK)==TCOM) && (np=t->com.comnamp) && (cp=nv_name(np)))
{
if(strcmp(cp,"exit")==0)
break;
/* check for exec of a command */
if(strcmp(cp,"exec")==0)
{
if(t->com.comtyp&COMSCAN)
{
if(t->com.comarg->argnxt.ap)
break;
}
else
{
struct dolnod *ap = (struct dolnod*)t->com.comarg;
if(ap->dolnum>1)
break;
}
}
}
}
/* copy any remaining input */
if(!sfeof(in))
sfmove(in,out,SF_UNBOUND,-1);
if(in!=sfstdin)
sfclose(in);
if(out!=sfstdout)
sfclose(out);
return(0);
}