diff --git a/modules/src/system/aprintf.c b/modules/src/system/aprintf.c new file mode 100644 index 000000000..997d408c2 --- /dev/null +++ b/modules/src/system/aprintf.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include "system.h" + +char* aprintf(const char* fmt, ...) +{ + int n; + char* p; + va_list ap; + + va_start(ap, fmt); + n = vsnprintf(NULL, 0, fmt, ap) + 1; + va_end(ap); + + p = malloc(n); + if (!p) + return NULL; + + va_start(ap, fmt); + vsnprintf(p, n, fmt, ap); + va_end(ap); + + return p; +} + +/* vim: set sw=4 ts=4 expandtab : */ + diff --git a/modules/src/system/build.lua b/modules/src/system/build.lua index 343c60fb3..c19a82924 100644 --- a/modules/src/system/build.lua +++ b/modules/src/system/build.lua @@ -1,17 +1,30 @@ clibrary { name = "lib", srcs = { - "./access.c", "./break.c", "./chmode.c", "./close.c", - "./create.c", "./filesize.c","./basename.c","./tmpnam.c", - --"./lock.c", - "./modtime.c", "./open.c", "./read.c", "./remove.c", - "./rename.c", "./seek.c", "./stop.c", "./system.c", - --"./unlock.c”, - "./write.c", - "./tmpdir.c", - "./syssystem.c", - "./strndup.c", + "./access.c", + "./aprintf.c", + "./basename.c", + "./break.c", + "./chmode.c", + "./close.c", + "./create.c", + "./filesize.c", + "./maketempfile.c", + "./modtime.c", + "./open.c", + "./read.c", + "./remove.c", + "./rename.c", + "./seek.c", "./setbinarymode.c", + "./stop.c", + "./strndup.c", + "./syssystem.c", + "./system.c", + "./tmpdir.c", + "./write.c", + --"./lock.c", + --"./unlock.c”, }, hdrs = { "./system.h" }, } diff --git a/modules/src/system/maketempfile.c b/modules/src/system/maketempfile.c new file mode 100644 index 000000000..02068b628 --- /dev/null +++ b/modules/src/system/maketempfile.c @@ -0,0 +1,52 @@ +/* Copyright (c) 2022. See the file License in + * the root directory for more information. + */ +#include +#include +#include +#include +#include +#include "system.h" + +#if defined WIN32 +static unsigned temper(unsigned x) +{ + x ^= x>>11; + x ^= x<<7 & 0x9D2C5680; + x ^= x<<15 & 0xEFC60000; + x ^= x>>18; + return x; +} + +static int rand_r(unsigned *seed) +{ + return temper(*seed = *seed * 1103515245 + 12345)/2; +} +#endif + +char* sys_maketempfile(const char* prefix, const char* suffix) +{ + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + + unsigned int seed = (unsigned int)(uintptr_t)prefix + ^ (unsigned int)ts.tv_sec ^ (unsigned int)ts.tv_nsec; + const char* tempdir = sys_gettmpdir(); + + for (;;) + { + unsigned int hash = rand_r(&seed); + char* filename = aprintf("%s/ack-%s-%x%s", + tempdir, prefix, hash, + suffix); + int fd = open(filename, O_CREAT|O_EXCL|O_RDWR, 0600); + if (fd != -1) + { + close(fd); + return filename; + } + if (errno != EEXIST) + perror("could not create temporary file"); + free(filename); + } +} diff --git a/modules/src/system/system.h b/modules/src/system/system.h index 582dd44e9..5f596822e 100644 --- a/modules/src/system/system.h +++ b/modules/src/system/system.h @@ -78,11 +78,11 @@ time_t sys_modtime(char *); * * Supports both DOS and UNIX style paths. * */ -void sys_basename(const char *str, register char *dst); +extern void sys_basename(const char *str, register char *dst); -/* Creates a temporary filename. This has - * the same semantics as ISO C90 tmpnam() */ -char* sys_tmpnam(char *buffer); +/* Creates a temporary filename, makes it, and returns a malloc'd string + * containing the filename. */ +extern char* sys_maketempfile(const char* prefix, const char* suffix); #if defined WIN32 /* Really? */ @@ -93,4 +93,8 @@ extern char* strndup(const char* s, size_t n); * sane systems. */ extern void sys_setbinarymode(FILE* fp); +/* As system sprintf(), except uses malloc() to allocate a new buffer of the + * right size for the result. */ +extern char* aprintf(const char* format, ...); + #endif /* __SYSTEM_INCLUDED__ */ diff --git a/modules/src/system/tmpnam.c b/modules/src/system/tmpnam.c deleted file mode 100644 index 1c58261ac..000000000 --- a/modules/src/system/tmpnam.c +++ /dev/null @@ -1,16 +0,0 @@ -/* Copyright (c) 2019. See the file License in - * the root directory for more information. - * - * Created on: 2019-03-13 - * - */ -#include - -/* This has been placed here, because on some famous platforms, this - * call is completely broken (e.g Windows up to recent versions of CRT) - */ -char* sys_tmpnam(char *buffer) -{ - return tmpnam(buffer); -} - diff --git a/util/LLgen/src/machdep.c b/util/LLgen/src/machdep.c index f2d0bd9c1..602edcb61 100644 --- a/util/LLgen/src/machdep.c +++ b/util/LLgen/src/machdep.c @@ -18,10 +18,9 @@ #include #include #include +#include #if defined WIN32 #include -#else -#include #endif # include "extern.h" # include "types.h" diff --git a/util/ack/files.c b/util/ack/files.c index 04167e2e5..f72ff57ca 100644 --- a/util/ack/files.c +++ b/util/ack/files.c @@ -53,14 +53,11 @@ int setfiles(trf *phase) { out.p_keeps=NO ; out.p_keep=YES ; } else { - gr_init(&pathname) ; if ( !phase->t_keep && !t_flag ) { - gr_cat(&pathname, sys_gettmpdir()); - gr_cat(&pathname, "/Ack-XXXXXX"); - int fd = mkstemp(pathname.gr_string); - close(fd); + out.p_path = sys_maketempfile("ack", phase->t_out); out.p_keep=NO ; } else { + gr_init(&pathname) ; if ( !p_basename ) { gr_cat(&pathname,"Ack") ; p_basename=keeps(gr_start(pathname)) ; @@ -69,10 +66,10 @@ int setfiles(trf *phase) { } else { gr_cat(&pathname,p_basename) ; } + gr_cat(&pathname,phase->t_out) ; + out.p_path= gr_final(&pathname) ; out.p_keep=YES ; } - gr_cat(&pathname,phase->t_out) ; - out.p_path= gr_final(&pathname) ; out.p_keeps= YES ; } scanlist( l_first(arguments), elem) { diff --git a/util/amisc/astrip.c b/util/amisc/astrip.c index 669c76739..11ba03892 100644 --- a/util/amisc/astrip.c +++ b/util/amisc/astrip.c @@ -17,7 +17,7 @@ */ -char tname[L_tmpnam]; +char* tname; FILE *tf; struct outhead buf; int readerror, writeerror; @@ -30,12 +30,7 @@ int main(int argc, char **argv) { int status; - if (sys_tmpnam(tname)==NULL) - { - fprintf(stderr, "astrip: cannot create temporary filename\n"); - return(1); - } - fclose(fopen(tname,"wb")); + tname = sys_maketempfile("ack", "dat"); while(--argc) { if ((status = strip(argv[argc])) > 1) break; diff --git a/util/arch/archiver.c b/util/arch/archiver.c index 98fc79375..bc1b01557 100644 --- a/util/arch/archiver.c +++ b/util/arch/archiver.c @@ -120,8 +120,7 @@ char io_buffer[IO_SIZE]; char *progname; -char temp_buf[L_tmpnam]; -char *temp_arch = &temp_buf[0]; +char *temp_arch; void do_object(FILE* f, long size); void do_names(struct outhead *headp); @@ -348,10 +347,7 @@ int main(int argc, char *argv[]) distr_time = statbuf.st_mtime; } #endif - if (sys_tmpnam(temp_arch) == NULL) - { - error(TRUE, "Cannot create a temporary filename\n", NULL); - } + temp_arch = sys_maketempfile("aal", "dat"); if (app_fl + ex_fl + del_fl + rep_fl + show_fl + pr_fl != 1) usage(); diff --git a/util/ass/ass80.c b/util/ass/ass80.c index 21ca7cf76..168a4a2b6 100644 --- a/util/ass/ass80.c +++ b/util/ass/ass80.c @@ -17,7 +17,7 @@ * this file contains several library routines. */ -static char filename[L_tmpnam]; +static char* filename; /* VARARGS1 */ @@ -384,9 +384,5 @@ void set_mode(int mode) char* tmpfil(void) { - if (sys_tmpnam(filename)==NULL) - { - fatal("Cannot create temporary filename."); - } - return filename; + return sys_maketempfile("ack-ass", "dat"); } diff --git a/util/ego/em_ego/em_ego.c b/util/ego/em_ego/em_ego.c index 31364c298..1946966f2 100644 --- a/util/ego/em_ego/em_ego.c +++ b/util/ego/em_ego/em_ego.c @@ -59,7 +59,7 @@ static const struct #define MAXARGS 1024 /* mar # of args */ #define NTEMPS 4 /* # of temporary files; not tunable */ -static char tmpbase[PATH_MAX]; +static char* tmpbase; static char ddump[PATH_MAX]; /* data label dump file */ static char pdump[PATH_MAX]; /* procedure name dump file */ static char tmpbufs[NTEMPS * 2][PATH_MAX]; @@ -389,11 +389,7 @@ int main(int argc, char* argv[]) fatal("no correct -P flag given"); } - { - strcpy(tmpbase, sys_gettmpdir()); - strcat(tmpbase, "/ego.XXXXXX"); - close(mkstemp(tmpbase)); - } + tmpbase = sys_maketempfile("ego", ""); strcpy(ddump, tmpbase); strcpy(pdump, tmpbase); diff --git a/util/ego/il/il.c b/util/ego/il/il.c index 478053ab6..34ff56c2f 100644 --- a/util/ego/il/il.c +++ b/util/ego/il/il.c @@ -38,12 +38,12 @@ calcnt_p cchead; /* call-count info of current proc */ STATIC long space = 0; STATIC long total_size = 0; -STATIC char cname[PATH_MAX]; -STATIC char ccname[PATH_MAX]; -STATIC char cname2[PATH_MAX]; +STATIC char* cname; +STATIC char* ccname; +STATIC char* cname2; /* For debugging only */ -STATIC char sname[PATH_MAX]; +STATIC char* sname; STATIC int kp_temps = 0; int Ssubst; @@ -337,20 +337,11 @@ char* argv[]; go(argc, argv, no_action, no_action, no_action, il_flags); il_extptab(fproc); /* add extended data structures */ - strcpy(cname, tmpdir); - strcpy(ccname, tmpdir); - strcpy(sname, tmpdir); - strcpy(cname2, tmpdir); + cname = sys_maketempfile("il", "i1"); + ccname = sys_maketempfile("il", "i2"); + sname = sys_maketempfile("il", "i3"); + cname2 = sys_maketempfile("il", "i4"); - strcat(cname, "/ego.i1.XXXXXX"); - strcat(ccname, "/ego.i2.XXXXXX"); - strcat(sname, "/ego.i3.XXXXXX"); - strcat(cname2, "/ego.i4.XXXXXX"); - - close(mkstemp(cname)); - close(mkstemp(ccname)); - close(mkstemp(sname)); - close(mkstemp(cname2)); pass1(files->lname_in, files->bname_in, cname); /* grep calls, analyse procedures */ space = total_size * space / 100; pass2(cname, space); /* select calls to be expanded */ diff --git a/util/opt/ext.h b/util/opt/ext.h index 342ab17c0..d4609a43b 100644 --- a/util/opt/ext.h +++ b/util/opt/ext.h @@ -16,7 +16,7 @@ extern bool repl_longmuls; extern byte em_flag[]; extern line_p instrs,pseudos; extern FILE *outfile; -extern char tempname[]; +extern char *tempname; extern offset wordsize; extern offset pointersize; extern char *progname; diff --git a/util/opt/main.c b/util/opt/main.c index 10b9da0a8..415435f11 100644 --- a/util/opt/main.c +++ b/util/opt/main.c @@ -48,11 +48,7 @@ void fileinit(void) error("wrong input file"); if (Lflag) { - - if (sys_tmpnam(tempname)==NULL) - { - error("can't create temporary file."); - } + tempname = sys_maketempfile("opt", "dat"); outfile = fopen(tempname, "wb"); if (outfile == NULL) error("can't create %s", tempname); diff --git a/util/opt/var.c b/util/opt/var.c index 3e51a9a70..6085b5ba8 100644 --- a/util/opt/var.c +++ b/util/opt/var.c @@ -22,7 +22,7 @@ bool repl_longmuls = 0; /* replacing longmuls as well? */ line_p instrs,pseudos; /* pointers to chains */ sym_p symhash[NSYMHASH]; /* array of pointers to chains */ FILE *outfile; -char tempname[L_tmpnam]; +char *tempname; offset wordsize = 0; offset pointersize = 0; char *progname;