1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 1982-2014 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Eclipse Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
8 * *
9 * A copy of the License is available at *
10 * http://www.eclipse.org/org/documents/epl-v10.html *
11 * (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12 * *
13 * Information and Software Systems Research *
14 * AT&T Research *
15 * Florham Park NJ *
16 * *
17 * David Korn <dgkorn@gmail.com> *
18 * *
19 ***********************************************************************/
20 //
21 // David Korn
22 // AT&T Labs
23 //
24 // Shell interface private definitions.
25 //
26 #ifndef _DEFS_H
27 #define _DEFS_H 1
28
29 // This include shouldn't be necessary but without it compilation errors occur in modules like
30 // lex.c. But if we include it in that module IWYU complains it isn't needed.
31 #include <ctype.h>
32
33 #include "argnod.h"
34 #include "fault.h"
35 #include "history.h"
36 #include "name.h"
37
38 #define Empty ((char *)(e_sptbnl + 3))
39 #define env_change() (++ast.env_serial)
40 #define Env_t void
41 #define sh_envput(e, p) env_change()
42 #define env_delete(e, p) env_change()
43
44 // Shell options.
45 typedef uint_fast64_t Shopt_t_data_t;
46 typedef struct {
47 Shopt_t_data_t v[(256 / 8) / sizeof(Shopt_t_data_t)];
48 } Shopt_t;
49
50 extern char *sh_getenv(const char *);
51 extern char *sh_setenviron(const char *);
52
53 //
54 // Note that the first few fields have to be the same as for Shscope_t in <shell.h>.
55 //
56 struct sh_scoped {
57 struct sh_scoped *prevst; // pointer to previous state
58 int dolc;
59 char **dolv;
60 char *cmdname;
61 char *filename;
62 char *funname;
63 int64_t lineno;
64 Dt_t *save_tree; // var_tree for calling function
65 struct sh_scoped *self; // pointer to copy of this scope
66
67 Dt_t *var_local; // local level variables for name()
68 struct slnod *staklist; // link list of function stacks
69 int states;
70 int breakcnt;
71 int execbrk;
72 int loopcnt;
73 int firstline;
74 int32_t optindex;
75 int32_t optnum;
76 int32_t tmout; // value for TMOUT
77 short optchar;
78 short opterror;
79 int ioset;
80 unsigned short trapmax;
81 char *trap[SH_DEBUGTRAP + 1];
82 char **otrap;
83 char **trapcom;
84 char **otrapcom;
85 void *timetrap;
86 struct Ufunction *real_fun; // current 'function name' function
87 int repl_index;
88 char *repl_arg;
89 };
90
91 struct limits {
92 long arg_max; // max arg+env exec() size
93 int open_max; // maximum number of file descriptors
94 int child_max; // maximum number of children
95 };
96
97 #undef _FPATH // Cygwin defines _FPATH in /usr/include/sys/_default_fcntl.h
98
99 // This structure must be kept in sync with the shtab_variables[] array in data/variables.c.
100 // All structure member names have a leading underscore to avoid conflicts with #define symbols;
101 // e.g., LC_ALL.
102 struct bltin_vars {
103 Namval_t *_sh; // ${.sh}
104 Namval_t *_sh_command; // ${.sh.command}
105 Namval_t *_sh_dollar; // ${.sh.dollar}
106 Namval_t *_sh_edchar; // ${.sh.dollar}
107 Namval_t *_sh_edcol; // ${.sh.dollar}
108 Namval_t *_sh_edmode; // ${.sh.dollar}
109 Namval_t *_sh_edtext; // ${.sh.dollar}
110 Namval_t *_sh_file; // ${.sh.dollar}
111 Namval_t *_sh_fun; // ${.sh.dollar}
112 Namval_t *_sh_install_prefix; // ${.sh.dollar}
113 Namval_t *_sh_level; // ${.sh.dollar}
114 Namval_t *_sh_lineno; // ${.sh.dollar}
115 Namval_t *_sh_match; // ${.sh.dollar}
116 Namval_t *_sh_math; // ${.sh.dollar}
117 Namval_t *_sh_name; // ${.sh.dollar}
118 Namval_t *_sh_op_astbin; // ${.sh.dollar}
119 Namval_t *_sh_pgrp; // ${.sh.dollar}
120 Namval_t *_sh_pool; // ${.sh.dollar}
121 Namval_t *_sh_pwdfd; // ${.sh.dollar}
122 Namval_t *_sh_sig; // ${.sh.dollar}
123 Namval_t *_sh_stats; // ${.sh.dollar}
124 Namval_t *_sh_subscript; // ${.sh.dollar}
125 Namval_t *_sh_subshell; // ${.sh.dollar}
126 Namval_t *_sh_value; // ${.sh.dollar}
127 Namval_t *_sh_version; // ${.sh.dollar}
128 Namval_t *_CDPATH;
129 Namval_t *_COLUMNS;
130 Namval_t *_COMPREPLY;
131 Namval_t *_COMP_CWORD;
132 Namval_t *_COMP_KEY;
133 Namval_t *_COMP_LINE;
134 Namval_t *_COMP_POINT;
135 Namval_t *_COMP_TYPE;
136 Namval_t *_COMP_WORDBREAKS;
137 Namval_t *_COMP_WORDS;
138 Namval_t *_EDITOR;
139 Namval_t *_ENV;
140 Namval_t *_FCEDIT;
141 Namval_t *_FIGNORE;
142 Namval_t *_FPATH;
143 Namval_t *_HISTCMD;
144 Namval_t *_HISTEDIT;
145 Namval_t *_HISTFILE;
146 Namval_t *_HISTSIZE;
147 Namval_t *_HOME;
148 Namval_t *_IFS;
149 Namval_t *_JOBMAX;
150 Namval_t *_KSH_VERSION;
151 Namval_t *_LANG;
152 Namval_t *_LC_ALL;
153 Namval_t *_LC_COLLATE;
154 Namval_t *_LC_CTYPE;
155 Namval_t *_LC_MESSAGES;
156 Namval_t *_LC_NUMERIC;
157 Namval_t *_LC_TIME;
158 Namval_t *_LINENO;
159 Namval_t *_LINES;
160 Namval_t *_MAIL;
161 Namval_t *_MAILCHECK;
162 Namval_t *_MAILPATH;
163 Namval_t *_OLDPWD;
164 Namval_t *_OPTARG;
165 Namval_t *_OPTIND;
166 Namval_t *_PATH;
167 Namval_t *_PPID;
168 Namval_t *_PS1;
169 Namval_t *_PS2;
170 Namval_t *_PS3;
171 Namval_t *_PS4;
172 Namval_t *_PWD;
173 Namval_t *_RANDOM;
174 Namval_t *_REPLY;
175 Namval_t *_SECONDS;
176 Namval_t *_SHELL;
177 Namval_t *_SHLVL;
178 Namval_t *_SH_OPTIONS;
179 Namval_t *_TMOUT;
180 Namval_t *_VISUAL;
181 Namval_t *_underscore; // $_
182 };
183
184 struct shared {
185 struct limits lim;
186 uid_t userid;
187 uid_t euserid;
188 gid_t groupid;
189 gid_t egroupid;
190 pid_t pid;
191 pid_t ppid;
192 unsigned char sigruntime[2];
193 struct bltin_vars vars;
194 Namval_t *bltin_cmds;
195 History_t *hist_ptr;
196 char *shpath;
197 char *user;
198 const char **sigmsg;
199 char *rcfile;
200 char **login_files;
201 Edit_t *ed_context;
202 void *init_context;
203 void *job_context;
204 int *stats;
205 int sigmax;
206 int nforks;
207 int shtype;
208 };
209
210 #include "shell.h"
211 #include "shtable.h"
212
213 // Error exits from various parts of shell.
214 #define exitset(shp) (shp->savexit = shp->exitval)
215
216 #ifndef SH_DICT
217 #define SH_DICT (void *)e_dict
218 #endif
219
220 #define SH_CMDLIB_DIR "/opt/ast/bin"
221
222 // States. Low numbered states are same as options.
223 #define SH_NOFORK 0 // set when fork not necessary
224 #define SH_FORKED 7 // set when process has been forked
225 #define SH_PROFILE 8 // set when processing profile
226 #define SH_NOALIAS 9 // do not expand non-exported aliases
227 #define SH_NOTRACK 10 // set to disable sftrack() function
228 #define SH_STOPOK 11 // set for stopable builtins
229 #define SH_GRACE 12 // set for timeout grace period
230 #define SH_TIMING 13 // set while timing pipelines
231 #define SH_DEFPATH 14 // set when using default path
232 #define SH_INIT 15 // set when initializing the shell
233 #define SH_TTYWAIT 16 // waiting for keyboard input
234 #define SH_FCOMPLETE 17 // set for filename completion
235 #define SH_PREINIT 18 // set with SH_INIT before parsing options
236 #define SH_COMPLETE 19 // set for command completion
237 #define SH_IOPROMPT 20 // set when prompting
238
239 #define SH_BASH 41
240 #define SH_BRACEEXPAND 42
241 #define SH_POSIX 46
242 #define SH_MULTILINE 47
243
244 #define SH_NOUSRPROFILE 79
245 #define SH_LOGIN_SHELL 67
246 #define SH_COMMANDLINE 0x100
247 #define SH_BASHEXTRA 0x200
248 #define SH_BASHOPT 0x400
249
250 #define SH_ID "ksh" // ksh id
251 #define SH_STD "sh" // standard sh id
252
253 // Defines for sh_type().
254 #define SH_TYPE_SH 001
255 #define SH_TYPE_KSH 002
256 #define SH_TYPE_BASH 004
257 #define SH_TYPE_LOGIN 010
258 #define SH_TYPE_PROFILE 020
259 #define SH_TYPE_RESTRICTED 040
260
261 #if SHOPT_BASH
262 // Define for all the bash options.
263 #define SH_CDABLE_VARS 51
264 #define SH_CDSPELL 52
265 #define SH_CHECKHASH 53
266 #define SH_CHECKWINSIZE 54
267 #define SH_CMDHIST 55
268 #define SH_DOTGLOB 56
269 #define SH_EXECFAIL 57
270 #define SH_EXPAND_ALIASES 58
271 #define SH_EXTGLOB 59
272 #define SH_HOSTCOMPLETE 63
273 #define SH_HUPONEXIT 64
274 #define SH_INTERACTIVE_COMM 65
275 #define SH_LITHIST 66
276 #define SH_MAILWARN 68
277 #define SH_NOEMPTYCMDCOMPL 69
278 #define SH_NOCASEGLOB 70
279 #define SH_NULLGLOB 71
280 #define SH_PHYSICAL 45
281 #define SH_PROGCOMP 72
282 #define SH_PROMPTVARS 73
283 #define SH_RESTRICTED2 74
284 #define SH_SHIFT_VERBOSE 75
285 #define SH_SOURCEPATH 76
286 #define SH_XPG_ECHO 77
287 #define SH_LASTPIPE 78
288 #endif
289
290 #define SH_HISTAPPEND 60
291 #define SH_HISTEXPAND 43
292 #define SH_HISTORY2 44
293 #define SH_HISTREEDIT 61
294 #define SH_HISTVERIFY 62
295
296 #ifndef PIPE_BUF
297 #define PIPE_BUF 512
298 #endif
299
300 #define MATCH_MAX 64
301
302 #define SH_READEVAL 0x4000 // for sh_eval
303 #define SH_FUNEVAL 0x10000 // for sh_eval for function load
304
305 extern struct shared *shgd;
306 extern void sh_outname(Shell_t *, Sfio_t *, char *, int);
307 extern void sh_applyopts(Shell_t *, Shopt_t);
308 extern char **sh_argbuild(Shell_t *, int *, const struct comnod *, int);
309 extern struct dolnod *sh_argfree(Shell_t *, struct dolnod *);
310 extern struct dolnod *sh_argnew(Shell_t *, char *[], struct dolnod **);
311 extern struct Shell_arg *sh_argopen(Shell_t *);
312 extern struct argnod *sh_argprocsub(Shell_t *, struct argnod *);
313 extern void sh_argreset(Shell_t *, struct dolnod *, struct dolnod *);
314 extern Namval_t *sh_assignok(Namval_t *, int);
315 extern struct dolnod *sh_arguse(Shell_t *);
316 extern char *sh_checkid(char *, char *);
317 extern void sh_chktrap(Shell_t *);
318 extern void sh_deparse(Sfio_t *, const Shnode_t *, int);
319 extern int sh_debug(Shell_t *shp, const char *, const char *, const char *, char *const[], int);
320 extern int sh_echolist(Shell_t *, Sfio_t *, int, char **);
321 extern struct argnod *sh_endword(Shell_t *, int);
322 extern char **sh_envgen(Shell_t *);
323 extern void sh_envnolocal(Namval_t *, void *);
324 extern Sfdouble_t sh_arith(Shell_t *, const char *);
325 extern void *sh_arithcomp(Shell_t *, char *);
326 extern pid_t sh_fork(Shell_t *, int, int *);
327 extern pid_t _sh_fork(Shell_t *, pid_t, int, int *);
328 extern char *sh_mactrim(Shell_t *, char *, int);
329 extern int sh_macexpand(Shell_t *, struct argnod *, struct argnod **, int);
330 extern bool sh_macfun(Shell_t *, const char *, int);
331 extern void sh_machere(Shell_t *, Sfio_t *, Sfio_t *, char *);
332 extern Mac_t *sh_macopen(Shell_t *);
333 extern char *sh_macpat(Shell_t *, struct argnod *, int);
334 extern Sfdouble_t sh_mathfun(Shell_t *, void *, int, Sfdouble_t *);
335 extern int sh_outtype(Shell_t *, Sfio_t *);
336 extern char *sh_mactry(Shell_t *, char *);
337 extern int sh_mathstd(const char *);
338 extern void sh_printopts(Shell_t *, Shopt_t, int, Shopt_t *);
339 extern int sh_readline(Shell_t *, char **, void *, volatile int, int, ssize_t, long);
340 extern Sfio_t *sh_sfeval(const char **);
341 extern char *sh_fmtstr(const char *, int);
342 extern void sh_setmatch(Shell_t *, const char *, int, int, int[], int);
343 extern Dt_t *sh_subaliastree(Shell_t *, int);
344 extern void sh_scope(Shell_t *, struct argnod *, int);
345 extern Namval_t *sh_scoped(Shell_t *, Namval_t *);
346 extern Namval_t **sh_setlist(Shell_t *, struct argnod *, nvflag_t, Namval_t *);
347 extern void sh_sigclear(Shell_t *, int);
348 extern void sh_sigdone(Shell_t *);
349 extern void sh_sigreset(Shell_t *, int);
350 extern void sh_sigtrap(Shell_t *, int);
351 extern void sh_siglist(Shell_t *, Sfio_t *, int);
352 extern Dt_t *sh_subfuntree(Shell_t *, bool);
353 extern void sh_subjobcheck(pid_t);
354 extern int sh_subsavefd(int);
355 extern void sh_subtmpfile(Shell_t *);
356 extern char *sh_substitute(Shell_t *, const char *, const char *, const char *);
357 extern const char *_sh_translate(const char *);
358 extern bool sh_trace(Shell_t *, char *[], int);
359 extern void sh_trim(char *);
360 extern int sh_type(const char *);
361 extern void sh_unscope(Shell_t *);
362 extern Namval_t *sh_fsearch(Shell_t *, const char *, nvflag_t);
363 extern int sh_diropenat(Shell_t *, int, const char *);
364 extern int sh_strchr(const char *, const char *, size_t);
365
366 // These two magic pointers are used to distinguish the purpose of the `extra` parameter of the
367 // `sh_addbuiltin()` function. It should be one of these two values, NULL, or a `Namfun_t*`.
368 extern void *const builtin_delete;
369 extern void *const builtin_disable;
370
371 #ifndef ERROR_dictionary
372 #define ERROR_dictionary(s) (s)
373 #endif
374 #define sh_translate(s) _sh_translate(ERROR_dictionary(s))
375
376 #define WBITS (sizeof(Shopt_t_data_t) * 8)
377 #define WMASK (0xff)
378
379 #define is_option(s, x) (((s)->v[((x)&WMASK) / WBITS] & (1ULL << ((x) % WBITS))) ? true : false)
380 #define on_option(s, x) ((void)((s)->v[((x)&WMASK) / WBITS] |= (1ULL << ((x) % WBITS))))
381 #define off_option(s, x) ((void)((s)->v[((x)&WMASK) / WBITS] &= ~(1ULL << ((x) % WBITS))))
382
383 #define sh_isoption(shp, x) is_option(&(shp)->options, (x))
384 #define sh_onoption(shp, x) on_option(&(shp)->options, (x))
385 #define sh_offoption(shp, x) off_option(&(shp)->options, (x))
386
387 #define sh_state(x) (1 << (x))
388 #define sh_isstate(shp, x) ((shp)->st.states & sh_state(x))
389 #define sh_onstate(shp, x) ((shp)->st.states |= sh_state(x))
390 #define sh_offstate(shp, x) ((shp)->st.states &= ~sh_state(x))
391 #define sh_getstate(shp) ((shp)->st.states)
392 #define sh_setstate(shp, x) ((shp)->st.states = (x))
393
394 extern int32_t sh_mailchk;
395 extern const char e_dict[];
396
397 // sh_printopts() mode flags -- set --[no]option by default.
398 #define PRINT_VERBOSE 0x01 // option on|off list
399 #define PRINT_ALL 0x02 // list unset options too
400 #define PRINT_NO_HEADER 0x04 // omit listing header
401 #define PRINT_SHOPT 0x08 // shopt -s|-u
402 #define PRINT_TABLE 0x10 // table of all options
403
404 // Performance statistics.
405 #define STAT_ARGHITS 0
406 #define STAT_ARGEXPAND 1
407 #define STAT_COMSUB 2
408 #define STAT_FORKS 3
409 #define STAT_FUNCT 4
410 #define STAT_GLOBS 5
411 #define STAT_READS 6
412 #define STAT_NVHITS 7
413 #define STAT_NVOPEN 8
414 #define STAT_PATHS 9
415 // #define STAT_SVFUNCT 10
416 #define STAT_SCMDS 11
417 #define STAT_SPAWN 12
418 #define STAT_SUBSHELL 13
419 extern const Shtable_t shtab_stats[];
420 #define sh_stats(x) (shgd->stats[(x)]++)
421 extern const Shtable_t shtab_siginfo[];
422
423 #define timeofday(p) gettimeofday(p, NULL)
424
425 // sigqueue() may not be available on some platforms (e.g., macOS) or doesn't work on others
426 // (e.g., WSL). So provide a fallback that mostly does what we need.
427 #if !_lib_sigqueue || _WSL_
sigqueue_fallback(pid_t pid,int sig,const union sigval sig_val)428 static inline int sigqueue_fallback(pid_t pid, int sig, const union sigval sig_val) {
429 UNUSED(sig_val);
430 return kill(pid, sig);
431 }
432 #define sigqueue sigqueue_fallback
433 #endif
434
435 #define sh_sigaction(s, action) \
436 do { \
437 sigset_t ss; \
438 sigemptyset(&ss); \
439 sigaddset(&ss, (s)); \
440 sigprocmask(action, &ss, NULL); \
441 } while (0)
442
443 #ifndef CLD_EXITED
444 #define CLD_EXITED 1
445 #define CLD_KILLED 2
446 #define CLD_DUMPED 3
447 #define CLD_STOPPED 4
448 #define CLD_CONTINUED 5
449 #endif
450
451 // TODO: Should this be removed when we move to standard locale functions?
getdecimal()452 static inline int getdecimal() {
453 struct lconv *lp;
454 lp = localeconv();
455 // cppcheck-suppress identicalInnerCondition
456 if (lp && lp->decimal_point && *lp->decimal_point) return *lp->decimal_point;
457 return '.';
458 }
459
460 #endif // _DEFS_H
461