Skip to content

Commit 64c25ec

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 2cb404e commit 64c25ec

File tree

16 files changed

+133
-194
lines changed

16 files changed

+133
-194
lines changed

CMakeLists.txt

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -345,15 +345,20 @@ if(HAVE_UNISTD_H)
345345
endif()
346346

347347

348-
# Check for missing functions: fgetln(3) is in 4.4BSD; realpath(3) is
349-
# in 4.4BSD, POSIX.1-2001; regcomp(3) is in POSIX.1-2001,
350-
# POSIX.1-2008.
348+
# Check for missing functions: fgetln(3) is in 4.4BSD; mkstemp(3) is
349+
# in 4.3BSD, POSIX.1-2001; realpath(3) is in 4.4BSD, POSIX.1-2001;
350+
# regex(3) is in POSIX.1-2001, POSIX.1-2008.
351351
include(CheckSymbolExists)
352352
check_symbol_exists(fgetln "stdio.h" HAVE_FGETLN)
353353
if(HAVE_FGETLN)
354354
add_compile_definitions("HAVE_FGETLN")
355355
endif()
356356

357+
check_symbol_exists(mkstemp "stdlib.h" HAVE_MKSTEMP)
358+
if(HAVE_MKSTEMP)
359+
add_compile_definitions("HAVE_MKSTEMP")
360+
endif()
361+
357362
check_symbol_exists(realpath "stdlib.h" HAVE_REALPATH)
358363
if(HAVE_REALPATH)
359364
add_compile_definitions("HAVE_REALPATH")
@@ -1116,6 +1121,10 @@ add_executable(cbf2nexus
11161121
"${CBF__EXAMPLES}/cbf2nexus.c")
11171122
target_link_libraries(cbf2nexus
11181123
cbf)
1124+
if(NOT HAVE_MKSTEMP)
1125+
target_sources(cbf2nexus
1126+
PRIVATE "${CBF__SRC}/mkstemp.c")
1127+
endif()
11191128

11201129
add_executable(nexus2cbf
11211130
"${CBF__EXAMPLES}/nexus2cbf.c")
@@ -1127,6 +1136,10 @@ add_executable(minicbf2nexus
11271136
"${CBF__EXAMPLES}/minicbf2nexus.c")
11281137
target_link_libraries(minicbf2nexus
11291138
cbf)
1139+
if(NOT HAVE_MKSTEMP)
1140+
target_sources(minicbf2nexus
1141+
PRIVATE "${CBF__SRC}/mkstemp.c")
1142+
endif()
11301143

