diff --git a/.gitignore b/.gitignore index 4f4cb67..4fb95ca 100644 --- a/.gitignore +++ b/.gitignore @@ -34,4 +34,5 @@ Makefile.in *.o test_libucontext +libucontext.so libucontext.so.* diff --git a/Makefile b/Makefile index a717fa1..094ba06 100644 --- a/Makefile +++ b/Makefile @@ -13,17 +13,18 @@ LIBUCONTEXT_S_SRC = \ LIBUCONTEXT_OBJ = ${LIBUCONTEXT_C_SRC:.c=.o} ${LIBUCONTEXT_S_SRC:.S=.o} LIBUCONTEXT_SOVERSION = 0 -LIBUCONTEXT_NAME = libucontext.so.${LIBUCONTEXT_SOVERSION} -LIBUCONTEXT_PATH = /lib/${LIBUCONTEXT_NAME} +LIBUCONTEXT_NAME = libucontext.so +LIBUCONTEXT_SONAME = libucontext.so.${LIBUCONTEXT_SOVERSION} +LIBUCONTEXT_PATH = /lib/${LIBUCONTEXT_SONAME} -all: ${LIBUCONTEXT_NAME} +all: ${LIBUCONTEXT_SONAME} ${LIBUCONTEXT_NAME}: ${LIBUCONTEXT_OBJ} - $(CC) -o ${LIBUCONTEXT_NAME} -Wl,-soname,${LIBUCONTEXT_NAME} \ + $(CC) -o ${LIBUCONTEXT_NAME} -Wl,-soname,${LIBUCONTEXT_SONAME} \ -shared ${LIBUCONTEXT_OBJ} -${LOADER_NAME}: ${LOADER_OBJ} - $(CC) -o ${LOADER_NAME} -fPIE -static ${LOADER_OBJ} +${LIBUCONTEXT_SONAME}: ${LIBUCONTEXT_NAME} + ln -sf ${LIBUCONTEXT_NAME} ${LIBUCONTEXT_SONAME} .c.o: $(CC) -std=c99 -D_BSD_SOURCE -fPIC -DPIC ${CFLAGS} ${CPPFLAGS} -c -o $@ $< @@ -32,7 +33,16 @@ ${LOADER_NAME}: ${LOADER_OBJ} $(CC) -fPIC -DPIC ${CFLAGS} ${CPPFLAGS} -c -o $@ $< clean: - rm -f ${LIBUCONTEXT_NAME} ${LIBUCONTEXT_OBJ} + rm -f ${LIBUCONTEXT_NAME} ${LIBUCONTEXT_SONAME} ${LIBUCONTEXT_OBJ} install: all install -D -m755 ${LIBUCONTEXT_NAME} ${DESTDIR}/${LIBUCONTEXT_PATH} + ln -sf ${LIBUCONTEXT_SONAME} ${DESTDIR}/lib/${LIBUCONTEXT_NAME} + +check: test_libucontext ${LIBUCONTEXT_SONAME} + env LD_LIBRARY_PATH=. ./test_libucontext + +test_libucontext: ${LIBUCONTEXT_NAME} + $(CC) -std=c99 -D_BSD_SOURCE $@.c -o $@ ${LIBUCONTEXT_NAME} + +.PHONY: check diff --git a/test_libucontext.c b/test_libucontext.c new file mode 100644 index 0000000..04883ee --- /dev/null +++ b/test_libucontext.c @@ -0,0 +1,54 @@ +/* + * libucontext test program based on POSIX example program. + * Public domain. + */ + +#include +#include +#include +#include + + +static ucontext_t ctx[3]; + + +static void f1 (void) { + printf("start f1\n"); + swapcontext(&ctx[1], &ctx[2]); + printf("finish f1\n"); +} + + +static void f2 (void) { + printf("start f2\n"); + swapcontext(&ctx[2], &ctx[1]); + printf("finish f2\n"); +} + + +int main (int argc, const char *argv[]) { + char st1[8192]; + char st2[8192]; + + + memset(st1, 'A', sizeof st1); + memset(st2, 'B', sizeof st2); + + + getcontext(&ctx[1]); + ctx[1].uc_stack.ss_sp = st1; + ctx[1].uc_stack.ss_size = sizeof st1; + ctx[1].uc_link = &ctx[0]; + makecontext(&ctx[1], f1, 0); + + + getcontext(&ctx[2]); + ctx[2].uc_stack.ss_sp = st2; + ctx[2].uc_stack.ss_size = sizeof st2; + ctx[2].uc_link = &ctx[1]; + makecontext(&ctx[2], f2, 0); + + + swapcontext(&ctx[0], &ctx[2]); + return 0; +}