static int gz_path_add_curve_notes(gx_path * ppath, fixed x1, fixed y1, fixed x2, fixed y2, fixed x3, fixed y3, segment_notes notes) { subpath *psub; curve_segment *lp; if (ppath->bbox_set) { check_in_bbox(ppath, x1, y1); check_in_bbox(ppath, x2, y2); check_in_bbox(ppath, x3, y3); } path_open(); path_alloc_segment(lp, curve_segment, &st_curve, s_curve, notes, "gx_path_add_curve"); path_alloc_link(lp); lp->p1.x = x1; lp->p1.y = y1; lp->p2.x = x2; lp->p2.y = y2; path_set_point(lp, x3, y3); psub->curve_count++; ppath->curve_count++; path_update_draw(ppath); trace_segment("[P]", (segment *) lp); return 0; }
/* * alloc_sema() * Create new semaphore */ struct sema * alloc_sema(int init_val) { struct sema *s; port_t port; /* * Get data structure */ s = malloc(sizeof(struct sema)); if (s == 0) { return(0); } init_lock(&s->s_locked); s->s_val = init_val; /* * Attach to sema server, get two ports */ s->s_port = path_open("fs/sema:clone", ACC_READ | ACC_WRITE | ACC_CREATE); if (s->s_port < 0) { free(s); return(0); } s->s_portmaster = clone(s->s_port); return(s); }
/* * sc_wstat() * Handle FS_WSTAT of "select" and "unselect" messages * * Returns 0 if it's handled here, 1 if not. * NOTE: we "handle" it here even if it's an error for one of our * message types. */ int sc_wstat(struct msg *m, struct selclient *scp, char *field, char *val) { if (!strcmp(field, "select")) { extern port_t path_open(); if (scp->sc_mask) { msg_err(m->m_sender, EBUSY); return(0); } if (parse(val, &scp->sc_mask, &scp->sc_clid, &scp->sc_fd, &scp->sc_key) || (!scp->sc_mask)) { msg_err(m->m_sender, EINVAL); return(0); } /* * Protect against any unsupported bits */ if (scp->sc_nosupp & scp->sc_mask) { scp->sc_mask = 0; msg_err(m->m_sender, ENOTSUP); return(0); } /* * TBD: use hostname for clustered case */ if (selfs_port < 0) { selfs_port = path_open("//fs/select", 0); } if (selfs_port < 0) { scp->sc_mask = 0; msg_err(m->m_sender, strerror()); return(0); } scp->sc_needsel = 1; scp->sc_iocount = 0; /* * Client no longer uses select() on this connection */ } else if (!strcmp(field, "unselect")) { sc_done(scp); } else { /* * Not a message *we* handle... */ return(1); } /* * Success */ m->m_arg = m->m_arg1 = m->m_buflen = m->m_nseg = 0; msg_reply(m->m_sender, m); return(0); }
/* Note that all lines have the same notes. */ int gx_path_add_lines_notes(gx_path *ppath, const gs_fixed_point *ppts, int count, segment_notes notes) { subpath *psub; segment *prev; line_segment *lp = 0; int i; int code = 0; if (count <= 0) return 0; path_unshare(ppath); path_open(); psub = ppath->current_subpath; prev = psub->last; /* * We could do better than the following, but this is a start. * Note that we don't make any attempt to undo partial additions * if we fail partway through; this is equivalent to what would * happen with multiple calls on gx_path_add_line. */ for (i = 0; i < count; i++) { fixed x = ppts[i].x; fixed y = ppts[i].y; line_segment *next; if (ppath->bbox_set && outside_bbox(ppath, x, y)) { code = gs_note_error(gs_error_rangecheck); break; } if (!(next = gs_alloc_struct(gs_memory_stable(ppath->memory), line_segment, &st_line, "gx_path_add_lines")) ) { code = gs_note_error(gs_error_VMerror); break; } lp = next; lp->type = s_line; lp->notes = notes; prev->next = (segment *) lp; lp->prev = prev; lp->pt.x = x; lp->pt.y = y; prev = (segment *) lp; trace_segment("[P]", (segment *) lp); } if (lp != 0) ppath->position.x = lp->pt.x, ppath->position.y = lp->pt.y, psub->last = (segment *) lp, lp->next = 0, path_update_draw(ppath); return code; }
static int gz_path_add_gap_notes(gx_path * ppath, fixed x, fixed y, segment_notes notes) { subpath *psub; line_segment *lp; if (ppath->bbox_set) check_in_bbox(ppath, x, y); path_open(); path_alloc_segment(lp, line_segment, &st_line, s_gap, notes, "gx_path_add_gap"); path_alloc_link(lp); path_set_point(lp, x, y); path_update_draw(ppath); trace_segment("[P]", (segment *) lp); return 0; }
/* Only for internal use of the stroking algorithm. */ int gx_path_add_dash_notes(gx_path * ppath, fixed x, fixed y, fixed dx, fixed dy, segment_notes notes) { subpath *psub; dash_segment *lp; if (ppath->bbox_set) check_in_bbox(ppath, x, y); path_open(); path_alloc_segment(lp, dash_segment, &st_dash, s_dash, notes, "gx_dash_add_dash"); path_alloc_link(lp); path_set_point(lp, x, y); lp->tangent.x = dx; lp->tangent.y = dy; path_update_draw(ppath); trace_segment("[P]", (segment *) lp); return 0; }
/* * open_tty_dev() * Direct stdin/out/err onto named device * * We access the * device read/write, and attach it in this mode to * stdin/stdout/stderr. This lets scripts have an * interactive FD no matter how I/O is redirected. */ static void open_tty_dev(char *tty) { int x; port_t p; extern port_t path_open(char *, int); /* * Access named server, get R/W access. */ for (x = 0; x <= 2; ++x) { close(x); p = path_open(tty, ACC_READ | ACC_WRITE); if (p < 0) { perror(tty); exit(1); } (void)__fd_alloc(p); } }
int sh_source(Shell_t *shp, Sfio_t *iop, const char *file) { char* oid; char* nid; int fd; if (!file || !*file || (fd = path_open(shp,file, PATHCOMP)) < 0) { REGRESS(source, "sh_source", ("%s:ENOENT", file)); return 0; } oid = error_info.id; nid = error_info.id = strdup(file); shp->st.filename = path_fullname(shp,stakptr(PATH_OFFSET)); REGRESS(source, "sh_source", ("%s", file)); exfile(shp, iop, fd); error_info.id = oid; free(nid); return 1; }
/* Play a list of audio files. */ int main(int argc, char **argv) { int errorStatus = 0; int i; int c; int cnt; int file_type; int rem; int outsiz; int tsize; int len; int err; int ifd; int stdinseen; int regular; int swapBytes; int frame; char *outbuf; caddr_t mapaddr; struct stat st; char *cp; char ctldev[MAXPATHLEN]; (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); /* Get the program name */ prog = strrchr(argv[0], '/'); if (prog == NULL) prog = argv[0]; else prog++; Stdin = MGET("(stdin)"); /* Check AUDIODEV environment for audio device name */ if (cp = getenv("AUDIODEV")) { Audio_dev = cp; } /* Parse the command line arguments */ err = 0; while ((i = getopt(argc, argv, prog_opts)) != EOF) { switch (i) { case 'v': if (parse_unsigned(optarg, &Volume, "-v")) { err++; } else if (Volume > MAX_GAIN) { Error(stderr, MGET("%s: invalid value " "for -v\n"), prog); err++; } break; case 'd': Audio_dev = optarg; break; case 'V': Verbose = TRUE; break; case 'E': Errdetect = TRUE; break; case 'i': Immediate = TRUE; break; case '?': usage(); /*NOTREACHED*/ } } if (err > 0) exit(1); argc -= optind; /* update arg pointers */ argv += optind; /* Validate and open the audio device */ err = stat(Audio_dev, &st); if (err < 0) { Error(stderr, MGET("%s: cannot stat "), prog); perror(Audio_dev); exit(1); } if (!S_ISCHR(st.st_mode)) { Error(stderr, MGET("%s: %s is not an audio device\n"), prog, Audio_dev); exit(1); } /* This should probably use audio_cntl instead of open_audio */ if ((argc <= 0) && isatty(fileno(stdin))) { Error(stderr, MGET("%s: No files and stdin is a tty.\n"), prog); exit(1); } /* Check on the -i status now. */ Audio_fd = open(Audio_dev, O_WRONLY | O_NONBLOCK); if ((Audio_fd < 0) && (errno == EBUSY)) { if (Immediate) { Error(stderr, MGET("%s: %s is busy\n"), prog, Audio_dev); exit(1); } } (void) close(Audio_fd); Audio_fd = -1; /* Try to open the control device and save the current format */ (void) snprintf(ctldev, sizeof (ctldev), "%sctl", Audio_dev); Audio_ctlfd = open(ctldev, O_RDWR); if (Audio_ctlfd >= 0) { /* * wait for the device to become available then get the * controls. We want to save the format that is left when the * device is in a quiescent state. So wait until then. */ Audio_fd = open(Audio_dev, O_WRONLY); (void) close(Audio_fd); Audio_fd = -1; if (audio_get_play_config(Audio_ctlfd, &Save_hdr) != AUDIO_SUCCESS) { (void) close(Audio_ctlfd); Audio_ctlfd = -1; } } /* store AUDIOPATH so we don't keep doing getenv() */ Audio_path = getenv("AUDIOPATH"); /* Set up SIGINT handler to flush output */ (void) signal(SIGINT, sigint); /* Set the endian nature of the machine. */ if ((ulong_t)1 != htonl((ulong_t)1)) { NetEndian = FALSE; } /* If no filenames, read stdin */ stdinseen = FALSE; if (argc <= 0) { Ifile = Stdin; } else { Ifile = *argv++; argc--; } /* Loop through all filenames */ do { /* Interpret "-" filename to mean stdin */ if (strcmp(Ifile, "-") == 0) Ifile = Stdin; if (Ifile == Stdin) { if (stdinseen) { Error(stderr, MGET("%s: stdin already processed\n"), prog); goto nextfile; } stdinseen = TRUE; ifd = fileno(stdin); } else { if ((ifd = path_open(Ifile, O_RDONLY, 0, Audio_path)) < 0) { Error(stderr, MGET("%s: cannot open "), prog); perror(Ifile); errorStatus++; goto nextfile; } } /* Check to make sure this is an audio file */ err = audio_read_filehdr(ifd, &File_hdr, &file_type, (char *)NULL, 0); if (err != AUDIO_SUCCESS) { Error(stderr, MGET("%s: %s is not a valid audio file\n"), prog, Ifile); errorStatus++; goto closeinput; } /* If G.72X adpcm, set flags for conversion */ if ((File_hdr.encoding == AUDIO_ENCODING_G721) && (File_hdr.samples_per_unit == 2) && (File_hdr.bytes_per_unit == 1)) { Decode = AUDIO_ENCODING_G721; File_hdr.encoding = AUDIO_ENCODING_ULAW; File_hdr.samples_per_unit = 1; File_hdr.bytes_per_unit = 1; adpcm_state = (struct audio_g72x_state *)malloc (sizeof (*adpcm_state) * File_hdr.channels); for (i = 0; i < File_hdr.channels; i++) { g721_init_state(&adpcm_state[i]); } } else if ((File_hdr.encoding == AUDIO_ENCODING_G723) && (File_hdr.samples_per_unit == 8) && (File_hdr.bytes_per_unit == 3)) { Decode = AUDIO_ENCODING_G723; File_hdr.encoding = AUDIO_ENCODING_ULAW; File_hdr.samples_per_unit = 1; File_hdr.bytes_per_unit = 1; adpcm_state = (struct audio_g72x_state *)malloc (sizeof (*adpcm_state) * File_hdr.channels); for (i = 0; i < File_hdr.channels; i++) { g723_init_state(&adpcm_state[i]); } } else { Decode = AUDIO_ENCODING_NONE; } /* Check the device configuration */ open_audio(); if (audio_cmp_hdr(&Dev_hdr, &File_hdr) != 0) { /* * The device does not match the input file. * Wait for any old output to drain, then attempt * to reconfigure the audio device to match the * input data. */ if (audio_drain(Audio_fd, FALSE) != AUDIO_SUCCESS) { /* Flush any remaining audio */ (void) ioctl(Audio_fd, I_FLUSH, FLUSHW); Error(stderr, MGET("%s: "), prog); perror(MGET("AUDIO_DRAIN error")); exit(1); } /* Flush any remaining audio */ (void) ioctl(Audio_fd, I_FLUSH, FLUSHW); if (!reconfig()) { errorStatus++; goto closeinput; } } /* try to do the mmaping - for regular files only ... */ err = fstat(ifd, &st); if (err < 0) { Error(stderr, MGET("%s: cannot stat "), prog); perror(Ifile); exit(1); } regular = (S_ISREG(st.st_mode)); /* If regular file, map it. Else, allocate a buffer */ mapaddr = 0; /* * This should compare to MAP_FAILED not -1, can't * find MAP_FAILED */ if (regular && ((mapaddr = mmap(0, st.st_size, PROT_READ, MAP_SHARED, ifd, 0)) != MAP_FAILED)) { (void) madvise(mapaddr, st.st_size, MADV_SEQUENTIAL); /* Skip the file header and set the proper size */ cnt = lseek(ifd, 0, SEEK_CUR); if (cnt < 0) { perror("lseek"); exit(1); } inbuf = (unsigned char *) mapaddr + cnt; len = cnt = st.st_size - cnt; } else { /* Not a regular file, or map failed */ /* mark is so. */ mapaddr = 0; /* Allocate buffer to hold 10 seconds of data */ cnt = BUFFER_LEN * File_hdr.sample_rate * File_hdr.bytes_per_unit * File_hdr.channels; if (bufsiz != cnt) { if (buf != NULL) { (void) free(buf); } buf = (unsigned char *) malloc(cnt); if (buf == NULL) { Error(stderr, MGET("%s: couldn't allocate %dK " "buf\n"), prog, bufsiz / 1000); exit(1); } inbuf = buf; bufsiz = cnt; } } /* Set buffer sizes and pointers for conversion, if any */ switch (Decode) { default: case AUDIO_ENCODING_NONE: insiz = bufsiz; outbuf = (char *)buf; break; case AUDIO_ENCODING_G721: insiz = ADPCM_SIZE / 2; outbuf = (char *)adpcm_buf; initmux(1, 2); break; case AUDIO_ENCODING_G723: insiz = (ADPCM_SIZE * 3) / 8; outbuf = (char *)adpcm_buf; initmux(3, 8); break; } /* * 8-bit audio isn't a problem, however 16-bit audio is. * If the file is an endian that is different from the machine * then the bytes will need to be swapped. * * Note: Because the G.72X conversions produce 8bit output, * they don't require a byte swap before display and so * this scheme works just fine. If a conversion is added * that produces a 16 bit result and therefore requires * byte swapping before output, then a mechanism * for chaining the two conversions will have to be built. * * Note: The following if() could be simplified, but then * it gets to be very hard to read. So it's left as is. */ if (File_hdr.bytes_per_unit == 2 && ((!NetEndian && file_type == FILE_AIFF) || (!NetEndian && file_type == FILE_AU) || (NetEndian && file_type == FILE_WAV))) { swapBytes = TRUE; } else { swapBytes = FALSE; } if (swapBytes) { /* Read in interal number of sample frames. */ frame = File_hdr.bytes_per_unit * File_hdr.channels; insiz = (SWAP_SIZE / frame) * frame; /* make the output buffer the swap buffer. */ outbuf = (char *)swap_buf; } /* * At this point, we're all ready to copy the data. */ if (mapaddr == 0) { /* Not mmapped, do it a buffer at a time. */ inbuf = buf; frame = File_hdr.bytes_per_unit * File_hdr.channels; rem = 0; while ((cnt = read(ifd, inbuf+rem, insiz-rem)) >= 0) { /* * We need to ensure only an integral number of * samples is ever written to the audio device. */ cnt = cnt + rem; rem = cnt % frame; cnt = cnt - rem; /* * If decoding adpcm, or swapping bytes do it * now. * * We treat the swapping like a separate * encoding here because the G.72X encodings * decode to single byte output samples. If * another encoding is added and it produces * multi-byte output samples this will have to * be changed. */ if (Decode == AUDIO_ENCODING_G721) { outsiz = 0; demux(1, cnt / File_hdr.channels); for (c = 0; c < File_hdr.channels; c++) { err = g721_decode(in_ch_data[c], cnt / File_hdr.channels, &File_hdr, (void*)out_ch_data[c], &tsize, &adpcm_state[c]); outsiz = outsiz + tsize; if (err != AUDIO_SUCCESS) { Error(stderr, MGET( "%s: error decoding g721\n"), prog); errorStatus++; break; } } mux(outbuf); cnt = outsiz; } else if (Decode == AUDIO_ENCODING_G723) { outsiz = 0; demux(3, cnt / File_hdr.channels); for (c = 0; c < File_hdr.channels; c++) { err = g723_decode(in_ch_data[c], cnt / File_hdr.channels, &File_hdr, (void*)out_ch_data[c], &tsize, &adpcm_state[c]); outsiz = outsiz + tsize; if (err != AUDIO_SUCCESS) { Error(stderr, MGET( "%s: error decoding g723\n"), prog); errorStatus++; break; } } mux(outbuf); cnt = outsiz; } else if (swapBytes) { swab((char *)inbuf, outbuf, cnt); } /* If input EOF, write an eof marker */ err = write(Audio_fd, outbuf, cnt); if (err < 0) { perror("write"); errorStatus++; break; } else if (err != cnt) { Error(stderr, MGET("%s: output error: "), prog); perror(""); errorStatus++; break; } if (cnt == 0) { break; } /* Move remainder to the front of the buffer */ if (rem != 0) { (void *)memcpy(inbuf, inbuf + cnt, rem); } } if (cnt < 0) { Error(stderr, MGET("%s: error reading "), prog); perror(Ifile); errorStatus++; } } else { /* We're mmaped */ if ((Decode != AUDIO_ENCODING_NONE) || swapBytes) { /* Transform data if we have to. */ for (i = 0; i <= len; i += cnt) { cnt = insiz; if ((i + cnt) > len) { cnt = len - i; } if (Decode == AUDIO_ENCODING_G721) { outsiz = 0; demux(1, cnt / File_hdr.channels); for (c = 0; c < File_hdr.channels; c++) { err = g721_decode( in_ch_data[c], cnt / File_hdr.channels, &File_hdr, (void*)out_ch_data[c], &tsize, &adpcm_state[c]); outsiz = outsiz + tsize; if (err != AUDIO_SUCCESS) { Error(stderr, MGET( "%s: error decoding " "g721\n"), prog); errorStatus++; break; } } mux(outbuf); } else if (Decode == AUDIO_ENCODING_G723) { outsiz = 0; demux(3, cnt / File_hdr.channels); for (c = 0; c < File_hdr.channels; c++) { err = g723_decode( in_ch_data[c], cnt / File_hdr.channels, &File_hdr, (void*)out_ch_data[c], &tsize, &adpcm_state[c]); outsiz = outsiz + tsize; if (err != AUDIO_SUCCESS) { Error(stderr, MGET( "%s: error " "decoding g723\n"), prog); errorStatus++; break; } } mux(outbuf); } else if (swapBytes) { swab((char *)inbuf, outbuf, cnt); outsiz = cnt; } inbuf += cnt; /* If input EOF, write an eof marker */ err = write(Audio_fd, (char *)outbuf, outsiz); if (err < 0) { perror("write"); errorStatus++; } else if (outsiz == 0) { break; } } } else { /* write the whole thing at once! */ err = write(Audio_fd, inbuf, len); if (err < 0) { perror("write"); errorStatus++; } if (err != len) { Error(stderr, MGET("%s: output error: "), prog); perror(""); errorStatus++; } err = write(Audio_fd, inbuf, 0); if (err < 0) { perror("write"); errorStatus++; } } } /* Free memory if decoding ADPCM */ switch (Decode) { case AUDIO_ENCODING_G721: case AUDIO_ENCODING_G723: freemux(); break; default: break; } closeinput:; if (mapaddr != 0) (void) munmap(mapaddr, st.st_size); (void) close(ifd); /* close input file */ if (Errdetect) { cnt = 0; audio_set_play_error(Audio_fd, (unsigned int *)&cnt); if (cnt) { Error(stderr, MGET("%s: output underflow in %s\n"), Ifile, prog); errorStatus++; } } nextfile:; } while ((argc > 0) && (argc--, (Ifile = *argv++) != NULL)); /* * Though drain is implicit on close(), it's performed here * to ensure that the volume is reset after all output is complete. */ (void) audio_drain(Audio_fd, FALSE); /* Flush any remaining audio */ (void) ioctl(Audio_fd, I_FLUSH, FLUSHW); if (Volume != INT_MAX) (void) audio_set_play_gain(Audio_fd, &Savevol); if ((Audio_ctlfd >= 0) && (audio_cmp_hdr(&Save_hdr, &Dev_hdr) != 0)) { (void) audio_set_play_config(Audio_fd, &Save_hdr); } (void) close(Audio_fd); /* close output */ return (errorStatus); }
int b_dot_cmd(int n, char *argv[], Shbltin_t *context) { char *script; Namval_t *np; int jmpval; Shell_t *shp = context->shp; struct sh_scoped savst, *prevscope = shp->st.self; int fd; char *filename = NULL; char *buffer = NULL; struct dolnod *saveargfor = NULL; volatile struct dolnod *argsave = NULL; checkpt_t buff; Sfio_t *iop = NULL; short level; Optdisc_t disc; memset(&disc, 0, sizeof(disc)); disc.version = OPT_VERSION; opt_info.disc = &disc; while ((n = optget(argv, sh_optdot))) { switch (n) { case ':': { errormsg(SH_DICT, 2, "%s", opt_info.arg); break; } case '?': { errormsg(SH_DICT, ERROR_usage(0), "%s", opt_info.arg); return 2; } default: { break; } } } argv += opt_info.index; script = *argv; if (error_info.errors || !script) { errormsg(SH_DICT, ERROR_usage(2), "%s", optusage(NULL)); __builtin_unreachable(); } if (shp->dot_depth + 1 > DOTMAX) { errormsg(SH_DICT, ERROR_exit(1), e_toodeep, script); __builtin_unreachable(); } np = shp->posix_fun; if (!np) { // Check for KornShell style function first. np = nv_search(script, shp->fun_tree, 0); if (np && is_afunction(np) && !nv_isattr(np, NV_FPOSIX)) { if (!FETCH_VT(np->nvalue, ip)) { // TODO: Replace this with a comment explaining why the return value of this // path_search() call is ignored. At the time I wrote this (2019-03-16) no unit test // exercises this statement. I added the void cast to silence Coverity Scan 253792. (void)path_search(shp, script, NULL, 0); if (FETCH_VT(np->nvalue, ip)) { if (nv_isattr(np, NV_FPOSIX)) np = NULL; } else { errormsg(SH_DICT, ERROR_exit(1), e_found, script); __builtin_unreachable(); } } } else { np = NULL; } if (!np) { fd = path_open(shp, script, path_get(shp, script)); if (fd < 0) { errormsg(SH_DICT, ERROR_system(1), e_open, script); __builtin_unreachable(); } filename = path_fullname(shp, stkptr(shp->stk, PATH_OFFSET)); } } *prevscope = shp->st; shp->st.lineno = np ? ((struct functnod *)nv_funtree(np))->functline : 1; shp->st.var_local = shp->st.save_tree = shp->var_tree; if (filename) { shp->st.filename = filename; shp->st.lineno = 1; } level = shp->fn_depth + shp->dot_depth + 1; nv_putval(SH_LEVELNOD, (char *)&level, NV_INT16); shp->st.prevst = prevscope; shp->st.self = &savst; shp->topscope = (Shscope_t *)shp->st.self; prevscope->save_tree = shp->var_tree; if (np) { struct Ufunction *rp = FETCH_VT(np->nvalue, rp); shp->st.filename = strdup(rp->fname ? rp->fname : ""); } nv_putval(SH_PATHNAMENOD, shp->st.filename, NV_NOFREE); shp->posix_fun = NULL; if (np || argv[1]) argsave = sh_argnew(shp, argv, &saveargfor); sh_pushcontext(shp, &buff, SH_JMPDOT); jmpval = sigsetjmp(buff.buff, 0); if (jmpval == 0) { shp->dot_depth++; if (np) { sh_exec(shp, (Shnode_t *)(nv_funtree(np)), sh_isstate(shp, SH_ERREXIT)); } else { buffer = malloc(IOBSIZE + 1); iop = sfnew(NULL, buffer, IOBSIZE, fd, SF_READ); sh_offstate(shp, SH_NOFORK); sh_eval(shp, iop, sh_isstate(shp, SH_PROFILE) ? SH_FUNEVAL : 0); } } sh_popcontext(shp, &buff); if (buffer) free(buffer); if (!np) { free(shp->st.filename); shp->st.filename = NULL; } shp->dot_depth--; if ((np || argv[1]) && jmpval != SH_JMPSCRIPT) { sh_argreset(shp, (struct dolnod *)argsave, saveargfor); } else { prevscope->dolc = shp->st.dolc; prevscope->dolv = shp->st.dolv; } if (shp->st.self != &savst) *shp->st.self = shp->st; // Only restore the top Shscope_t portion for posix functions. memcpy(&shp->st, prevscope, sizeof(Shscope_t)); shp->topscope = (Shscope_t *)prevscope; nv_putval(SH_PATHNAMENOD, shp->st.filename, NV_NOFREE); if (jmpval && jmpval != SH_JMPFUN) siglongjmp(shp->jmplist->buff, jmpval); return shp->exitval; }