/* open a compressed file, filtering it thru zcat. 18 Jan 1990 tps@chem.ucsd.edu (Tom Stockfisch) posted to comp.sys.sgi 13 Jan 1993 added mode argument. Eric Grosse (and changed name to copen(), to protect the innocent.) 26 Nov 1993 (ehg) added -f; provided for gzip; converted to POSIX 16 Mar 1995 (ehg) gzcat name 2 May 2000 (rsc) posix include fixes */ /* #define COMPRESS execlp("compress", "compress","-f",0) #define UNCOMPRESS execlp("zcat", "zcat",name,0) /**/ #define COMPRESS execlp("gzip","gzip","-f",0) #define UNCOMPRESS execlp("gzcat","gzcat",name,0) /**/ #define _POSIX_SOURCE #include #include #include #include #include #include extern FILE *fdopen(); #define READ 0 #define WRITE 1 static void defaultErrHndlr(char *diagnostic) { fprintf( stderr, "copen(): %s\n", diagnostic ); exit(1); } void (*zopenErrHndlr)(char *) = defaultErrHndlr; FILE * zopen(char *name) { FILE *stream; int piped[2]; if ( pipe(piped) == -1 ) (*zopenErrHndlr)( "pipe failure\n" ); switch ( fork() ) { case -1: (*zopenErrHndlr)( "fork failure\n" ); case 0: /* child */ close( piped[READ] ); close(1); if ( dup( piped[WRITE] ) != 1 ) (*zopenErrHndlr)( "dup screwup\n" ); close( piped[WRITE] ); UNCOMPRESS; (*zopenErrHndlr)( "cannot start uncompression" ); default: /* parent */ close( piped[WRITE] ); stream = fdopen( piped[READ], "r" ); if (stream == NULL) (*zopenErrHndlr)( "cannot open pipe\n" ); break; } return stream; } FILE * copen(char *name, char *mode) { FILE *stream; int piped[2], out; if(strcmp(mode,"r")==0) return zopen(name); if(strcmp(mode,"w")!=0) (*zopenErrHndlr)( "mode must be r or w\n" ); if ( pipe(piped) == -1 ) (*zopenErrHndlr)( "pipe failure\n" ); switch ( fork() ) { case -1: (*zopenErrHndlr)( "fork failure\n" ); case 0: /* child */ close( piped[WRITE] ); close(0); if ( dup( piped[READ] ) != 0 ) (*zopenErrHndlr)( "dup screwup\n" ); close( piped[READ] ); close(1); out = creat(name,0666); if ( out < 0 ) (*zopenErrHndlr)( "can't create file\n" ); if ( out != 1 ) (*zopenErrHndlr)( "expected fd=1\n" ); COMPRESS; (*zopenErrHndlr)( "cannot start compression" ); default: /* parent */ close( piped[READ] ); stream = fdopen( piped[WRITE], "w" ); if (stream == NULL) (*zopenErrHndlr)( "cannot open pipe\n" ); break; } return stream; }