Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] OCaml 5.0 support #122

Closed
wants to merge 46 commits into from
Closed
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
de0299f
tmp
kit-ty-kate Oct 5, 2022
2b31cbb
tmp
kit-ty-kate Oct 5, 2022
cad5c3b
fix test-include weird Makefile issues
kit-ty-kate Oct 5, 2022
3f473c7
tmp
kit-ty-kate Oct 5, 2022
563fd92
test
kit-ty-kate Oct 6, 2022
665e955
tmp
kit-ty-kate Oct 6, 2022
fa430fb
test
kit-ty-kate Oct 7, 2022
82205a7
tmp
kit-ty-kate Oct 7, 2022
f147b12
bump
kit-ty-kate Oct 7, 2022
92fc584
bump
kit-ty-kate Oct 7, 2022
d6b9bcb
fix
kit-ty-kate Oct 7, 2022
6b06b3f
fix linking
kit-ty-kate Oct 8, 2022
1d5f77c
fix
kit-ty-kate Oct 8, 2022
97671f2
fix 10_000 feet above the floor
kit-ty-kate Oct 8, 2022
aa1ac8f
more stubs (actually needed)
kit-ty-kate Oct 8, 2022
ad01905
atomic_thread_fence
kit-ty-kate Oct 9, 2022
2b65ad2
pthread_mutexattr_*
kit-ty-kate Oct 9, 2022
5b378ed
atomic_fetch_add + pthread_sigmask + pthread_equal
kit-ty-kate Oct 9, 2022
f91352a
fixup
kit-ty-kate Oct 9, 2022
8017dfd
more atomics
kit-ty-kate Oct 9, 2022
c235799
fixup
kit-ty-kate Oct 9, 2022
401371d
fixup
kit-ty-kate Oct 9, 2022
0c2ec55
atomic_fetch_or
kit-ty-kate Oct 9, 2022
59621fd
pthread_cond_*
kit-ty-kate Oct 9, 2022
f154280
more
kit-ty-kate Oct 9, 2022
5dc13d7
end?
kit-ty-kate Oct 9, 2022
840db53
cleanup
kit-ty-kate Oct 9, 2022
6440f4c
Update nolibc/include/stdio.h
kit-ty-kate Oct 13, 2022
4f795f2
no extern
kit-ty-kate Oct 21, 2022
c3e4833
fill up definitions
kit-ty-kate Oct 21, 2022
9a1f248
Fix opam exec --switch=5.0 -- make
kit-ty-kate Oct 21, 2022
02c2010
Fix weird makefile issues
kit-ty-kate Oct 21, 2022
2f3f627
tmp
kit-ty-kate Oct 21, 2022
1b69cbb
tmp
kit-ty-kate Oct 21, 2022
02407fb
tmp
kit-ty-kate Oct 21, 2022
33da6cf
tmp
kit-ty-kate Oct 21, 2022
22cacf0
fix parallel build
kit-ty-kate Oct 21, 2022
a3fd322
fix linking
kit-ty-kate Oct 21, 2022
6e799a9
Implement sysconf
kit-ty-kate Oct 25, 2022
2b26368
Add mmap
kit-ty-kate Oct 25, 2022
8f5bd96
tmp
kit-ty-kate Oct 25, 2022
738e62b
tmp
kit-ty-kate Oct 25, 2022
72eb013
dumb thread local storage
palainp Dec 22, 2022
8a23cdf
tls as static
palainp Dec 31, 2022
d3e6e33
patch ocaml runtime for 1 domain
palainp Jan 4, 2023
f118992
remove -i argument which is not posix
palainp Jan 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 14 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ LOCAL_CFLAGS=$(MAKECONF_CFLAGS) -I$(TOP)/nolibc/include -include _solo5/override
# CFLAGS used by the OCaml compiler to build C stubs
GLOBAL_CFLAGS=$(MAKECONF_CFLAGS) -I$(MAKECONF_PREFIX)/solo5-sysroot/include/nolibc/ -include _solo5/overrides.h
# LIBS used by the OCaml compiler to link executables
GLOBAL_LIBS=-L$(MAKECONF_PREFIX)/solo5-sysroot/lib/nolibc/ -lnolibc -lopenlibm $(MAKECONF_EXTRA_LIBS)
GLOBAL_LIBS=-L$(MAKECONF_PREFIX)/solo5-sysroot/lib/nolibc/ -Wl,--start-group -lnolibc -lopenlibm $(MAKECONF_EXTRA_LIBS) -Wl,--end-group

