static NODE * do_fork(int nargs) { int ret = -1; NODE **aptr; NODE *tmp; if (do_lint && get_curfunc_arg_count() > 0) lintwarn("fork: called with too many arguments"); ret = fork(); if (ret < 0) update_ERRNO(); else if (ret == 0) { /* update PROCINFO in the child */ aptr = assoc_lookup(PROCINFO_node, tmp = make_string("pid", 3), FALSE); (*aptr)->numbr = (AWKNUM) getpid(); unref(tmp); aptr = assoc_lookup(PROCINFO_node, tmp = make_string("ppid", 4), FALSE); (*aptr)->numbr = (AWKNUM) getppid(); unref(tmp); } /* Set the return value */ return make_number((AWKNUM) ret); }
static NODE * do_waitpid(int nargs) { NODE *pidnode; int ret = -1; double pidval; pid_t pid; int options = 0; if (do_lint && get_curfunc_arg_count() > 1) lintwarn("waitpid: called with too many arguments"); pidnode = get_scalar_argument(0, FALSE); if (pidnode != NULL) { pidval = force_number(pidnode); pid = (int) pidval; options = WNOHANG|WUNTRACED; ret = waitpid(pid, NULL, options); if (ret < 0) update_ERRNO(); } else if (do_lint) lintwarn("wait: called with no arguments"); /* Set the return value */ return make_number((AWKNUM) ret); }
static NODE * do_pause(int nargs) { if (do_lint && get_curfunc_arg_count() > 0) lintwarn("pause: called with too many arguments"); return make_number((AWKNUM) pause()); }
static NODE * do_killpg(int nargs) { if (do_lint && get_curfunc_arg_count() > 2) lintwarn("killpg: called with too many arguments"); return kill_killpg(killpg); }
static NODE * do_has_exception(int nags) { if (do_lint && get_curfunc_arg_count() > 2) lintwarn("has_exception: called with too many arguments"); return can_sub(HAS_EXCEPTION); }
static NODE * do_can_write(int nags) { if (do_lint && get_curfunc_arg_count() > 2) lintwarn("can_write: called with too many arguments"); return can_sub(CAN_WRITE); }
static NODE * do_sigsuspend(int nargs) { sigset_t mask; if (do_lint && get_curfunc_arg_count() > 1) lintwarn("sigsuspend: called with too many arguments"); ana_mask(&mask, 0); return make_number((AWKNUM) sigsuspend(&mask)); }
static NODE * do_writea(int nargs) { NODE *file, *array; int ret; int fd; uint32_t major = MAJOR; uint32_t minor = MINOR; if (do_lint && get_curfunc_arg_count() > 2) lintwarn("writea: called with too many arguments"); /* directory is first arg, array to dump is second */ file = get_scalar_argument(0, FALSE); array = get_array_argument(1, FALSE); /* open the file, if error, set ERRNO and return */ (void) force_string(file); fd = creat(file->stptr, 0600); if (fd < 0) { goto done1; } if (write(fd, MAGIC, strlen(MAGIC)) != strlen(MAGIC)) goto done1; major = htonl(major); if (write(fd, & major, sizeof(major)) != sizeof(major)) goto done1; minor = htonl(minor); if (write(fd, & minor, sizeof(minor)) != sizeof(minor)) goto done1; ret = write_array(fd, array); if (ret != 0) goto done1; ret = 0; goto done0; done1: ret = -1; update_ERRNO(); unlink(file->stptr); done0: close(fd); /* Set the return value */ return make_number((AWKNUM) ret); }
static NODE * do_alarm(int nargs) { NODE *tmp; unsigned int second; if (do_lint && get_curfunc_arg_count() > 1) lintwarn("alarm: called with too many arguments"); tmp = (NODE *) get_scalar_argument(0, FALSE); second = (unsigned int) force_number(tmp); return make_number((AWKNUM) alarm(second)); }
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 * do_usleep(int nags) { NODE *tmp; struct timeval timeout; if (do_lint && get_curfunc_arg_count() > 1) lintwarn("usleep: called with too many arguments"); timeout.tv_sec = 0; tmp = (NODE *) get_actual_argument(0, FALSE, FALSE); timeout.tv_usec = (suseconds_t) force_number(tmp); select(0, NULL, NULL, NULL, &timeout); return make_number((AWKNUM) 0); }
static NODE * do_sleep(int nags) { NODE *tmp; struct timeval timeout; double integer, point; if (do_lint && get_curfunc_arg_count() > 1) lintwarn("sleep: called with too many arguments"); tmp = (NODE *) get_actual_argument(0, FALSE, FALSE); point = modf(force_number(tmp), &integer); timeout.tv_sec = (time_t) integer; timeout.tv_usec = (suseconds_t) (point * 1000000); select(0, NULL, NULL, NULL, &timeout); return make_number((AWKNUM) 0); }
static NODE * do_sigprocmask(int nargs) { NODE *tmp; int how; sigset_t mask; sigset_t old; int ret; if (do_lint && get_curfunc_arg_count() > 1) lintwarn("sigsuspend: called with too many arguments"); tmp = (NODE *) get_scalar_argument(0, FALSE); force_string(tmp); how = str2how(tmp->stptr); ana_mask(&mask, 1); ret = sigprocmask(how, &mask, &old); ret_mask(&mask, 2); return make_number((AWKNUM) ret); }
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)); }
static NODE * do_select(int nags) { NODE *tmp, *array, *elm, *value; int nfds; fd_set rfds, wfds, efds; struct timeval timeout; struct timeval *timeout_ptr; int retval; struct redirect *rp; double integer, point; int i, j; int fp; if (do_lint && get_curfunc_arg_count() > 4) lintwarn("select: called with too many arguments"); /*** Analyse File-descriptors ***/ nfds = -1; FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds); for (i = 0; i < 3; i++ ) { array = (NODE *) get_array_argument(i, FALSE); if ( array == NULL ) { continue; } for (j = 0; j < array->array_size; j++) { for (elm = array->var_array[j]; elm != NULL; elm = elm->ahnext) { value = elm->hvalue; force_string(value); rp = getredirect(value->stptr, value->stlen); if (rp == NULL) { if (do_lint) { lintwarn("select: `%.*s' is not an open file, pipe or co-process", (int) value->stlen, value->stptr); } } fp = fileno(rp->fp); switch (i) { case 0: FD_SET(fp, &rfds); break; case 1: FD_SET(fp, &wfds); break; case 2: FD_SET(fp, &efds); break; } if (fp + 1 > nfds ) { nfds = fp + 1; } } } } /*** Analyse Timeout ***/ /* timeout specified as milli-seconds */ tmp = (NODE *) get_actual_argument(3, FALSE, FALSE); point = modf(force_number(tmp), &integer); if (integer < 0) { timeout_ptr = NULL; } else { timeout.tv_sec = (time_t) (integer / 1000); timeout.tv_usec = (suseconds_t) (point * 1000); timeout_ptr = &timeout; } retval = select(nfds, &rfds, &wfds, &efds, timeout_ptr); if (retval == -1) { perror("select()"); } else if (retval != 0) { /* TODO */ } return make_number((AWKNUM) retval); }
static NODE * do_reada(int nargs) { NODE *file, *array; int ret; int fd; uint32_t major; uint32_t minor; char magic_buf[30]; if (do_lint && get_curfunc_arg_count() > 2) lintwarn("reada: called with too many arguments"); /* directory is first arg, array to dump is second */ file = get_scalar_argument(0, FALSE); array = get_array_argument(1, FALSE); (void) force_string(file); fd = open(file->stptr, O_RDONLY); if (fd < 0) { goto done1; } memset(magic_buf, '\0', sizeof(magic_buf)); if (read(fd, magic_buf, strlen(MAGIC)) != strlen(MAGIC)) { goto done1; } if (strcmp(magic_buf, MAGIC) != 0) { goto done1; } if (read(fd, & major, sizeof(major)) != sizeof(major)) { goto done1; } major = ntohl(major); if (major != MAJOR) { goto done1; } if (read(fd, & minor, sizeof(minor)) != sizeof(minor)) { goto done1; } minor = ntohl(minor); if (minor != MINOR) { goto done1; } assoc_clear(array); ret = read_array(fd, array); if (ret == 0) goto done0; done1: ret = -1; update_ERRNO(); done0: close(fd); /* Set the return value */ return make_number((AWKNUM) ret); }