This patch causes libjpeg to open all files with O_CLOEXEC the "e" fopen mode is a glibc/linux specific feature hence not suitable for other OS. Note that it is NOT HANDLED GRACEFULLY on kernels older than 2.6.23 or glibc < 2.7.x and WILL segfault. The other alternative, using fcntl with FD_CLOEXEC is NOT enough to prevent race conditions. --- wrjpgcom.c.orig +++ wrjpgcom.c @@ -35,15 +35,15 @@ extern void * malloc (); #endif #ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */ -#define READ_BINARY "r" -#define WRITE_BINARY "w" +#define READ_BINARY "re" +#define WRITE_BINARY "we" #else #ifdef VMS /* VMS is very nonstandard */ #define READ_BINARY "rb", "ctx=stm" #define WRITE_BINARY "wb", "ctx=stm" #else /* standard ANSI-compliant case */ -#define READ_BINARY "rb" -#define WRITE_BINARY "wb" +#define READ_BINARY "rbe" +#define WRITE_BINARY "wbe" #endif #endif @@ -439,7 +439,7 @@ main (int argc, char **argv) keep_COM = 0; } else if (keymatch(arg, "cfile", 2)) { if (++argn >= argc) usage(); - if ((comment_file = fopen(argv[argn], "r")) == NULL) { + if ((comment_file = fopen(argv[argn], READ_BINARY)) == NULL) { fprintf(stderr, "%s: can't open %s\n", progname, argv[argn]); exit(EXIT_FAILURE); } --- cdjpeg.h.orig +++ cdjpeg.h @@ -156,15 +156,15 @@ EXTERN(FILE *) write_stdout JPP((void)); /* miscellaneous useful macros */ #ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */ -#define READ_BINARY "r" -#define WRITE_BINARY "w" +#define READ_BINARY "re" +#define WRITE_BINARY "we" #else #ifdef VMS /* VMS is very nonstandard */ #define READ_BINARY "rb", "ctx=stm" #define WRITE_BINARY "wb", "ctx=stm" #else /* standard ANSI-compliant case */ -#define READ_BINARY "rb" -#define WRITE_BINARY "wb" +#define READ_BINARY "rbe" +#define WRITE_BINARY "wbe" #endif #endif --- rdswitch.c.orig +++ rdswitch.c @@ -92,7 +92,7 @@ read_quant_tables (j_compress_ptr cinfo, long val; unsigned int table[DCTSIZE2]; - if ((fp = fopen(filename, "r")) == NULL) { + if ((fp = fopen(filename, READ_BINARY)) == NULL) { fprintf(stderr, "Can't open table file %s\n", filename); return FALSE; } @@ -190,7 +190,7 @@ read_scan_script (j_compress_ptr cinfo, #define MAX_SCANS 100 /* quite arbitrary limit */ jpeg_scan_info scans[MAX_SCANS]; - if ((fp = fopen(filename, "r")) == NULL) { + if ((fp = fopen(filename, READ_BINARY)) == NULL) { fprintf(stderr, "Can't open scan definition file %s\n", filename); return FALSE; } --- bmp.c.orig +++ bmp.c @@ -112,7 +112,7 @@ int loadbmp(char *filename, unsigned cha if(!filename || !buf || !w || !h || dstpf<0 || dstpf>=TJ_NUMPF) _throw("loadbmp(): Invalid argument"); - if((file=fopen(filename, "rb"))==NULL) + if((file=fopen(filename, READ_BINARY))==NULL) _throwunix("loadbmp(): Cannot open input file"); cinfo.err=jpeg_std_error(&jerr.pub); @@ -196,7 +196,7 @@ int savebmp(char *filename, unsigned cha if(!filename || !buf || w<1 || h<1 || srcpf<0 || srcpf>=TJ_NUMPF) _throw("savebmp(): Invalid argument"); - if((file=fopen(filename, "wb"))==NULL) + if((file=fopen(filename, WRITE_BINARY))==NULL) _throwunix("savebmp(): Cannot open output file"); dinfo.err=jpeg_std_error(&jerr.pub);