# NOLIBC
NOLIBC_CFLAGS=$(LOCAL_CFLAGS) -I$(TOP)/openlibm/src -I$(TOP)/openlibm/include
Expand Down Expand Up @@ -45,26 +45,25 @@ ocaml/Makefile:
# configure link test
# - We override OCAML_OS_TYPE since configure just hardcodes it to "Unix".
OC_CFLAGS=$(LOCAL_CFLAGS) -I$(TOP)/openlibm/include -I$(TOP)/openlibm/src -nostdlib
OC_LIBS=-L$(TOP)/nolibc -lnolibc -L$(TOP)/openlibm -lopenlibm -nostdlib $(MAKECONF_EXTRA_LIBS)
OC_LIBS=-L$(TOP)/nolibc -Wl,--start-group -lnolibc -L$(TOP)/openlibm -lopenlibm -nostdlib $(MAKECONF_EXTRA_LIBS) -Wl,--end-group
ocaml/Makefile.config: ocaml/Makefile openlibm/libopenlibm.a nolibc/libnolibc.a
# configure: Do not build dynlink
sed -i -e 's/otherlibraries="dynlink"/otherlibraries=""/g' ocaml/configure
# configure: Allow precise input of flags and libs
sed -i -e 's/oc_cflags="/oc_cflags="$$OC_CFLAGS /g' ocaml/configure
sed -i -e 's/ocamlc_cflags="/ocamlc_cflags="$$OCAMLC_CFLAGS /g' ocaml/configure
sed -i -e 's/nativecclibs="$$cclibs $$DLLIBS"/nativecclibs="$$GLOBAL_LIBS"/g' ocaml/configure
sed -i -e 's/nativecclibs="$$cclibs $$DLLIBS $$PTHREAD_LIBS"/nativecclibs="$$GLOBAL_LIBS"/g' ocaml/configure
# runtime/Makefile: Runtime rules: don't build libcamlrun.a and import ocamlrun from the system
sed -i -e 's/^all: $$(BYTECODE_STATIC_LIBRARIES) $$(BYTECODE_SHARED_LIBRARIES)/all: primitives ld.conf/' ocaml/runtime/Makefile
sed -i -e 's/^ocamlrun$$(EXE):.*/dummy:/g' ocaml/runtime/Makefile
sed -i -e 's/^ocamlruni$$(EXE):.*/dummyi:/g' ocaml/runtime/Makefile
sed -i -e 's/^ocamlrund$$(EXE):.*/dummyd:/g' ocaml/runtime/Makefile
echo -e "ocamlrun:\n\tcp $(shell which ocamlrun) .\n" >> ocaml/runtime/Makefile
echo -e "ocamlrund:\n\tcp $(shell which ocamlrund) .\n" >> ocaml/runtime/Makefile
echo -e "ocamlruni:\n\tcp $(shell which ocamlruni) .\n" >> ocaml/runtime/Makefile
touch ocaml/runtime/libcamlrun.a ocaml/runtime/libcamlrund.a ocaml/runtime/libcamlruni.a
sed -i -e 's,^runtime/ocamlrun$$(EXE):.*,dummy:,g' ocaml/Makefile
sed -i -e 's,^runtime/ocamlruni$$(EXE):.*,dummyi:,g' ocaml/Makefile
sed -i -e 's,^runtime/ocamlrund$$(EXE):.*,dummyd:,g' ocaml/Makefile
echo -e "runtime/ocamlrun:\n\tcp $(shell which ocamlrun) runtime/\n" >> ocaml/Makefile
echo -e "runtime/ocamlrund:\n\tcp $(shell which ocamlrund) runtime/\n" >> ocaml/Makefile
echo -e "runtime/ocamlruni:\n\tcp $(shell which ocamlruni) runtime/\n" >> ocaml/Makefile
touch ocaml/runtime/libcamlrun.a ocaml/runtime/libcamlrund.a ocaml/libcamlruni.a
# yacc/Makefile: import ocamlyacc from the system
sed -i -e 's/^ocamlyacc$$(EXE):.*/dummy:/g' ocaml/yacc/Makefile
echo -e "ocamlyacc:\n\tcp $(shell which ocamlyacc) .\n" >> ocaml/yacc/Makefile
sed -i -e 's,^yacc/ocamlyacc$$(EXE):.*,dummy:,g' ocaml/Makefile
echo -e "yacc/ocamlyacc:\n\tcp $(shell which ocamlyacc) yacc/\n" >> ocaml/Makefile
# tools/Makefile: stub out objinfo_helper
echo -e "objinfo_helper:\n\ttouch objinfo_helper\n" >> ocaml/tools/Makefile
# av_cv_libm_cos=no is passed to configure to prevent -lm being used (which
Expand All @@ -89,10 +88,12 @@ ocaml/Makefile.config: ocaml/Makefile openlibm/libopenlibm.a nolibc/libnolibc.a
-disable-systhreads\
-disable-unix-lib\
-disable-instrumented-runtime\
-disable-debug-runtime\
-disable-ocamltest\
-disable-ocamldoc\
$(MAKECONF_OCAML_CONFIGURE_OPTIONS)
echo "ARCH=$(MAKECONF_OCAML_BUILD_ARCH)" >> ocaml/Makefile.config
echo 'NATIVE_COMPILER=true' >> ocaml/Makefile.config
echo 'SAK_CC=cc' >> ocaml/Makefile.config
echo 'SAK_CFLAGS=' >> ocaml/Makefile.config
echo 'SAK_LINK=cc $(SAK_CFLAGS) $$(OUTPUTEXE)$$(1) $$(2)' >> ocaml/Makefile.config
Expand Down
6 changes: 3 additions & 3 deletions nolibc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ test-include/%.c: include/%.h | test-include/sys

