From fd8e9096aeeb32e4f8ee96b080be61d05b98ee50 Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Sat, 16 Apr 2016 16:00:17 -0400 Subject: [PATCH] ex29 extra credit --- lcthw-remnants-2/.gitignore | 1 + lcthw-remnants-2/ex29.c | 33 ----------- lcthw-remnants-2/ex29/.gitignore | 1 + lcthw-remnants-2/ex29/LICENSE | 0 lcthw-remnants-2/ex29/Makefile | 59 +++++++++++++++++++ lcthw-remnants-2/ex29/README.md | 0 lcthw-remnants-2/ex29/src/dbg.h | 30 ++++++++++ .../{libex29.c => ex29/src/ex29.c} | 10 ++-- lcthw-remnants-2/ex29/tests/ex29_tests.c | 48 +++++++++++++++ lcthw-remnants-2/ex29/tests/runtests.sh | 19 ++++++ 10 files changed, 162 insertions(+), 39 deletions(-) delete mode 100644 lcthw-remnants-2/ex29.c create mode 100644 lcthw-remnants-2/ex29/.gitignore create mode 100644 lcthw-remnants-2/ex29/LICENSE create mode 100644 lcthw-remnants-2/ex29/Makefile create mode 100644 lcthw-remnants-2/ex29/README.md create mode 100644 lcthw-remnants-2/ex29/src/dbg.h rename lcthw-remnants-2/{libex29.c => ex29/src/ex29.c} (64%) create mode 100644 lcthw-remnants-2/ex29/tests/ex29_tests.c create mode 100644 lcthw-remnants-2/ex29/tests/runtests.sh diff --git a/lcthw-remnants-2/.gitignore b/lcthw-remnants-2/.gitignore index 4e8f831..3860bfb 100644 --- a/lcthw-remnants-2/.gitignore +++ b/lcthw-remnants-2/.gitignore @@ -1,5 +1,6 @@ *.dat ex* +!ex29 !ex*.c devpkgzed *.log diff --git a/lcthw-remnants-2/ex29.c b/lcthw-remnants-2/ex29.c deleted file mode 100644 index ff115c5..0000000 --- a/lcthw-remnants-2/ex29.c +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include "dbg.h" -#include - -typedef int (*lib_function)(const char *data); - - -int main(int argc, char *argv[]) -{ - int rc = 0; - check(argc == 4, "USAGE: ex29 libex29.so function data"); - - char *lib_file = argv[1]; - char *func_to_run = argv[2]; - char *data = argv[3]; - - void *lib = dlopen(lib_file, RTLD_NOW); - check(lib != NULL, "Failed to open the library %s: %s", lib_file, dlerror()); - - lib_function func = dlsym(lib, func_to_run); - check(func != NULL, "Did not find %s function in the library %s: %s", func_to_run, lib_file, dlerror()); - - rc = func(data); - check(rc == 0, "Function %s return %d for data: %s", func_to_run, rc, data); - - rc = dlclose(lib); - check(rc == 0, "Failed to close %s", lib_file); - - return 0; - -error: - return 1; -} diff --git a/lcthw-remnants-2/ex29/.gitignore b/lcthw-remnants-2/ex29/.gitignore new file mode 100644 index 0000000..9b6cf51 --- /dev/null +++ b/lcthw-remnants-2/ex29/.gitignore @@ -0,0 +1 @@ +tests/your_library_tests diff --git a/lcthw-remnants-2/ex29/LICENSE b/lcthw-remnants-2/ex29/LICENSE new file mode 100644 index 0000000..e69de29 diff --git a/lcthw-remnants-2/ex29/Makefile b/lcthw-remnants-2/ex29/Makefile new file mode 100644 index 0000000..6b432a5 --- /dev/null +++ b/lcthw-remnants-2/ex29/Makefile @@ -0,0 +1,59 @@ +CFLAGS = -g -O2 -Wall -Wextra -Isrc -Lbuild -rdynamic -DNDEBUG $(OPTFLAGS) +LDLIBS = -ldl $(OPTLIBS) + +PREFIX ?= /usr/local + +SOURCES = $(wildcard src/**/*.c src/*.c) +OBJECTS = $(patsubst %.c,%.o,$(SOURCES)) + +TEST_SRC = $(wildcard tests/*_tests.c) +TESTS = $(patsubst %.c,%,$(TEST_SRC)) + +LIBNAME = ex29 +TARGET = build/lib$(LIBNAME).a +SO_TARGET = $(patsubst %.a,%.so,$(TARGET)) + +# The Target Build +all: $(TARGET) $(SO_TARGET) tests + +dev: CFLAGS = -g -Wall -Isrc -Wall -Wextra $(OPTFLAGS) +dev: all + +$(TARGET): CFLAGS += -fPIC +$(TARGET): build $(OBJECTS) + $(AR) rcs $@ $(OBJECTS) + ranlib $@ + +$(SO_TARGET): $(TARGET) $(OBJECTS) + $(CC) -shared -o $@ $(OBJECTS) + +build: + @mkdir -p build + @mkdir -p bin + +# The Unit Tests +.PHONY: tests +tests: LDLIBS += -l$(LIBNAME) +tests: $(TESTS) + sh ./tests/runtests.sh + +valgrind: + VALGRIND="valgrind --log-file=/tmp/valgrind-%p.log" $(MAKE) + +# The Cleaner +clean: + rm -rf build $(OBJECTS) $(TESTS) + rm -f tests/tests.log + find . -name "*.gc*" -exec rm {} \; + rm -rf `find . -name "*.dSYM" -print` + +# The Install +install: all + install -d $(DESTDIR)/$(PREFIX)/lib/ + install $(TARGET) $(DESTDIR)/$(PREFIX)/lib/ + +# The Checker +BADFUNCS='[^_.>a-zA-Z0-9](str(n?cpy|n?cat|xfrm|n?dup|str|pbrk|tok|_)|stpn?cpy|a?sn?printf|byte_)' +check: + @echo Files with potentially dangerous functions + @egrep $(BADFUNCS) $(SOURCES) || true diff --git a/lcthw-remnants-2/ex29/README.md b/lcthw-remnants-2/ex29/README.md new file mode 100644 index 0000000..e69de29 diff --git a/lcthw-remnants-2/ex29/src/dbg.h b/lcthw-remnants-2/ex29/src/dbg.h new file mode 100644 index 0000000..a7aaa6a --- /dev/null +++ b/lcthw-remnants-2/ex29/src/dbg.h @@ -0,0 +1,30 @@ +#ifndef __dbg_h__ +#define __dbg_h__ + +#include +#include +#include + +#ifdef NDEBUG +#define debug(M, ...) +#else +#define debug(M, ...) fprintf(stderr, "DEBUG %s:%d:%s: " M "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__) +#endif + +#define clean_errno() (errno == 0 ? "None" : strerror(errno)) + +#define log_err(M, ...) fprintf(stderr, "[ERROR] (%s:%d:%s: errno: %s) " M "\n", __FILE__, __LINE__, __func__, clean_errno(), ##__VA_ARGS__) + +#define log_warn(M, ...) fprintf(stderr, "[WARN] (%s:%d:%s: errno: %s) " M "\n", __FILE__, __LINE__, __func__, clean_errno(), ##__VA_ARGS__) + +#define log_info(M, ...) fprintf(stderr, "[INFO] (%s:%d:%s) " M "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__) + +#define check(A, M, ...) if(!(A)) { log_err(M, ##__VA_ARGS__); errno=0; goto error; } + +#define sentinel(M, ...) { log_err(M, ##__VA_ARGS__); errno=0; goto error; } + +#define check_mem(A) check((A), "Out of memory.") + +#define check_debug(A, M, ...) if(!(A)) { debug(M, ##__VA_ARGS__); errno=0; goto error; } + +#endif diff --git a/lcthw-remnants-2/libex29.c b/lcthw-remnants-2/ex29/src/ex29.c similarity index 64% rename from lcthw-remnants-2/libex29.c rename to lcthw-remnants-2/ex29/src/ex29.c index 1aafd4f..5a42d91 100644 --- a/lcthw-remnants-2/libex29.c +++ b/lcthw-remnants-2/ex29/src/ex29.c @@ -11,12 +11,11 @@ int print_a_message(const char *msg) } -int uppercase(const char *msg) +int uppercase(const char *msg, int count) { int i = 0; - // BUG: \0 termination problems - for(i = 0; msg[i] != '\0'; i++) { + for(i = 0; i < count; i++) { printf("%c", toupper(msg[i])); } @@ -25,12 +24,11 @@ int uppercase(const char *msg) return 0; } -int lowercase(const char *msg) +int lowercase(const char *msg, int count) { int i = 0; - // BUG: \0 termination problems - for(i = 0; msg[i] != '\0'; i++) { + for(i = 0; i < count; i++) { printf("%c", tolower(msg[i])); } diff --git a/lcthw-remnants-2/ex29/tests/ex29_tests.c b/lcthw-remnants-2/ex29/tests/ex29_tests.c new file mode 100644 index 0000000..c31a6d3 --- /dev/null +++ b/lcthw-remnants-2/ex29/tests/ex29_tests.c @@ -0,0 +1,48 @@ +#include +#include +#include "dbg.h" +#include + +typedef int (*lib_function)(const char *data, int count); + +int test_ex29(char *lib_file, char *func_to_run, char *data) +{ + int rc = 0; + + void *lib = dlopen(lib_file, RTLD_NOW); + check(lib != NULL, "Failed to open the library %s: %s", lib_file, dlerror()); + + lib_function func = dlsym(lib, func_to_run); + check(func != NULL, "Did not find %s function in the library %s: %s", func_to_run, lib_file, dlerror()); + + rc = func(data, (int)strlen(data)); + check(rc == 0, "Function %s return %d for data: %s", func_to_run, rc, data); + + rc = dlclose(lib); + check(rc == 0, "Failed to close %s", lib_file); + + return 0; + +error: + return 1; +} + +int main() +{ + char *dllib = getenv("EX29_DLLIB"); + if(dllib == NULL) { + dllib = "build/libex29.so"; + } + + check(test_ex29(dllib, "print_a_message", "hello there") == 0, "print failed"); + check(test_ex29(dllib, "uppercase", "hello there") == 0, "uppercase failed"); + check(test_ex29(dllib, "lowercase", "HELLO tHeRe") == 0, "lowercase failed"); + check(test_ex29(dllib, "fail_on_purpose", "i fail") == 1, "fail failed to fail"); + check(test_ex29(dllib, "fail_on_purpose", "") == 1, "fail failed to fail"); + check(test_ex29(dllib, "adfasfasdf", "asdfadff") == 1, "adfasfasdf failed to fail"); + check(test_ex29("libex.so", "adfasfasdf", "asdfadff") == 1, "libex failed to fail"); + + return 0; +error: + return 1; +} diff --git a/lcthw-remnants-2/ex29/tests/runtests.sh b/lcthw-remnants-2/ex29/tests/runtests.sh new file mode 100644 index 0000000..2976086 --- /dev/null +++ b/lcthw-remnants-2/ex29/tests/runtests.sh @@ -0,0 +1,19 @@ +echo "Running unit tests:" + +for i in tests/*_tests +do + if test -f $i + then + if $VALGRIND ./$i 2>> tests/tests.log + then + echo $i PASS + else + echo "ERROR in test $i: here's tests/tests.log" + echo "------" + tail tests/tests.log + exit 1 + fi + fi +done + +echo ""