summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2006-06-16 23:53:26 +0000
committerKarl Berry <karl@freefriends.org>2006-06-16 23:53:26 +0000
commitf5e0b65756bd1f791c91935b0eeba0352a2d95f9 (patch)
tree73e1a79c01ec3c918ee44dc24d121cb3e8750f30
parenta70eca31896304d624bb5f9473a7a258e0d806e0 (diff)
allow pipes as input or output files; from Taco
git-svn-id: svn://tug.org/texlive/trunk@1688 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r--Build/source/texk/web2c/cpascal.h3
-rw-r--r--Build/source/texk/web2c/lib/openclose.c2
-rw-r--r--Build/source/texk/web2c/lib/texmfmp.c110
-rw-r--r--Build/source/texk/web2c/texmfmp.h19
4 files changed, 132 insertions, 2 deletions
diff --git a/Build/source/texk/web2c/cpascal.h b/Build/source/texk/web2c/cpascal.h
index f9493690d3b..efe830359dd 100644
--- a/Build/source/texk/web2c/cpascal.h
+++ b/Build/source/texk/web2c/cpascal.h
@@ -134,6 +134,7 @@ typedef FILE *text;
needs to know what path to use. Used by BibTeX, MF, TeX. */
#define aopenin(f,p) open_input (&(f), p, FOPEN_RBIN_MODE)
#define aopenout(f) open_output (&(f), FOPEN_W_MODE)
+#define aclose close_file
/* For faking arrays in tftopl. */
typedef unsigned char *pointertobyte;
@@ -266,7 +267,7 @@ extern TEXDLL void mainbody P1H(void); /* generated by web2c */
/* openclose.c */
extern boolean open_input P3H(FILE **, int, const_string fopen_mode);
extern boolean open_output P2H(FILE **, const_string fopen_mode);
-extern void aclose P1H(FILE *);
+extern void close_file P1H(FILE *);
extern void recorder_change_filename P1H(string);
extern boolean recorder_enabled;
extern string output_directory;
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. */
diff --git a/Build/source/texk/web2c/texmfmp.h b/Build/source/texk/web2c/texmfmp.h
index 45fca14d140..d000afc7cd7 100644
--- a/Build/source/texk/web2c/texmfmp.h
+++ b/Build/source/texk/web2c/texmfmp.h
@@ -89,6 +89,13 @@ extern int tfmtemp, texinputtype;
extern boolean openinnameok P1H(const_string);
extern boolean openoutnameok P1H(const_string);
+/* pdfTeX uses these for pipe support */
+#if defined(pdfTeX) || defined(pdfeTeX)
+extern boolean open_in_or_pipe P3H(FILE **, int, const_string fopen_mode);
+extern boolean open_out_or_pipe P2H(FILE **, const_string fopen_mode);
+extern void close_file_or_pipe P1H(FILE *);
+#endif
+
/* All but the Omega family use this. */
#if !defined(Omega) && !defined(eOmega) && !defined(Aleph)
extern void readtcxfile P1H(void);
@@ -171,6 +178,18 @@ extern void topenin P1H(void);
/* Set an array size from texmf.cnf. */
extern void setupboundvariable P3H(integer *, const_string, integer);
+/* These defines reroute the file i/o calls to the new pipe-enabled
+ functions in texmfmp.c*/
+
+#if defined(pdfTeX) || defined(pdfeTeX)
+#undef aopenin
+#undef aopenout
+#undef aclose
+#define aopenin(f,p) open_in_or_pipe(&(f),p,FOPEN_RBIN_MODE)
+#define aopenout(f) open_out_or_pipe(&(f),FOPEN_W_MODE)
+#define aclose(f) close_file_or_pipe(f)
+#endif
+
/* `bopenin' (and out) is used only for reading (and writing) .tfm
files; `wopenin' (and out) only for dump files. The filenames are
passed in as a global variable, `nameoffile'. */