.PRECIOUS: test-include/%.c

test-include:
test-include/:
mkdir $@

test-include/sys: test-include
test-include/sys/: test-include/
mkdir $@

test-headers: $(TEST_H_OBJS)
test-headers: test-include/sys/ $(TEST_H_OBJS)
2 changes: 2 additions & 0 deletions nolibc/include/ctype.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@ int isdigit(int);
int isprint(int);
int isspace(int);
int isupper(int);
int isalnum(int);
int tolower(int);

#endif
1 change: 1 addition & 0 deletions nolibc/include/errno.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ extern int errno;
#define EINVAL 6
#define ENOMEM 7
#define EMFILE 8
#define EBUSY 9

#endif
1 change: 1 addition & 0 deletions nolibc/include/fcntl.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ int open(const char *, int, ...);
#define O_CREAT (1<<3)
#define O_TRUNC (1<<4)
#define O_EXCL (1<<5)
#define O_RDWR (1<<6)

#endif
56 changes: 56 additions & 0 deletions nolibc/include/pthread.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#ifndef _PTHREAD_H
#define _PTHREAD_H

#include <stddef.h>

typedef unsigned long int pthread_t;

extern int pthread_getaffinity_np ();
palainp marked this conversation as resolved.
Show resolved Hide resolved

extern pthread_t pthread_self (void);

typedef int pthread_attr_t;

extern int pthread_create ();
palainp marked this conversation as resolved.
Show resolved Hide resolved
extern int pthread_join ();
extern int pthread_attr_init ();
extern void pthread_cleanup_push ();
extern void pthread_cleanup_pop ();

typedef int pthread_mutex_t;
typedef int pthread_cond_t;

extern int pthread_mutex_lock ();
extern int pthread_mutex_trylock ();
extern int pthread_mutex_unlock ();

#define PTHREAD_MUTEX_INITIALIZER 0
#define PTHREAD_COND_INITIALIZER 0

extern int pthread_sigmask ();
extern int pthread_sigmask ();
extern int pthread_detach ();
extern int pthread_equal ();

typedef int pthread_mutexattr_t;

