mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
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 commited478ab7
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.
223 lines
6.6 KiB
C
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);
|
|
}
|