mirror of
https://github.com/fluencelabs/musl
synced 2025-06-22 19:21:58 +00:00
add mkostemp, mkstemps, and mkostemps functions and reorganize temp internals
based on patch contributed by Anthony G. Basile (blueness) some issues remain with the filename generation algorithm and other small bugs, but this patch has been sitting around long enough that I feel it's best to get it committed and then work out any remaining issues.
This commit is contained in:
@ -95,6 +95,7 @@ int posix_memalign (void **, size_t, size_t);
|
|||||||
int setenv (const char *, const char *, int);
|
int setenv (const char *, const char *, int);
|
||||||
int unsetenv (const char *);
|
int unsetenv (const char *);
|
||||||
int mkstemp (char *);
|
int mkstemp (char *);
|
||||||
|
int mkostemp (char *, int);
|
||||||
char *mkdtemp (char *);
|
char *mkdtemp (char *);
|
||||||
int getsubopt (char **, char *const *, char **);
|
int getsubopt (char **, char *const *, char **);
|
||||||
int rand_r (unsigned *);
|
int rand_r (unsigned *);
|
||||||
@ -134,6 +135,8 @@ void lcong48 (unsigned short [7]);
|
|||||||
#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
||||||
#include <alloca.h>
|
#include <alloca.h>
|
||||||
char *mktemp (char *);
|
char *mktemp (char *);
|
||||||
|
int mkstemps (char *, int);
|
||||||
|
int mkostemps (char *, int, int);
|
||||||
void *valloc (size_t);
|
void *valloc (size_t);
|
||||||
void *memalign(size_t, size_t);
|
void *memalign(size_t, size_t);
|
||||||
#define WCOREDUMP(s) ((s) & 0x80)
|
#define WCOREDUMP(s) ((s) & 0x80)
|
||||||
@ -150,6 +153,11 @@ char *gcvt(double, int, char *);
|
|||||||
|
|
||||||
#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
|
#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
|
||||||
#define mkstemp64 mkstemp
|
#define mkstemp64 mkstemp
|
||||||
|
#define mkostemp64 mkostemp
|
||||||
|
#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
||||||
|
#define mkstemps64 mkstemps
|
||||||
|
#define mkostemps64 mkostemps
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
21
src/temp/__randname.c
Normal file
21
src/temp/__randname.c
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
int __clock_gettime(clockid_t, struct timespec *);
|
||||||
|
|
||||||
|
/* This assumes that a check for the
|
||||||
|
template size has alrady been made */
|
||||||
|
char *__randname(char *template)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct timespec ts;
|
||||||
|
unsigned long r;
|
||||||
|
|
||||||
|
__clock_gettime(CLOCK_REALTIME, &ts);
|
||||||
|
r = ts.tv_nsec*65537 ^ (uintptr_t)&ts / 16 + (uintptr_t)template;
|
||||||
|
for (i=0; i<6; i++, r>>=5)
|
||||||
|
template[i] = 'A'+(r&15)+(r&16)*2;
|
||||||
|
|
||||||
|
return template;
|
||||||
|
}
|
12
src/temp/mkostemp.c
Normal file
12
src/temp/mkostemp.c
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#define _BSD_SOURCE
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "libc.h"
|
||||||
|
|
||||||
|
int __mkostemps(char *, int, int);
|
||||||
|
|
||||||
|
int mkostemp(char *template, int flags)
|
||||||
|
{
|
||||||
|
return __mkostemps(template, 0, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
LFS64(mkostemp);
|
32
src/temp/mkostemps.c
Normal file
32
src/temp/mkostemps.c
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#define _BSD_SOURCE
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include "libc.h"
|
||||||
|
|
||||||
|
char *__randname(char *);
|
||||||
|
|
||||||
|
int __mkostemps(char *template, int len, int flags)
|
||||||
|
{
|
||||||
|
if (len < 0) return EINVAL;
|
||||||
|
|
||||||
|
size_t l = strlen(template)-len;
|
||||||
|
if (l < 6 || strncmp(template+l-6, "XXXXXX", 6)) {
|
||||||
|
errno = EINVAL;
|
||||||
|
*template = 0;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fd, retries = 100;
|
||||||
|
while (retries--) {
|
||||||
|
__randname(template+l-6);
|
||||||
|
if ((fd = open(template, flags | O_RDWR | O_CREAT | O_EXCL, 0600))>=0)
|
||||||
|
return fd;
|
||||||
|
if (errno != EEXIST) return -1;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
weak_alias(__mkostemps, mkostemps);
|
||||||
|
weak_alias(__mkostemps, mkostemps64);
|
@ -1,28 +1,11 @@
|
|||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <fcntl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include "libc.h"
|
#include "libc.h"
|
||||||
|
|
||||||
char *__mktemp(char *);
|
int __mkostemps(char *, int, int);
|
||||||
|
|
||||||
int mkstemp(char *template)
|
int mkstemp(char *template)
|
||||||
{
|
{
|
||||||
int fd, retries = 100, t0 = *template;
|
return __mkostemps(template, 0, 0);
|
||||||
while (retries--) {
|
|
||||||
if (!*__mktemp(template)) return -1;
|
|
||||||
if ((fd = open(template, O_RDWR | O_CREAT | O_EXCL, 0600))>=0)
|
|
||||||
return fd;
|
|
||||||
if (errno != EEXIST) return -1;
|
|
||||||
/* this is safe because mktemp verified
|
|
||||||
* that we have a valid template string */
|
|
||||||
template[0] = t0;
|
|
||||||
strcpy(template+strlen(template)-6, "XXXXXX");
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LFS64(mkstemp);
|
LFS64(mkstemp);
|
||||||
|
12
src/temp/mkstemps.c
Normal file
12
src/temp/mkstemps.c
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#define _BSD_SOURCE
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "libc.h"
|
||||||
|
|
||||||
|
int __mkostemps(char *, int, int);
|
||||||
|
|
||||||
|
int mkstemps(char *template, int len)
|
||||||
|
{
|
||||||
|
return __mkostemps(template, len, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
LFS64(mkstemps);
|
@ -1,17 +1,14 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <time.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "libc.h"
|
#include "libc.h"
|
||||||
|
|
||||||
|
char *__randname(char *);
|
||||||
|
|
||||||
char *__mktemp(char *template)
|
char *__mktemp(char *template)
|
||||||
{
|
{
|
||||||
struct timespec ts;
|
size_t l = strlen(template);
|
||||||
size_t i, l = strlen(template);
|
|
||||||
int retries = 10000;
|
int retries = 10000;
|
||||||
unsigned long r;
|
unsigned long r;
|
||||||
|
|
||||||
@ -21,10 +18,7 @@ char *__mktemp(char *template)
|
|||||||
return template;
|
return template;
|
||||||
}
|
}
|
||||||
while (retries--) {
|
while (retries--) {
|
||||||
clock_gettime(CLOCK_REALTIME, &ts);
|
__randname(template+l-6);
|
||||||
r = ts.tv_nsec + (uintptr_t)&ts / 16 + (uintptr_t)template;
|
|
||||||
for (i=1; i<=6; i++, r>>=4)
|
|
||||||
template[l-i] = 'A'+(r&15);
|
|
||||||
if (access(template, F_OK) < 0) return template;
|
if (access(template, F_OK) < 0) return template;
|
||||||
}
|
}
|
||||||
*template = 0;
|
*template = 0;
|
||||||
|
Reference in New Issue
Block a user