extern int pthread_mutexattr_init ();
extern int pthread_mutexattr_settype ();

#define PTHREAD_MUTEX_ERRORCHECK 0

extern int pthread_mutex_init ();
extern int pthread_mutexattr_destroy ();
extern int pthread_mutex_destroy ();

typedef int pthread_condattr_t;

extern int pthread_condattr_init ();
extern int pthread_cond_init ();

extern int pthread_cond_wait ();
extern int pthread_cond_broadcast ();
extern int pthread_cond_signal ();
extern int pthread_cond_destroy ();

#endif
8 changes: 8 additions & 0 deletions nolibc/include/sched.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef _SCHED_H
#define _SCHED_H

typedef int cpu_set_t;

#define CPU_ZERO (x) 0

#endif
4 changes: 4 additions & 0 deletions nolibc/include/setjmp.h
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
#include <signal.h>

void longjmp(int, int) __attribute__ ((__noreturn__));

#define setjmp(buf) 0
6 changes: 6 additions & 0 deletions nolibc/include/signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,17 @@ void (*signal(int sig, void (*func)(int)))(int);
#define SIG_DFL NULL
#define SIG_IGN NULL
#define SIG_ERR NULL
#define SIG_BLOCK NULL
#define SIG_SETMASK NULL
/*
* The following definitions are not required by the OCaml runtime, but are
* needed to build the freestanding version of GMP used by Mirage.
*/
#define SIGFPE 1
int raise(int);

typedef int sigset_t;

extern int sigfillset ();

#endif
43 changes: 43 additions & 0 deletions nolibc/include/stdatomic.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#ifndef _STDATOMIC_H
#define _STDATOMIC_H

#define atomic_load_explicit(x, mode) ( *x )
#define atomic_load(x) ( *x )

extern int memory_order_release;
extern int memory_order_acquire;
extern int memory_order_relaxed;
extern int memory_order_seq_cst;

#define atomic_fetch_add(X, Y) ({ __auto_type tmp = *X; *X = tmp + Y; tmp; })
#define atomic_fetch_add_explicit(X, Y, MOD) atomic_fetch_add(X, Y)

#define atomic_thread_fence(MO) do {} while (0)

typedef unsigned long long atomic_uint_fast64_t;

#define atomic_compare_exchange_strong(OBJ, EXPECTED, DESIRED) \
({ int ret = 0; \
if (*OBJ == *EXPECTED) { \
*OBJ = DESIRED; \
ret = 1; \
} \
ret; \
})

#define atomic_exchange(OBJ, DESIRED) \
({ __auto_type tmp = *OBJ; \
*OBJ = DESIRED; \
tmp; \
})

#define atomic_store(OBJ, DESIRED) do { *OBJ = DESIRED; } while(0)
#define atomic_store_explicit(OBJ, DESIRED, ORDER) atomic_store(OBJ, DESIRED)

#define atomic_fetch_or(OBJ, ARG) \
({ __auto_type tmp = *OBJ; \
*OBJ = *OBJ | ARG; \
tmp; \
})

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be easier to just call into the compiler atomics (__atomic_bla) no ?

#endif
7 changes: 7 additions & 0 deletions nolibc/include/stdio.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,12 @@ size_t fwrite(const void *, size_t, size_t, FILE *);
int fputc(int, FILE *);
int putc(int, FILE *);
int ferror(FILE *);
int puts(const char *);
int putchar(int);
int fputs(const char *, FILE *);
FILE *fopen(const char *, const char *);
int fclose(FILE *);
char *strcpy(char *, const char *); /* TODO ??? */


#endif
5 changes: 5 additions & 0 deletions nolibc/include/stdlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,9 @@ int system(const char *);
double strtod(const char *, char **);
long strtol(const char *, char **, int);

void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));

char *mktemp(char *);

#endif
4 changes: 4 additions & 0 deletions nolibc/include/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,8 @@ char *strstr(const char *, const char *);
*/
int strncmp(const char*, const char*, size_t);

int strerror_r(int errnum, char *buf, size_t buflen);

char *strdup(const char *);

