static NODE * do_raise(int nargs) { NODE *tmp; int sig; if (do_lint && get_curfunc_arg_count() > 1) lintwarn("raise: called with too many arguments"); tmp = (NODE *) get_scalar_argument(0, FALSE); sig = get_signo(tmp); return make_number((AWKNUM) raise(sig)); }
static NODE * kill_killpg(int (*func)(int, int)) { NODE *tmp; pid_t pid_prg; int sig; tmp = (NODE *) get_scalar_argument(0, FALSE); pid_prg = (pid_t) force_number(tmp); tmp = (NODE *) get_scalar_argument(1, FALSE); sig = get_signo(tmp); return make_number((AWKNUM) func(pid_prg, sig)); }
int eval_options (int argc, char **argv, struct target_opts* defaults, const char** exe_opts) { const char opt_timeout[] = "-t"; const char opt_data_dir[] = "-d"; const char opt_t_flags[] = "-x"; const char opt_compat[] = "--compat"; const char opt_exit[] = "--exit"; const char opt_help[] = "--help"; const char opt_ignore[] = "--ignore"; const char opt_nocompat[] = "--nocompat"; const char opt_signal[] = "--signal"; const char opt_sleep[] = "--sleep"; const char opt_ulimit[] = "--ulimit"; const char opt_verbose[] = "--verbose"; const char opt_warn[] = "--warn"; int i; assert (0 != argv); assert (0 != defaults); memset (defaults, 0, sizeof (target_opts)); /* The chain of preprocesor logic below initializes the defaults->c_warn and defaults->l_warn values. */ #ifdef __GNUG__ parse_warn_opts ("Gcc", defaults); #elif defined (__HP_aCC) parse_warn_opts ("Acc", defaults); #elif defined (__IBMCPP__) parse_warn_opts ("Xlc", defaults); #elif defined (__SUNPRO_CC) parse_warn_opts ("Sunpro", defaults); #elif defined (SNI) parse_warn_opts ("Cds", defaults); #elif defined (__APOGEE__) /* EDG variant that doesn't define __EDG__. */ parse_warn_opts ("Como", defaults); /* The following are EDG variants, that define __EDG__ */ #elif defined (__DECCXX) parse_warn_opts ("Cxx", defaults); #elif defined (_SGI_COMPILER_VERSION) parse_warn_opts ("Mipspro", defaults); #elif defined (__INTEL_COMPILER) parse_warn_opts ("Icc", defaults); /* So we need to check for __EDG__ after we check for them. */ #elif defined (__EDG__) parse_warn_opts ("Eccp", defaults); #endif if (1 == argc || '-' != argv [1][0]) return 1; for (i = 1; i < argc && '-' == argv [i][0]; ++i) { /* the name of the option being processed */ const char* optname = argv [i]; /* the option's argument, if any */ const char* optarg = 0; char* end = 0; switch (argv [i][1]) { case '?': /* display help and exit with status of 0 */ case 'h': show_usage (0); case 'r': ++i; /* Ignore -r option (makefile compat) */ break; case 't': /* executable timeout in seconds */ optname = opt_timeout; optarg = get_short_val (argv, &i); if (optarg) { if (!isdigit (*optarg)) bad_value (optname, optarg); errno = 0; defaults->timeout = strtol (optarg, &end, 10); if (*end || errno) bad_value (optname, optarg); } else missing_value (optname); break; case 'd': /* directory containing example reference files */ optname = opt_data_dir; defaults->data_dir = get_short_val (argv, &i); if (!defaults->data_dir) missing_value (optname); break; case 'v': /* enable verbose mode */ optname = opt_verbose; ++defaults->verbose; break; case 'x': /* command line options to pass to targets */ optname = opt_t_flags; *exe_opts = get_short_val (argv, &i); if (!*exe_opts) missing_value (optname); break; case '-': /* long options */ { const size_t arglen = strlen (argv [i]); /* abort processing on --, eat token */ if ('\0' == argv [i][2]) return i+1; if ( sizeof opt_compat - 1 == arglen && !memcmp (opt_compat, argv [i], sizeof opt_compat)) { /* enter compatibility mode */ defaults->compat = 1; break; } else if ( sizeof opt_nocompat - 1 == arglen && !memcmp (opt_nocompat, argv [i], sizeof opt_nocompat)) { /* exit compatibility mode */ defaults->compat = 0; break; } else if ( sizeof opt_exit - 1 <= arglen && !memcmp (opt_exit, argv [i], sizeof opt_exit - 1)) { /* exit immediately with the specified status */ optname = opt_exit; optarg = get_long_val (argv, &i, sizeof opt_exit - 1); if (optarg && *optarg) { if (!isdigit (*optarg)) bad_value (optname, optarg); errno = 0; const long code = strtol (optarg, &end, 10); if ('\0' == *end && !errno) exit (code); } } else if ( sizeof opt_help - 1 == arglen && !memcmp (opt_help, argv [i], sizeof opt_help - 1)) { /* display help and exit with status of 0 */ optname = opt_help; show_usage (0); break; } else if ( sizeof opt_sleep - 1 <= arglen && !memcmp (opt_sleep, argv [i], sizeof opt_sleep - 1)) { /* sleep for the specified number of seconds */ optname = opt_sleep; optarg = get_long_val (argv, &i, sizeof opt_sleep - 1); if (optarg && *optarg) { if (!isdigit (*optarg)) bad_value (optname, optarg); errno = 0; const long nsec = strtol (optarg, &end, 10); if ('\0' == *end && 0 <= nsec && !errno) { rw_sleep (nsec); break; } } } else if ( sizeof opt_signal - 1 <= arglen && !memcmp (opt_signal, argv [i], sizeof opt_signal - 1)) { /* send ourselves the specified signal */ optname = opt_signal; optarg = get_long_val (argv, &i, sizeof opt_signal - 1); if (optarg && *optarg) { const int signo = get_signo (optarg); if (0 <= signo) { if (0 > raise (signo)) terminate (1, "raise(%s) failed: %s\n", get_signame (signo), strerror (errno)); break; } } } else if ( sizeof opt_ignore - 1 <= arglen && !memcmp (opt_ignore, argv [i], sizeof opt_ignore - 1)) { /* ignore the specified signal */ optname = opt_ignore; optarg = get_long_val (argv, &i, sizeof opt_ignore - 1); if (optarg && *optarg) { const int signo = get_signo (optarg); if (0 <= signo) { if (rw_signal (signo, 0 /* SIG_IGN */)) terminate (1, "rw_signal(%s, ...) failed: %s\n", get_signame (signo), strerror (errno)); break; } } } else if ( sizeof opt_ulimit - 1 <= arglen && !memcmp (opt_ulimit, argv [i], sizeof opt_ulimit - 1)) { /* set child process resource utilization limits */ optname = opt_ulimit; optarg = get_long_val (argv, &i, sizeof opt_ulimit - 1); if (optarg && *optarg) { if (!parse_limit_opts (optarg, defaults)) { break; } } } else if ( sizeof opt_warn - 1 <= arglen && !memcmp (opt_warn, argv [i], sizeof opt_warn - 1)) { /* set compiler warning mode */ optname = opt_warn; optarg = get_long_val (argv, &i, sizeof opt_warn - 1); if (optarg && *optarg) { if (!parse_warn_opts (optarg, defaults)) { break; } } } /* fall through */ } default: if (optarg) { if (*optarg) bad_value (optname, optarg); else missing_value (optname); } if (argv [i]) bad_option (argv [i]); else missing_value (optname); } } return i; }
static NODE * do_signal(int nargs) { NODE *tmp; const char *str; int sig; NODE *fnc_ptr; SigTable *sig_tbl; struct sigaction sig_act; if (do_lint && get_curfunc_arg_count() > 4) lintwarn("signal: called with too many arguments"); memset(&sig_act, 0, sizeof(struct sigaction)); /* signal number */ tmp = (NODE *) get_scalar_argument(0, FALSE); sig = get_signo(tmp); /* signal handler */ tmp = (NODE *) get_scalar_argument(1, FALSE); force_string(tmp); str = tmp->stptr; sig_tbl = sig2ptr(sig); if (str[0] == '@') { str++; /* advance '@' */ if (strncmp(str, "SIG", 3) == 0) { str += 3; } if (strncmp(str, "_", 1) == 0) { str += 1; } if (strcmp(str, "DFL") == 0) { sig_act.sa_handler = SIG_DFL; } else if (strcmp(str, "IGN") == 0) { sig_act.sa_handler = SIG_IGN; } else { //TODO sig_act.sa_handler = SIG_IGN; fatal } sig_tbl->user_handler = NULL; } else { fnc_ptr = lookup(str); sig_tbl->user_handler = fnc_ptr; sig_act.sa_handler = handler; } if (fnc_ptr == NULL || fnc_ptr->type != Node_func) fatal(_("Callback function `%s' is not defined"), tmp->stptr); /* mask */ if (get_curfunc_arg_count() >= 3) ana_mask(&sig_act.sa_mask, 2); else sigfillset(&sig_act.sa_mask); /* flags */ if (get_curfunc_arg_count() >= 4) sig_act.sa_flags = ana_flags(3); else sig_act.sa_flags |= SA_RESTART; /* システムコールが中止しない */ return make_number((AWKNUM) sigaction(sig, &sig_act, NULL)); }