diff options
author | Karl Berry <karl@freefriends.org> | 2006-06-16 23:53:26 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2006-06-16 23:53:26 +0000 |
commit | f5e0b65756bd1f791c91935b0eeba0352a2d95f9 (patch) | |
tree | 73e1a79c01ec3c918ee44dc24d121cb3e8750f30 /Build/source/texk/web2c/lib | |
parent | a70eca31896304d624bb5f9473a7a258e0d806e0 (diff) |
allow pipes as input or output files; from Taco
git-svn-id: svn://tug.org/texlive/trunk@1688 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/lib')
-rw-r--r-- | Build/source/texk/web2c/lib/openclose.c | 2 | ||||
-rw-r--r-- | Build/source/texk/web2c/lib/texmfmp.c | 110 |
2 files changed, 111 insertions, 1 deletions
diff --git a/Build/source/texk/web2c/lib/openclose.c b/Build/source/texk/web2c/lib/openclose.c index 6e542d247fa..a4ac21495b8 100644 --- a/Build/source/texk/web2c/lib/openclose.c +++ b/Build/source/texk/web2c/lib/openclose.c @@ -234,7 +234,7 @@ open_output P2C(FILE **, f_ptr, const_string, fopen_mode) /* Close F. */ void -aclose P1C(FILE *, f) +close_file P1C(FILE *, f) { /* If F is null, just return. bad_pool might close a file that has never been opened. */ diff --git a/Build/source/texk/web2c/lib/texmfmp.c b/Build/source/texk/web2c/lib/texmfmp.c index ff69d12df4f..d876e075170 100644 --- a/Build/source/texk/web2c/lib/texmfmp.c +++ b/Build/source/texk/web2c/lib/texmfmp.c @@ -1192,6 +1192,116 @@ boolean openoutnameok P1C(const_string, fname) /* For output, default to paranoid. */ return opennameok (fname, "openout_any", "p", ok_writing); } +/* + piped I/O + */ + +/* The code that implements popen() needs an array for tracking + possible pipe file pointers, because these need to be + closed using pclose(). +*/ + +#if defined(pdfTeX) || defined(pdfeTeX) + +static FILE *pipes [] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; + +boolean +open_in_or_pipe P3C(FILE **, f_ptr, int, filefmt, const_string, fopen_mode) +{ + string fname = NULL; + int i; /* iterator */ + + /* opening a read pipe is straightforward, only have to + skip past the pipe symbol in the file name. filename + quoting is assumed to happen elsewhere (it does :-)) */ + + if (shellenabledp && *(nameoffile+1) == '|') { + /* the user requested a pipe */ + *f_ptr = NULL; + fname = (string)xmalloc(strlen(nameoffile+1)); + strcpy(fname,nameoffile+1); + *f_ptr = popen(fname+1,"r"); + free(fname); + for (i=0; i<=15; i++) { + if (pipes[i]==NULL) { + pipes[i] = *f_ptr; + break; + } + } + if (*f_ptr) + setvbuf (*f_ptr,(char *)NULL,_IOLBF,0); + + return *f_ptr != NULL; + } + + return open_input(f_ptr,filefmt,fopen_mode) ; +} + + +boolean +open_out_or_pipe P2C(FILE **, f_ptr, const_string, fopen_mode) +{ + string fname; + int i; /* iterator */ + + /* opening a write pipe takes a little bit more work, because TeX + will perhaps have appended ".tex". To avoid user confusion as + much as possible, this extension is stripped only when the command + is a bare word. Some small string trickery is needed to make + sure the correct number of bytes is free()-d afterwards */ + + if (shellenabledp && *(nameoffile+1) == '|') { + /* the user requested a pipe */ + fname = (string)xmalloc(strlen(nameoffile+1)); + strcpy(fname,nameoffile+1); + if (strchr (fname,' ')==NULL && strchr(fname,'>')==NULL) { + /* mp and mf currently do not use this code, but it + is better to be prepared */ + if (STREQ((fname+strlen(fname)-3),"tex")) + *(fname+strlen(fname)-4) = 0; + *f_ptr = popen(fname+1,"w"); + *(fname+strlen(fname)) = '.'; + } else { + *f_ptr = popen(fname+1,"w"); + } + free(fname); + + for (i=0; i<=15; i++) { + if (pipes[i]==NULL) { + pipes[i] = *f_ptr; + break; + } + } + + if (*f_ptr) + setvbuf(*f_ptr,(char *)NULL,_IOLBF,0); + + return *f_ptr != NULL; + } + + return open_output(f_ptr,fopen_mode); +} + + +void +close_file_or_pipe P1C(FILE *, f) +{ + int i; /* iterator */ + + if (shellenabledp) { + /* if this file was a pipe, pclose() it and return */ + for (i=0; i<=15; i++) { + if (pipes[i] == f) { + pclose (f); + pipes[i] = NULL; + return; + } + } + } + close_file(f); +} +#endif /* All our interrupt handler has to do is set TeX's or Metafont's global variable `interrupt'; then they will do everything needed. */ |