11311144
add_executable(adscimg2cbf
11321145
"${CBF__EXAMPLES}/adscimg2cbf.c"
@@ -1149,11 +1162,19 @@ add_executable(convert_image
11491162
"${CBF__EXAMPLES}/convert_image.c")
11501163
target_link_libraries(convert_image
11511164
cbf)
1165+
if(NOT HAVE_MKSTEMP)
1166+
target_sources(convert_image
1167+
PRIVATE "${CBF__SRC}/mkstemp.c")
1168+
endif()
11521169

11531170
add_executable(convert_minicbf
11541171
"${CBF__EXAMPLES}/convert_minicbf.c")
11551172
target_link_libraries(convert_minicbf
11561173
cbf)
1174+
if(NOT HAVE_MKSTEMP)
1175+
target_sources(convert_minicbf
1176+
PRIVATE "${CBF__SRC}/mkstemp.c")
1177+
endif()
11571178

11581179
add_executable(makecbf
11591180
"${CBF__EXAMPLES}/makecbf.c")
@@ -1190,13 +1211,21 @@ add_executable(img2cif
11901211
"${CBF__EXAMPLES}/img2cif.c")
11911212
target_link_libraries(img2cif
11921213
cbf)
1214+
if(NOT HAVE_MKSTEMP)
1215+
target_sources(img2cif
1216+
PRIVATE "${CBF__SRC}/mkstemp.c")
1217+
endif()
11931218

11941219
add_executable(cif2cbf
11951220
"${CBF__EXAMPLES}/cif2cbf.c")
11961221
target_link_libraries(cif2cbf
11971222
cbf
11981223
CQR
11991224
"${libm}")
1225+
if(NOT HAVE_MKSTEMP)
1226+
target_sources(cif2cbf
1227+
PRIVATE "${CBF__SRC}/mkstemp.c")
1228+
endif()
12001229

12011230
add_executable(cbf_template_t
12021231
"${CBF__DECTRIS_EXAMPLES}/cbf_template_t.c")
@@ -1224,6 +1253,10 @@ add_executable(sequence_match
12241253
"${CBF__EXAMPLES}/sequence_match.c")
12251254
target_link_libraries(sequence_match
12261255
cbf)
1256+
if(NOT HAVE_MKSTEMP)
1257+
target_sources(sequence_match
1258+
PRIVATE "${CBF__SRC}/mkstemp.c")
1259+
endif()
12271260

12281261
add_executable(test_cbf_airy_disk
12291262
"${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 -D_USE_XOPEN_EXTENDED -fno-strict-aliasing -DHAVE_REALPATH -DCBFDEBUG=1 -DHAVE_UNISTD_H $(HDF5CFLAGS)
734+
CFLAGS = -g -O0 -Wall -D_USE_XOPEN_EXTENDED -fno-strict-aliasing -DCBFDEBUG=1 -DHAVE_MKSTEMP -DHAVE_REALPATH -DHAVE_UNISTD_H $(HDF5CFLAGS)
735735
else
736-
CFLAGS = -g -O3 -Wall -D_USE_XOPEN_EXTENDED -fno-strict-aliasing -DHAVE_REALPATH -DHAVE_UNISTD_H $(HDF5CFLAGS)
736+
CFLAGS = -g -O3 -Wall -D_USE_XOPEN_EXTENDED -fno-strict-aliasing -DHAVE_MKSTEMP -DHAVE_REALPATH -DHAVE_UNISTD_H $(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 -D_USE_XOPEN_EXTENDED -fno-strict-aliasing -DHAVE_REALPATH -DHAVE_UNISTD_H $(HDF5CFLAGS)
733+
CFLAGS = -g -O2 -Wall -D_USE_XOPEN_EXTENDED -fno-strict-aliasing -DHAVE_MKSTEMP -DHAVE_REALPATH -DHAVE_UNISTD_H $(HDF5CFLAGS)
734734
LDFLAGS =
735735
F90C = gfortran
736736
#F90FLAGS = -g -fno-range-check -fallow-invalid-boz

Makefile_MSYS2

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -731,8 +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 -DHAVE_UNISTD_H \
735-
$(HDF5CFLAGS)
734+
-DH5_HAVE_MINGW -DH5_USE_110_API -fno-strict-aliasing -DHAVE_MKSTEMP \
735+
-DHAVE_UNISTD_H $(HDF5CFLAGS)
736736
LDFLAGS =
737737
F90C = gfortran
738738
#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 -DHAVE_UNISTD_H $(HDF5CFLAGS)
733+
CFLAGS = -g -O2 -Wall -std=c99 -pedantic -DHAVE_MKSTEMP -DHAVE_REALPATH -DHAVE_UNISTD_H $(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
@@ -259,9 +259,10 @@
259259

260260
#define C2CBUFSIZ 8192
261261

262-
#ifdef __MINGW32__
263-
#define NOMKSTEMP
264-
#define NOTMPDIR
262+
#ifndef HAVE_MKSTEMP
263+
#define mkstemp _cbf_mkstemp
264+
int
265+
_cbf_mkstemp(char *templ);
265266
#endif
266267

267268
int local_exit (int status);
@@ -650,34 +651,20 @@ int main (int argc, char *argv [])
650651

651652
for (f = 0; CBF_SUCCESS == error && f != cifid; ++f) {
652653
cbf_handle cif = NULL;
653-
#ifdef NOTMPDIR
654-
char ciftmp[] = "cif2cbfXXXXXX";
655-
#else
656654
char ciftmp[] = "/tmp/cif2cbfXXXXXX";
657655
int ciftmpfd;
658-
#endif
659656
/* Get suitable file - reading from stdin to a temporary file if needed */
660657
if (!(cifin[f]) || strcmp(cifin[f]?cifin[f]:"","-") == 0) {
661658
FILE *file = NULL;
662659
int nbytes;
663660
char buf[C2CBUFSIZ];
664-
#ifdef NOMKSTEMP
665-
if (mktemp(ciftmp) == NULL ) {
666-
fprintf(stderr,"%s: Can't create temporary file name %s.\n%s\n", argv[0], ciftmp,strerror(errno));
667-
error |= CBF_FILEOPEN;
668-
} else if ((file = fopen(ciftmp,"wb+")) == NULL) {
669-
fprintf(stderr,"Can't open temporary file %s.\n%s\n", ciftmp,strerror(errno));
670-
error |= CBF_FILEOPEN;
671-
}
672-
#else
673661
if ((ciftmpfd = mkstemp(ciftmp)) == -1 ) {
674662
fprintf(stderr,"%s: Can't create temporary file %s.\n%s\n", argv[0], ciftmp,strerror(errno));
675663
error |= CBF_FILEOPEN;
676664
} else if ((file = fdopen(ciftmpfd, "w+")) == NULL) {
677665
fprintf(stderr,"Can't open temporary file %s.\n%s\n", ciftmp,strerror(errno));
678666
error |= CBF_FILEOPEN;
679667
}
680-
#endif
681668
while ((nbytes = fread(buf, 1, C2CBUFSIZ, stdin))) {
682669
if((size_t)nbytes != fwrite(buf, 1, nbytes, file)) {
683670
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
@@ -309,9 +309,10 @@
309309

310310
#define C2CBUFSIZ 8192
311311

312-
#ifdef __MINGW32__
313-
#define NOMKSTEMP
314-
#define NOTMPDIR
312+
#ifndef HAVE_MKSTEMP
313+
# define mkstemp _cbf_mkstemp
314+
int
315+
_cbf_mkstemp(char *templ);
315316
#endif
316317

317318

@@ -340,12 +341,7 @@ int main (int argc, char *argv [])
340341
int errflg = 0;
341342
const char *cifin, *codeout, *function_name;
342343
char ciftmp[19];
343-
#ifdef NOMKSTEMP
344-
char *xciftmp;
345-
#endif
346-
#ifndef NOMKSTEMP
347344
int ciftmpfd;
348-
#endif
349345
int ciftmpused;
350346
unsigned int nbytes;
351347
char buf[C2CBUFSIZ];
@@ -434,23 +430,7 @@ int main (int argc, char *argv [])
434430
/* Read the cif */
435431

436432
if (!cifin || strcmp(cifin?cifin:"","-") == 0) {
437-
#ifdef NOTMPDIR
438-
strcpy(ciftmp, "cif2cXXXXXX");
439-
#else
440433
strcpy(ciftmp, "/tmp/cif2cXXXXXX");
441-
#endif
442-
#ifdef NOMKSTEMP
443-
if ((xciftmp=mktemp(ciftmp)) == NULL ) {
444-
fprintf(stderr,"\n cif2c: Can't create temporary file name %s.\n", ciftmp);
445-
fprintf(stderr,"%s\n",strerror(errno));
446-
exit(1);
447-
}
448-
if ( (file = fopen(ciftmp,"wb+")) == NULL) {
449-
fprintf(stderr,"Can't open temporary file %s.\n", ciftmp);
450-
fprintf(stderr,"%s\n",strerror(errno));
451-
exit(1);
452-
}
453-
#else
454434
if ((ciftmpfd = mkstemp(ciftmp)) == -1 ) {
455435
fprintf(stderr,"Can't create temporary file %s.\n", ciftmp);
456436
fprintf(stderr,"%s\n",strerror(errno));
@@ -461,7 +441,6 @@ int main (int argc, char *argv [])
461441
fprintf(stderr,"%s\n",strerror(errno));
462442
exit(1);
463443
}
464-
#endif
465444
while ((nbytes = fread(buf, 1, C2CBUFSIZ, stdin))) {
466445
if(nbytes != fwrite(buf, 1, nbytes, file)) {
467446
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
@@ -505,9 +505,10 @@
505505
#define C2CBUFSIZ 8192
506506
#define NUMDICTS 50
507507

508-
#ifdef __MINGW32__
509-
#define NOMKSTEMP
510-
#define NOTMPDIR
508+
#ifndef HAVE_MKSTEMP
509+
#define mkstemp _cbf_mkstemp
510+
int
511+
_cbf_mkstemp(char *templ);
511512
#endif
512513

513514
#define HDR_FINDDIMS 0x0040 /* On read, find header dims */
@@ -826,9 +827,7 @@ int main (int argc, char *argv [])
826827
const char *dictionary[NUMDICTS];
827828
int dqrflags[NUMDICTS];
828829
char *ciftmp=NULL;
829-
#ifndef NOMKSTEMP
830830
int ciftmpfd;
831-
#endif
832831
int ciftmpused;
833832
int padflag;
834833
int dimflag;
@@ -1697,23 +1696,7 @@ int main (int argc, char *argv [])
16971696

16981697
if (!cifin || strcmp(cifin?cifin:"","-") == 0) {
16991698
ciftmp = (char *)malloc(strlen("/tmp/cif2cbfXXXXXX")+1);
1700-
#ifdef NOTMPDIR
1701-
strcpy(ciftmp, "cif2cbfXXXXXX");
1702-
#else
17031699
strcpy(ciftmp, "/tmp/cif2cbfXXXXXX");
1704-
#endif
1705-
#ifdef NOMKSTEMP
1706-
if ((ciftmp = mktemp(ciftmp)) == NULL ) {
1707-
fprintf(stderr,"\n cif2cbf: Can't create temporary file name %s.\n", ciftmp);
1708-
fprintf(stderr,"%s\n",strerror(errno));
1709-
exit(1);
1710-
}
1711-
if ( (file = fopen(ciftmp,"wb+")) == NULL) {
1712-
fprintf(stderr,"Can't open temporary file %s.\n", ciftmp);
1713-
fprintf(stderr,"%s\n",strerror(errno));
1714-
exit(1);
1715-
}
1716-
#else
17171700
if ((ciftmpfd = mkstemp(ciftmp)) == -1 ) {
17181701
fprintf(stderr,"\n cif2cbf: Can't create temporary file %s.\n", ciftmp);
17191702
fprintf(stderr,"%s\n",strerror(errno));
@@ -1724,7 +1707,6 @@ int main (int argc, char *argv [])
17241707
fprintf(stderr,"%s\n",strerror(errno));
17251708
exit(1);
17261709
}
1727-
#endif
17281710
while ((nbytes = fread(buf, 1, C2CBUFSIZ, stdin))) {
17291711
if(nbytes != fwrite(buf, 1, nbytes, file)) {
17301712
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
@@ -309,6 +309,11 @@
309309
# include <unistd.h>
310310
#endif
311311

312+
#ifndef HAVE_MKSTEMP
313+
# define mkstemp _cbf_mkstemp
314+
int
315+
_cbf_mkstemp(char *templ);
316+
#endif
312317

313318

314319
double rint(double);
@@ -526,7 +531,7 @@ int main (int argc, char *argv [])
526531
int copt;
527532
int errflg = 0;
528533
char * imgtmp=NULL;
529-
int imgtmpused = 0;
534+
int imgtmpfd = -1;
530535
const char *imgin, *cbfout, *template, *distancestr, *alias;
531536
cbf_detector detector;
532537
char *tag, *data, *root;
@@ -671,12 +676,13 @@ int main (int argc, char *argv [])
671676
if (!imgin || strcmp(imgin?imgin:"","-") == 0) {
672677
imgtmp = (char *)malloc(strlen("/tmp/cvt_imgXXXXXX")+1);
673678
strcpy(imgtmp, "/tmp/cvt_imgXXXXXX");
674-
if ((imgin = mktemp(imgtmp)) == NULL ) {
679+
if ((imgtmpfd = mkstemp(imgtmp)) == -1 ) {
675680
fprintf(stderr,"\n convert_image: Can't create temporary file name %s.\n", imgtmp);
676681
fprintf(stderr,"%s\n",strerror(errno));
677682
exit(1);
678683
}
679-
imgtmpused = 1;
684+
close(imgtmpfd);
685+
imgin = imgtmp;
680686
}
681687

682688
/* Read the image */
@@ -685,7 +691,7 @@ int main (int argc, char *argv [])
685691

686692
cbf_failnez (img_read (img, imgin))
687693

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

0 commit comments

Comments
 (0)