#endif
23 changes: 23 additions & 0 deletions nolibc/include/sys/mman.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef _MMAP_H
#define _MMAP_H

#include <stddef.h>

typedef int off_t;

extern void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off);

#define PROT_NONE 0
#define PROT_READ 1
#define PROT_WRITE 2

#define MAP_PRIVATE 0
#define MAP_ANONYMOUS 0
#define MAP_FIXED 0
#define MAP_SHARED 0

#define MAP_FAILED NULL

extern int munmap(void *addr, size_t len);

#endif
3 changes: 3 additions & 0 deletions nolibc/include/sys/stat.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ struct stat {
#define S_IFMT 0
#define S_IFREG 0
#define S_ISREG(x) (0)
#define S_IRUSR 0
#define S_IWUSR 0
int stat(const char *, struct stat *);
int mkdir(const char *, mode_t);
int fstat(int, struct stat *);

#endif
1 change: 1 addition & 0 deletions nolibc/include/sys/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ typedef int pid_t;
typedef int off_t;
typedef int ssize_t;
typedef int mode_t;
typedef int useconds_t;

#endif
5 changes: 5 additions & 0 deletions nolibc/include/unistd.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,10 @@ ssize_t write(int, const void *, size_t);
ssize_t readlink(const char *, char *, size_t);
int unlink(const char *);
int rmdir(const char *);
int usleep(useconds_t);
int ftruncate(int, off_t);
long sysconf(int);

#define _SC_PAGESIZE 1

#endif
49 changes: 49 additions & 0 deletions nolibc/stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ STUB_ABORT(read);
STUB_IGNORE(int, readlink, -1);
STUB_ABORT(unlink);
STUB_ABORT(rmdir);
STUB_ABORT(ftruncate);

/* dirent.h */
STUB_WARN_ONCE(int, closedir, -1);
Expand All @@ -100,3 +101,51 @@ STUB_ABORT(strerror);
/* sys/stat.h */
STUB_WARN_ONCE(int, stat, -1);
STUB_ABORT(mkdir);

/* pthread.h */
STUB_IGNORE(int, pthread_join, 0);
STUB_IGNORE(int, pthread_create, 0);
STUB_IGNORE(int, pthread_attr_init, 0);
STUB_ABORT(pthread_cleanup_push);
STUB_ABORT(pthread_cleanup_pop);

STUB_ABORT(mmap);
STUB_ABORT(munmap);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmhmm, from a discussion with @Engil and @TheLortex, I suspected a call of mmap which should be replaced by malloc. Can you compile and run a program with your version of OCaml 5?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have to be careful, mmap -> malloc on MAP_ANONYMOUS probabably is ok, on !MAP_ANONYMOUS we should fail.


int memory_order_release;
int memory_order_acquire;
int memory_order_relaxed;

STUB_ABORT(atomic_store_explicit);
STUB_ABORT(atomic_exchange);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why you STUB_ABORT these functions when you defined them into atomic.h (as macros) and when, in anyway, the compiler should be able to provide to us implementations of them. A first solution is to define these symbols as functions and use your macros inside. But, as @haesbaert, pointed out, the compiler should give to you the implementation of them.


STUB_ABORT(sysconf);

/* above that line, for OCaml 5, those are only required (i guess) for the configure step */
STUB_IGNORE(int, pthread_mutex_lock, 0);
palainp marked this conversation as resolved.
Show resolved Hide resolved
STUB_IGNORE(int, pthread_mutex_trylock, 0);
STUB_IGNORE(int, pthread_mutex_unlock, 0);
STUB_IGNORE(int, pthread_mutex_destroy, 0);
STUB_IGNORE(int, pthread_mutex_init, 0);

STUB_IGNORE(int, pthread_mutexattr_init, 0);
STUB_IGNORE(int, pthread_mutexattr_destroy, 0);
STUB_IGNORE(int, pthread_mutexattr_settype, 0);

STUB_IGNORE(int, pthread_sigmask, 0);

STUB_IGNORE(int, pthread_equal, 1);

STUB_IGNORE(int, pthread_condattr_init, 0); /* TODO: Is there a memory leak in OCaml? Shouldn't there be a call to pthread_condattr_destroy? */

/* TODO: No idea how to implement this properly */
STUB_ABORT(pthread_cond_init);
STUB_ABORT(pthread_cond_destroy);
STUB_ABORT(pthread_cond_wait);
STUB_ABORT(pthread_cond_signal);
STUB_ABORT(pthread_cond_broadcast);
STUB_ABORT(pthread_self);
STUB_ABORT(pthread_detach);
STUB_ABORT(sigfillset);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could probably be STUB_IGNORE, we'll never have signals.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed it can be STUB_IGNORE, during the small experiences I've done so far it doesn't seems to be an issue as I never saw any abort exception raised. Could it worth to keep it as STUB_ABORT and wait for the time an unikernel tells us when we need to add signal to solo5? :)

STUB_ABORT(usleep);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be something like calling solo5_yield(deadline, emptyset)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, we currently can sleep with Solo5 since we have the monotonic clock (it's just matter that we will block the only CPU we have).

STUB_ABORT(strerror_r);
Copy link
Member

@haesbaert haesbaert Oct 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is one:

#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>

int
mystrerror_r(int num, char *buf, size_t buflen)
{
	static const char *errlist[] = {
		"Undefined error: 0",			/*  0 - ENOERROR */
		"Bad file descriptor",			/*  1 - EBADF */
		"Result too large",			/*  2 - ERANGE */
		"Function not implemented",		/*  3 - ENOSYS */
		"Value too large to be stored in data type", /* 4 - OVERFLOW */
		"No such file or directory",		/*  5 - ENOENT */
		"Invalid argument",			/* 6 - EINVAL */
		"Cannot allocate memory",		/* 7 - ENOMEM */
		"Too many open files",			/* 8 - EMFILE */
		"Device busy",				/* 9 - EBUSY */
	};
	int nerr;

	nerr = sizeof(errlist) / sizeof(errlist[0]);

	if (num >= nerr || num < 0) {
		errno = EINVAL;
		return (EINVAL);
	}

	if (snprintf(buf, buflen, "%s", errlist[num]) >= buflen) {
		errno = ERANGE;
		return (ERANGE);
	}

	return (0);
}

int
main(void)
{
	char buf[256];
	int i;

	assert(mystrerror_r(0, buf, strlen("Undefined error: 0")) == ERANGE);
	assert(mystrerror_r(-1, buf, sizeof(buf)) == EINVAL);
	assert(mystrerror_r(10, buf, sizeof(buf)) == EINVAL);

	for (i = 0; i < 10; i++) {
		assert (mystrerror_r(i, buf, sizeof(buf)) == 0);
		printf("strerror_r[%d] = %s\n", i, buf);
	}

	return (0);
}
sam:tmp: cc -o strerror strerror.c -Wall && ./strerror
strerror_r[0] = Undefined error: 0
strerror_r[1] = Bad file descriptor
strerror_r[2] = Result too large
strerror_r[3] = Function not implemented
strerror_r[4] = Value too large to be stored in data type
strerror_r[5] = No such file or directory
strerror_r[6] = Invalid argument
strerror_r[7] = Cannot allocate memory
strerror_r[8] = Too many open files
strerror_r[9] = Device busy

Copy link
Member

@haesbaert haesbaert Oct 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh forgot to store errno on the error cases, fixed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! I agree it should be added, but as for sigfillset, if no exception raised, maybe it's not needed?

4 changes: 2 additions & 2 deletions ocaml-solo5-cross-aarch64.opam
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ build: [
"--ocaml-configure-option=--enable-flambda" {ocaml-option-flambda:installed}
"--ocaml-configure-option=--disable-naked-pointers" {ocaml-option-nnp:installed}
]
[make "-j%{jobs}%"]
[make]
]
install: [make "install" ]
depends: [
"conf-which" {build}
"ocamlfind" {build} # needed by dune context (for tests)
"ocaml-src" {build}
"ocaml" {>= "4.12.1" & < "4.15.0"}
"ocaml" {>= "4.12.1" & < "5.1"}
"solo5" {>= "0.7.0"}
"solo5-cross-aarch64" {>= "0.7.0" }
]
Expand Down
Loading