/* BKG_DELFILES -- Called when a background job is spawned to make sure there * are no dreg query service files lying about from a prior job which did not * complete normally. */ void bkg_delfiles (int job) { char bkg_query_file[SZ_PATHNAME]; char query_response_file[SZ_PATHNAME]; get_bkgqfiles (job, c_getpid(), bkg_query_file, query_response_file); c_delete (bkg_query_file); c_delete (query_response_file); }
/* CLSYSTEM -- Run a host system command and try to arrange for its standard * output and standard error output to go where our t_stdout is going; this * will let us redirect its output and use it with pipes.. */ void clsystem ( char *cmd, /* command to be executed */ FILE *taskout, /* stdout of task */ FILE *taskerr /* stderr of task */ ) { register char *ip; register int ch; char outfile[SZ_PATHNAME], errfile[SZ_PATHNAME]; FILE *fp; /* Ignore null commands. */ for (ip=cmd; (*ip == ' ' || *ip == '\t'); ip++) ; if (*ip == EOS) return; /* Run command with output redirected into temporary files. * This is done only if the output is redirected. */ outfile[0] = EOS; errfile[0] = EOS; if (taskout && taskout != stdout) c_mktemp ("tmp$tso", outfile, SZ_PATHNAME); if (taskerr == taskout) strcpy (errfile, outfile); else if (taskerr && taskerr != stderr) c_mktemp ("tmp$tse", errfile, SZ_PATHNAME); c_oscmd (cmd, "", outfile, errfile); /* Copy spooled output, if any, to the error streams of the current * task. */ if (outfile[0] != EOS) if ((fp = fopen (outfile, "r")) != NULL) { while ((ch = fgetc (fp)) != EOF) fputc (ch, taskout); fclose (fp); c_delete (outfile); } if (errfile[0] != EOS && taskerr != taskout) if ((fp = fopen (errfile, "r")) != NULL) { while ((ch = fgetc (fp)) != EOF) fputc (ch, taskerr); fclose (fp); c_delete (errfile); } }
/* DELPIPES -- Delete N pipefiles (the actual file may not have been created * yet), and pop N pipes off the pipe stack. If N is zero, all pipefiles are * deleted and the pipestack is cleared (i.e., during error recovery). */ void delpipes (register int npipes) { register int pipe; char *pipefile(); if (npipes == 0) { while (nextpipe > 0) c_delete (pipefile (pipetable[--nextpipe])); } else { while (npipes-- > 0) { if ((pipe = --nextpipe) < 0) cl_error (E_IERR, "Pipestack underflow"); c_delete (pipefile (pipetable[pipe])); } } }
void stack_pop_frame(mvc *sql) { while(!sql->vars[--sql->topvars].frame) { sql_var *v = &sql->vars[sql->topvars]; c_delete(v->name); VALclear(&v->value); v->value.vtype = 0; if (v->t && v->view) table_destroy(v->t); else if (v->rel) rel_destroy(v->rel); } if (sql->topvars && sql->vars[sql->topvars].name) c_delete(sql->vars[sql->topvars].name); sql->frame--; }
void stack_pop_until(mvc *sql, int top) { while(sql->topvars > top) { sql_var *v = &sql->vars[--sql->topvars]; c_delete(v->name); VALclear(&v->value); v->value.vtype = 0; } }
/* WBKGFILE -- Create a unique file, write and close the background file. * Jobno is the job number the new cl is to think its running for. * We don't use the global bkgno because that's OUR number, if we ourselves * are background. * Return pointer to the new name. * No error return, but we may call error() and never return. */ char * wbkgfile ( int jobno, /* ordinal jobnumber of child */ char *cmd, /* command to be run in bkg */ char *fname /* filename for env file */ ) { static char *bkgwerr = "error writing background job file"; static char bkgfile[SZ_PATHNAME]; struct bkgfilehdr bh; int n, show_redefs=NO; FILE *fp; /* If we're a normal background job no name was specified so * create a unique uparm file. Otherwise, use the specified * filename (e.g. for special onerr handling). */ if (fname == (char *)NULL) c_mktemp ("uparm$bkg", bkgfile, SZ_PATHNAME); else { if (c_access (fname,0,0) == YES) c_delete (fname); strncpy (bkgfile, fname, strlen(fname)); } /* Open the file. */ if ((fp = fopen (bkgfile, "wb")) == NULL) cl_error (E_IERR, "unable to create background job file `%s'", bkgfile); for (n=0; n < MAXPIPES; n++) bh.b_pipetable[n] = pipetable[n]; bh.b_nextpipe = nextpipe; strncpy (bh.b_cmd, cmd, SZ_BKCMD); bh.b_magic = BKG_MAGIC; bh.b_bkgno = jobno; bh.b_ppid = c_getpid(); bh.b_szstack = STACKSIZ * BPI; bh.b_szdict = topd * BPI; bh.b_dict = dictionary; bh.b_topd = topd; bh.b_maxd = maxd; bh.b_parhead = parhead; bh.b_pachead = pachead; bh.b_pc = pc; bh.b_topos = topos; bh.b_basos = basos; bh.b_topcs = topcs; bh.b_firstask = firstask; bh.b_currentask = currentask; bh.b_curpack = curpack; /* Write the header structure, followed by the stack area and the * dictionary. */ if (fwrite ((char *)&bh, BKGHDRSIZ, 1, fp) == NULL) cl_error (E_IERR|E_P, bkgwerr); if (fwrite ((char *)stack, STACKSIZ, BPI, fp) == NULL) cl_error (E_IERR|E_P, bkgwerr); if (fwrite ((char *)dictionary, topd, BPI, fp) == NULL) cl_error (E_IERR|E_P, bkgwerr); /* Write the environment as a sequence of SET statements in binary. * Append a blank line as a terminator. */ c_envlist (fileno(fp), "set ", show_redefs); fputs ("\n", fp); fclose (fp); return (bkgfile); }
/* BKG_SPAWN -- Spawn a new background job. Called by main() when we have * seen an '&'. */ void bkg_spawn ( char *cmd /* command entered by user to spawn job */ ) { register struct _bkgjob *bk; register int jobno, stat; char clprocess[SZ_PATHNAME]; char *wbkgfile(); char *bkgfile; /* Find first unused slot in a circular search. */ bkg_update (1); jobno = (lastjobno == NBKG) ? 1 : lastjobno + 1; while (jobno != lastjobno) { if (!busy (jobno)) break; if (jobno++ >= NBKG) jobno = 1; } if (jobno == lastjobno) cl_error (E_UERR, "no more background job slots"); /* Write bkgfile. Delete any dreg bkg communication files. */ bkg_delfiles (jobno); bkgfile = wbkgfile (jobno, cmd, NULL); /* Spawn bkg job. */ sprintf (clprocess, "%s%s", CLDIR, CLPROCESS); intr_disable(); jobtable[jobno-1].b_jobno = stat = c_propdpr (findexe (firstask->t_curpack, clprocess), bkgfile, bkgmsg); if (stat == NULL) { c_delete (bkgfile); intr_enable(); cl_error (E_IERR, "cannot spawn background CL"); } else { bk = &jobtable[jobno-1]; bk->b_flags = J_RUNNING; bk->b_clock = c_clktime (0L); bk->b_verbose = 2; strncpy (bk->b_cmd, cmd, SZ_CMD); *(bk->b_cmd+SZ_CMD) = EOS; intr_enable(); } eprintf ("[%d]\n", lastjobno = jobno); /* Make a logfile entry, saying we started the background job. */ if (keeplog() && log_background()) { char buf[SZ_LINE]; sprintf (buf, "Start [%d]", jobno); putlog (0, buf); } }