--- dvi.c.orig 2012-07-31 18:22:25.000000000 -0500 +++ dvi.c 2012-07-31 18:20:13.000000000 -0500 @@ -39,9 +39,14 @@ # define SLEEP sleep(1) # endif /* WIN32 */ #endif /* MIKTEX */ +#include #include +#include bool followmode=0; +char temp_filename[32]; +FILE *pipe_fp = NULL; +unsigned char pipe_buffer[512]; bool DVIFollowToggle(void) { @@ -51,9 +56,35 @@ static unsigned char fgetc_follow(FILE* fp) { int got=fgetc(fp); + int count, pos, flags; + unsigned char onebyte; while(followmode && got==EOF) { - SLEEP; + clearerr(fp); + if ( pipe_fp ) { + /* Remember the current end-of-file position. */ + pos = ftell(fp); + /* This first fread blocks until data is available. + If it returns 0 the pipe has been closed.*/ + count = fread(&onebyte, 1, 1, pipe_fp); + if (count == 0) + Fatal("DVI file ends prematurely"); + else + fwrite(&onebyte, 1, 1, fp); + /* Now unblock the pipe and drain it out. */ + flags = fcntl(fileno(pipe_fp), F_GETFL); + fcntl(fileno(pipe_fp), F_SETFL, O_NONBLOCK); + for (count=512; count == 512; ) { + count = fread(pipe_buffer, 1, 512, pipe_fp); + if ( count > 0 ) + fwrite(pipe_buffer, 1, count, fp); + } + fcntl(fileno(pipe_fp), F_SETFL, flags & ~O_NONBLOCK); + /* Reset the file pointer. */ + fseek(fp, pos, SEEK_SET); + } + else + SLEEP; got=fgetc(fp); } if (got==EOF) @@ -165,6 +196,20 @@ exit (EXIT_FAILURE); } DEBUG_PRINT(DEBUG_DVI,("OPEN FILE\t%s", dvi->name)); + + { + /* Check if our dvi file is a fifo. If so, open a temporary + buffer file and remember the fifo. */ + struct stat dvi_stat; + fstat(fileno(dvi->filep), &dvi_stat); + if ( dvi_stat.st_mode & S_IFIFO ) { + Message(BE_NONQUIET,"Reading from fifo %s.\n", dvi->name); + pipe_fp = dvi->filep; + strcpy(temp_filename, "/tmp/tmp_dvipngXXXXXX"); + dvi->filep = fdopen(mkstemp(temp_filename), "rb+"); + } + } + DVIInit(dvi); return(dvi); }