PTR get_pipe(char *command, int type, int *tmp_idp) { PTR retval; char xbuff[256]; char *tmpname; *tmp_idp = next_tmp; tmpname = tmp_file_name(next_tmp, xbuff + 163); if (type == PIPE_OUT) { retval = (PTR) fopen(tmpname, (binmode() & 2) ? "wb" : "w"); } else { sprintf(xbuff, "%s > %s", command, tmpname); tmp_idp[1] = DOSexec(xbuff); retval = (PTR) FINopen(tmpname, 0); } next_tmp++; return retval; }
/* get the next command line file open */ static FIN * next_main(int open_flag) /* called by open_main() if on */ { register CELL *cp; CELL *cp0; CELL argc; /* copy of ARGC */ CELL c_argi; /* cell copy of argi */ CELL argval; /* copy of ARGV[c_argi] */ int failed = 1; argval.type = C_NOINIT; c_argi.type = C_DOUBLE; if (main_fin) { FINclose(main_fin); main_fin = 0; } /* FILENAME and FNR don't change unless we really open a new file */ /* make a copy of ARGC to avoid side effect */ if (cellcpy(&argc, ARGC)->type != C_DOUBLE) cast1_to_d(&argc); while (argi < argc.dval) { c_argi.dval = argi; argi += 1.0; if (!(cp0 = array_find(Argv, &c_argi, NO_CREATE))) continue; /* its deleted */ /* make a copy so we can cast w/o side effect */ cell_destroy(&argval); cp = cellcpy(&argval, cp0); #ifndef NO_LEAKS cell_destroy(cp0); #endif if (cp->type < C_STRING) cast1_to_s(cp); if (string(cp)->len == 0) { /* file argument is "" */ cell_destroy(cp); continue; } /* it might be a command line assignment */ if (is_cmdline_assign(string(cp)->str)) { continue; } /* try to open it -- we used to continue on failure, but posix says we should quit */ if (!(main_fin = FINopen(string(cp)->str, 1))) { errmsg(errno, "cannot open %s", string(cp)->str); mawk_exit(2); } /* success -- set FILENAME and FNR */ cell_destroy(FILENAME); cellcpy(FILENAME, cp); cell_destroy(cp); cell_destroy(FNR); FNR->type = C_DOUBLE; FNR->dval = 0.0; rt_fnr = 0; failed = 0; break; } if (failed) { cell_destroy(&argval); if (open_flag) { /* all arguments were null or assignment */ set_main_to_stdin(); } else { main_fin = &dead_main; /* since MAIN_FLAG is not set, FINgets won't call next_main() */ } } return main_fin; }
/* * Find a file on file_list. Outputs return a FILE*, while inputs return FIN*. */ PTR file_find(STRING * sval, int type) { PTR result = 0; FILE_NODE *p; FILE_NODE *q; char *name = sval->str; TRACE(("file_find(%s, %d)\n", name, type)); for (q = 0, p = file_list; p != 0; q = p, p = p->link) { /* search is by name and type */ if (strcmp(name, p->name->str) == 0 && (p->type == type || /* no distinction between F_APPEND and F_TRUNC here */ (p->type >= F_APPEND && type >= F_APPEND))) { if (q != 0) { /* delete from list for move to front */ q->link = p->link; } break; /* while loop */ } } if (!p) { /* open a new one */ p = alloc_filenode(); switch (p->type = (short) type) { case F_TRUNC: if (!(p->ptr = (PTR) tfopen(name, BinMode2("wb", "w")))) output_failed(name); break; case F_APPEND: if (!(p->ptr = (PTR) tfopen(name, BinMode2("ab", "a")))) output_failed(name); break; case F_IN: p->ptr = (PTR) FINopen(name, 0); break; case PIPE_OUT: case PIPE_IN: #if defined(HAVE_REAL_PIPES) || defined(HAVE_FAKE_PIPES) if (!(p->ptr = get_pipe(name, type, &p->pid))) { if (type == PIPE_OUT) output_failed(name); } #else rt_error("pipes not supported"); #endif break; #ifdef DEBUG default: bozo("bad file type"); #endif } } else if (p->ptr == 0 && type == F_IN) { p->ptr = (PTR) FINopen(name, 0); } /* put p at the front of the list */ if (p->ptr == 0) { free_filenode(p); } else { if (p != file_list) { p->link = file_list; file_list = p; } /* successful open */ p->name = sval; sval->ref_cnt++; TRACE(("-> %p\n", p->ptr)); result = p->ptr; } return result; }