Skip to content

Commit 457b36e

Browse files
committed
Provide replacement mkstemp(3) implementation for Windows
The replacement implementation somewhat arbitrarily fails with EEXIST after 65536 attempts. Assume mkstemp(3) is now everywhere available and use it in favor of mktemp(3). Inspired by Microsoft's _mktemp example and an implementation derived from the wcecompat library.
1 parent cfec5a8 commit 457b36e

File tree

16 files changed

+137
-194
lines changed

16 files changed

+137
-194
lines changed

CMakeLists.txt

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -337,15 +337,20 @@ if (NOT CMAKE_BUILD_TYPE)
337337
endif (NOT CMAKE_BUILD_TYPE)
338338

339339

340-
# Check for missing functions: fgetln(3) is in 4.4BSD; realpath(3) is
341-
# in 4.4BSD, POSIX.1-2001; regcomp(3) is in POSIX.1-2001,
342-
# POSIX.1-2008.
340+
# Check for missing functions: fgetln(3) is in 4.4BSD; mkstemp(3) is
341+
# in 4.3BSD, POSIX.1-2001; realpath(3) is in 4.4BSD, POSIX.1-2001;
342+
# regex(3) is in POSIX.1-2001, POSIX.1-2008.
343343
include(CheckSymbolExists)
344344
check_symbol_exists(fgetln "stdio.h" HAVE_FGETLN)
345345
if(HAVE_FGETLN)
346346
add_compile_definitions("HAVE_FGETLN")
347347
endif()
348348

349+
check_symbol_exists(mkstemp "stdlib.h" HAVE_MKSTEMP)
350+
if(HAVE_MKSTEMP)
351+
add_compile_definitions("HAVE_MKSTEMP")
352+
endif()
353+
349354
check_symbol_exists(realpath "stdlib.h" HAVE_REALPATH)
350355
if(HAVE_REALPATH)
351356
add_compile_definitions("HAVE_REALPATH")
@@ -1060,6 +1065,10 @@ add_executable(cbf2nexus
10601065
"${CBF__EXAMPLES}/cbf2nexus.c")
10611066
target_link_libraries(cbf2nexus
10621067
cbf)
1068+
if(NOT HAVE_MKSTEMP)
1069+
target_sources(cbf2nexus
1070+
PRIVATE "${CBF__SRC}/mkstemp.c")
1071+
endif()
10631072

10641073
add_executable(nexus2cbf
10651074
"${CBF__EXAMPLES}/nexus2cbf.c")
@@ -1071,6 +1080,10 @@ add_executable(minicbf2nexus
10711080
"${CBF__EXAMPLES}/minicbf2nexus.c")
10721081
target_link_libraries(minicbf2nexus
10731082
cbf)
1083+
if(NOT HAVE_MKSTEMP)
1084+
target_sources(minicbf2nexus
1085+
PRIVATE "${CBF__SRC}/mkstemp.c")
1086+
endif()
10741087

