/* open a compressed file, filtering it thru zcat.
(and changed name to copen(), to protect the innocent.)
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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
extern FILE *fdopen();
#define READ 0
#define WRITE 1
{
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;
}
.