Skip to content

Commit

Permalink
test: add tmpfile.c
Browse files Browse the repository at this point in the history
Though `wasi-libc` may not want to expose `tmpfile` and other related,
Unix-specific, "create a /tmp thing" functions, these functions are
quite useful during testing. By pulling in slightly-altered versions of
these functions, this change also enables two new tests, `fdopen.c` and
`ungetc.c`.
  • Loading branch information
abrown committed Nov 21, 2024
1 parent dff5f29 commit 13ff49f
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 0 deletions.
6 changes: 6 additions & 0 deletions test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ INFRA_WASM_OBJS := $(patsubst $(LIBC_TEST)/src/common/%.c,$(OBJDIR)/common/%.was
$(OBJDIR)/common/%.wasm.o: $(LIBC_TEST)/src/common/%.c | $(INFRA_OBJDIR)
$(CC) $(CFLAGS) -c $< -o $@

# In some cases, we need extra test infrastructure to provide some unimplemented
# functions (see the `common` directory).
INFRA_WASM_OBJS += $(OBJDIR)/common/tmpfile.wasm.o
$(OBJDIR)/common/tmpfile.wasm.o: common/tmpfile.c | $(INFRA_OBJDIR)
$(CC) $(CFLAGS) -c $< -o $@

# Also, include the `libc-test` infrastructure headers.
INFRA_HEADERS_DIR := $(LIBC_TEST)/src/common
INFRA_HEADERS := $(shell find $(INFRA_HEADERS_DIR) -name '*.h')
Expand Down
86 changes: 86 additions & 0 deletions test/common/tmpfile.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* For tests that need to create temporary files, it is quite convenient to
* implement the following functions. Note that these are to be used as testing
* infrastructure (i.e., creating files to test against), not for testing the
* implementation of these functions themselves which may be altered slightly.
*/

#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

/*
* Copied from `libc-top-half/musl/src/temp/__randname.c`. This assumes that a
check for the template size has already 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;
}

/*
* Adapted from `libc-top-half/musl/src/stdio/tmpfile.c`; this implementation
* does not retry opening the file.
*/
#define MAXTRIES 1
FILE *tmpfile(void)
{
char s[] = "/tmp/tmpfile_XXXXXX";
int fd;
FILE *f;
int try;
for (try=0; try<MAXTRIES; try++) {
__randname(s+5);
fd = open(s, O_RDWR|O_CREAT|O_EXCL, 0600);
if (fd >= 0) {
unlink(s);
f = fdopen(fd, "w+");
if (!f) close(fd);
return f;
}
}
return 0;
}

/*
* Adapted from `libc-top-half/musl/src/stdio/mkostemps.c` and
* `libc-top-half/musl/src/temp/mkstemp.c`; this implementation does not
* actually retry creating the file.
*/
int __mkostemps(char *template, int len, int flags)
{
size_t l = strlen(template);
if (l<6 || len>l-6 || memcmp(template+l-len-6, "XXXXXX", 6)) {
errno = EINVAL;
return -1;
}

flags -= flags & O_ACCMODE;
int fd, retries = 1;
do {
__randname(template+l-len-6);
if ((fd = open(template, flags | O_RDWR | O_CREAT | O_EXCL, 0600))>=0)
return fd;
} while (--retries && errno == EEXIST);

memcpy(template+l-len-6, "XXXXXX", 6);
return -1;
}
int mkstemp(char *template)
{
return __mkostemps(template, 0, 0);
}
7 changes: 7 additions & 0 deletions test/common/tmpfile.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* For tests that need to create temporary files, it is quite convenient to
* implement the following functions; see `tmpfile.c` for details.
*/
#include <stdio.h>
FILE *tmpfile(void);
int mkstemp(char *);
3 changes: 3 additions & 0 deletions test/src/libc-test/functional/fdopen.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// add-flags.py(CFLAGS): -I. -include common/tmpfile.h
// add-flags.py(RUN): --dir fs::/tmp
#include "build/download/libc-test/src/functional/fdopen.c"
3 changes: 3 additions & 0 deletions test/src/libc-test/functional/ungetc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// add-flags.py(CFLAGS): -I. -include common/tmpfile.h
// add-flags.py(RUN): --dir fs::/tmp
#include "build/download/libc-test/src/functional/ungetc.c"

0 comments on commit 13ff49f

Please sign in to comment.