10751088
add_executable(adscimg2cbf
10761089
"${CBF__EXAMPLES}/adscimg2cbf.c"
@@ -1093,11 +1106,19 @@ add_executable(convert_image
10931106
"${CBF__EXAMPLES}/convert_image.c")
10941107
target_link_libraries(convert_image
10951108
cbf)
1109+
if(NOT HAVE_MKSTEMP)
1110+
target_sources(convert_image
1111+
PRIVATE "${CBF__SRC}/mkstemp.c")
1112+
endif()
10961113

10971114
add_executable(convert_minicbf
10981115
"${CBF__EXAMPLES}/convert_minicbf.c")
10991116
target_link_libraries(convert_minicbf
11001117
cbf)
1118+
if(NOT HAVE_MKSTEMP)
1119+
target_sources(convert_minicbf
1120+
PRIVATE "${CBF__SRC}/mkstemp.c")
1121+
endif()
11011122

11021123
add_executable(makecbf
11031124
"${CBF__EXAMPLES}/makecbf.c")
@@ -1134,13 +1155,21 @@ add_executable(img2cif
11341155
"${CBF__EXAMPLES}/img2cif.c")
11351156
target_link_libraries(img2cif
11361157
cbf)
1158+
if(NOT HAVE_MKSTEMP)
1159+
target_sources(img2cif
1160+
PRIVATE "${CBF__SRC}/mkstemp.c")
1161+
endif()
11371162

11381163
add_executable(cif2cbf
11391164
"${CBF__EXAMPLES}/cif2cbf.c")
11401165
target_link_libraries(cif2cbf
11411166
cbf
11421167
CQR
11431168
"${libm}")
1169+
if(NOT HAVE_MKSTEMP)
1170+
target_sources(cif2cbf
1171+
PRIVATE "${CBF__SRC}/mkstemp.c")
1172+
endif()
11441173

11451174
add_executable(cbf_template_t
11461175
"${CBF__DECTRIS_EXAMPLES}/cbf_template_t.c")
@@ -1161,6 +1190,10 @@ add_executable(sequence_match
11611190
"${CBF__EXAMPLES}/sequence_match.c")
11621191
target_link_libraries(sequence_match
11631192
cbf)
1193+
if(NOT HAVE_MKSTEMP)
1194+
target_sources(sequence_match
1195+
PRIVATE "${CBF__SRC}/mkstemp.c")
1196+
endif()
11641197

11651198
add_executable(test_cbf_airy_disk
11661199
"${CBF__EXAMPLES}/test_cbf_airy_disk.c")

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -731,9 +731,9 @@ endif
731731
CC = gcc
732732
C++ = g++
733733
ifneq ($(CBFDEBUG),)
734-
CFLAGS = -g -O0 -Wall -DHAVE_REALPATH -D_USE_XOPEN_EXTENDED -fno-strict-aliasing -DCBFDEBUG=1 $(HDF5CFLAGS)
734+
CFLAGS = -g -O0 -Wall -D_USE_XOPEN_EXTENDED -fno-strict-aliasing -DCBFDEBUG=1 -DHAVE_MKSTEMP -DHAVE_REALPATH $(HDF5CFLAGS)
735735
else
736-
CFLAGS = -g -O3 -Wall -DHAVE_REALPATH -D_USE_XOPEN_EXTENDED -fno-strict-aliasing $(HDF5CFLAGS)
736+
CFLAGS = -g -O3 -Wall -D_USE_XOPEN_EXTENDED -fno-strict-aliasing -DHAVE_MKSTEMP -DHAVE_REALPATH $(HDF5CFLAGS)
737737
endif
738738
LDFLAGS =
739739
F90C = gfortran

Makefile_LINUX

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ endif
730730
#########################################################
731731
CC = gcc
732732
C++ = g++
733-
CFLAGS = -g -O2 -Wall -DHAVE_REALPATH -D_USE_XOPEN_EXTENDED -fno-strict-aliasing $(HDF5CFLAGS)
733+
CFLAGS = -g -O2 -Wall -D_USE_XOPEN_EXTENDED -fno-strict-aliasing -DHAVE_MKSTEMP -DHAVE_REALPATH $(HDF5CFLAGS)
734734
LDFLAGS =
735735
F90C = gfortran
736736
#F90FLAGS = -g -fno-range-check -fallow-invalid-boz

Makefile_MSYS2

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,8 @@ endif
731731
CC = gcc
732732
C++ = g++
733733
CFLAGS = -g -O2 -Wall -D_USE_XOPEN_EXTENDED -DH5_HAVE_WIN32_API \
734-
-DH5_HAVE_MINGW -DH5_USE_110_API -fno-strict-aliasing $(HDF5CFLAGS)
734+
-DH5_HAVE_MINGW -DH5_USE_110_API -fno-strict-aliasing -DHAVE_MKSTEMP \
735+
$(HDF5CFLAGS)
735736
LDFLAGS =
736737
F90C = gfortran
737738
#F90FLAGS = -g -fno-range-check -fallow-invalid-boz

Makefile_OSX

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ endif
730730
#########################################################
731731
CC = gcc
732732
C++ = g++
733-
CFLAGS = -g -O2 -Wall -std=c99 -pedantic -DHAVE_REALPATH $(HDF5CFLAGS)
733+
CFLAGS = -g -O2 -Wall -std=c99 -pedantic -DHAVE_MKSTEMP -DHAVE_REALPATH $(HDF5CFLAGS)
734734
LDFLAGS =
735735
F90C = gfortran
736736
#F90FLAGS = -g -fno-range-check -fallow-invalid-boz

examples/cbf2nexus.c

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,10 @@
257257

258258
#define C2CBUFSIZ 8192
259259

260-
#ifdef __MINGW32__
261-
#define NOMKSTEMP
262-
#define NOTMPDIR
260+
#ifndef HAVE_MKSTEMP
261+
#define mkstemp _cbf_mkstemp
262+
int
263+
_cbf_mkstemp(char *templ);
263264
#endif
264265

265266
int local_exit (int status);
@@ -648,34 +649,20 @@ int main (int argc, char *argv [])
648649

649650
for (f = 0; CBF_SUCCESS == error && f != cifid; ++f) {
650651
cbf_handle cif = NULL;
651-
#ifdef NOTMPDIR
652-
char ciftmp[] = "cif2cbfXXXXXX";
653-
#else
654652
char ciftmp[] = "/tmp/cif2cbfXXXXXX";
655653
int ciftmpfd;
656-
#endif
657654
/* Get suitable file - reading from stdin to a temporary file if needed */
658655
if (!(cifin[f]) || strcmp(cifin[f]?cifin[f]:"","-") == 0) {
659656
FILE *file = NULL;
660657
int nbytes;
661658
char buf[C2CBUFSIZ];
662-
#ifdef NOMKSTEMP
663-
if (mktemp(ciftmp) == NULL ) {
664-
fprintf(stderr,"%s: Can't create temporary file name %s.\n%s\n", argv[0], ciftmp,strerror(errno));
665-
error |= CBF_FILEOPEN;
666-
} else if ((file = fopen(ciftmp,"wb+")) == NULL) {
667-
fprintf(stderr,"Can't open temporary file %s.\n%s\n", ciftmp,strerror(errno));
668-
error |= CBF_FILEOPEN;
669-
}
670-
#else
671659
if ((ciftmpfd = mkstemp(ciftmp)) == -1 ) {
672660
fprintf(stderr,"%s: Can't create temporary file %s.\n%s\n", argv[0], ciftmp,strerror(errno));
673661
error |= CBF_FILEOPEN;
674662
} else if ((file = fdopen(ciftmpfd, "w+")) == NULL) {
675663
fprintf(stderr,"Can't open temporary file %s.\n%s\n", ciftmp,strerror(errno));
676664
error |= CBF_FILEOPEN;
677665
}
678-
#endif
679666
while ((nbytes = fread(buf, 1, C2CBUFSIZ, stdin))) {
680667
if((size_t)nbytes != fwrite(buf, 1, nbytes, file)) {
681668
fprintf(stderr,"Failed to write %s.\n", ciftmp);

examples/cif2c.c

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -307,9 +307,10 @@
307307

308308
#define C2CBUFSIZ 8192
309309

310-
#ifdef __MINGW32__
311-
#define NOMKSTEMP
312-
#define NOTMPDIR
310+
#ifndef HAVE_MKSTEMP
311+
# define mkstemp _cbf_mkstemp
312+
int
313+
_cbf_mkstemp(char *templ);
313314
#endif
314315

315316

@@ -338,12 +339,7 @@ int main (int argc, char *argv [])
338339
int errflg = 0;
339340
const char *cifin, *codeout, *function_name;
340341
char ciftmp[19];
341-
#ifdef NOMKSTEMP
342-
char *xciftmp;
343-
#endif
344-
#ifndef NOMKSTEMP
345342
int ciftmpfd;
346-
#endif
347343
int ciftmpused;
348344
unsigned int nbytes;
349345
char buf[C2CBUFSIZ];
@@ -432,23 +428,7 @@ int main (int argc, char *argv [])
432428
/* Read the cif */
433429

434430
if (!cifin || strcmp(cifin?cifin:"","-") == 0) {
435-
#ifdef NOTMPDIR
436-
strcpy(ciftmp, "cif2cXXXXXX");
437-
#else
438431
strcpy(ciftmp, "/tmp/cif2cXXXXXX");
439-
#endif
440-
#ifdef NOMKSTEMP
441-
if ((xciftmp=mktemp(ciftmp)) == NULL ) {
442-
fprintf(stderr,"\n cif2c: Can't create temporary file name %s.\n", ciftmp);
443-
fprintf(stderr,"%s\n",strerror(errno));
444-
exit(1);
445-
}
446-
if ( (file = fopen(ciftmp,"wb+")) == NULL) {
447-
fprintf(stderr,"Can't open temporary file %s.\n", ciftmp);
448-
fprintf(stderr,"%s\n",strerror(errno));
449-
exit(1);
450-
}
451-
#else
452432
if ((ciftmpfd = mkstemp(ciftmp)) == -1 ) {
453433
fprintf(stderr,"Can't create temporary file %s.\n", ciftmp);
454434
fprintf(stderr,"%s\n",strerror(errno));
@@ -459,7 +439,6 @@ int main (int argc, char *argv [])
459439
fprintf(stderr,"%s\n",strerror(errno));
460440
exit(1);
461441
}
462-
#endif
463442
while ((nbytes = fread(buf, 1, C2CBUFSIZ, stdin))) {
464443
if(nbytes != fwrite(buf, 1, nbytes, file)) {
465444
fprintf(stderr,"Failed to write %s.\n", ciftmp);

examples/cif2cbf.c

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -503,9 +503,10 @@
503503
#define C2CBUFSIZ 8192
504504
#define NUMDICTS 50
505505

506-
#ifdef __MINGW32__
507-
#define NOMKSTEMP
508-
#define NOTMPDIR
506+
#ifndef HAVE_MKSTEMP
507+
#define mkstemp _cbf_mkstemp
508+
int
509+
_cbf_mkstemp(char *templ);
509510
#endif
510511

511512
#define HDR_FINDDIMS 0x0040 /* On read, find header dims */
@@ -824,9 +825,7 @@ int main (int argc, char *argv [])
824825
const char *dictionary[NUMDICTS];
825826
int dqrflags[NUMDICTS];
826827
char *ciftmp=NULL;
827-
#ifndef NOMKSTEMP
828828
int ciftmpfd;
829-
#endif
830829
int ciftmpused;
831830
int padflag;
832831
int dimflag;
@@ -1695,23 +1694,7 @@ int main (int argc, char *argv [])
16951694

16961695
if (!cifin || strcmp(cifin?cifin:"","-") == 0) {
16971696
ciftmp = (char *)malloc(strlen("/tmp/cif2cbfXXXXXX")+1);
1698-
#ifdef NOTMPDIR
1699-
strcpy(ciftmp, "cif2cbfXXXXXX");
1700-
#else
17011697
strcpy(ciftmp, "/tmp/cif2cbfXXXXXX");
1702-
#endif
1703-
#ifdef NOMKSTEMP
1704-
if ((ciftmp = mktemp(ciftmp)) == NULL ) {
1705-
fprintf(stderr,"\n cif2cbf: Can't create temporary file name %s.\n", ciftmp);
1706-
fprintf(stderr,"%s\n",strerror(errno));
1707-
exit(1);
1708-
}
1709-
if ( (file = fopen(ciftmp,"wb+")) == NULL) {
1710-
fprintf(stderr,"Can't open temporary file %s.\n", ciftmp);
1711-
fprintf(stderr,"%s\n",strerror(errno));
1712-
exit(1);
1713-
}
1714-
#else
17151698
if ((ciftmpfd = mkstemp(ciftmp)) == -1 ) {
17161699
fprintf(stderr,"\n cif2cbf: Can't create temporary file %s.\n", ciftmp);
17171700
fprintf(stderr,"%s\n",strerror(errno));
@@ -1722,7 +1705,6 @@ int main (int argc, char *argv [])
17221705
fprintf(stderr,"%s\n",strerror(errno));
17231706
exit(1);
17241707
}
1725-
#endif
17261708
while ((nbytes = fread(buf, 1, C2CBUFSIZ, stdin))) {
17271709
if(nbytes != fwrite(buf, 1, nbytes, file)) {
17281710
fprintf(stderr,"Failed to write %s.\n", ciftmp);

examples/convert_image.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,11 @@
307307
#include "cbf_getopt.h"
308308
#include <unistd.h>
309309

310+
#ifndef HAVE_MKSTEMP
311+
# define mkstemp _cbf_mkstemp
312+
int
313+
_cbf_mkstemp(char *templ);
314+
#endif
310315

311316

312317
double rint(double);
@@ -524,7 +529,7 @@ int main (int argc, char *argv [])
524529
int copt;
525530
int errflg = 0;
526531
char * imgtmp=NULL;
527-
int imgtmpused = 0;
532+
int imgtmpfd = -1;
528533
const char *imgin, *cbfout, *template, *distancestr, *alias;
529534
cbf_detector detector;
530535
char *tag, *data, *root;
@@ -669,12 +674,13 @@ int main (int argc, char *argv [])
669674
if (!imgin || strcmp(imgin?imgin:"","-") == 0) {
670675
imgtmp = (char *)malloc(strlen("/tmp/cvt_imgXXXXXX")+1);
671676
strcpy(imgtmp, "/tmp/cvt_imgXXXXXX");
672-
if ((imgin = mktemp(imgtmp)) == NULL ) {
677+
if ((imgtmpfd = mkstemp(imgtmp)) == -1 ) {
673678
fprintf(stderr,"\n convert_image: Can't create temporary file name %s.\n", imgtmp);
674679
fprintf(stderr,"%s\n",strerror(errno));
675680
exit(1);
676681
}
677-
imgtmpused = 1;
682+
close(imgtmpfd);
683+
imgin = imgtmp;
678684
}
679685

680686
/* Read the image */
@@ -683,7 +689,7 @@ int main (int argc, char *argv [])
683689

684690
cbf_failnez (img_read (img, imgin))
685691

686-
if (imgtmpused)
692+
if (imgtmpfd != -1)
687693
{
688694
if (unlink(imgtmp) != 0 ) {
689695
fprintf(stderr," convert_image: Can't unlink temporary file %s.\n", imgtmp);

0 commit comments

Comments
 (0)