ex29 extra credit
This commit is contained in:
parent
1fdab16d96
commit
fd8e9096ae
1
lcthw-remnants-2/.gitignore
vendored
1
lcthw-remnants-2/.gitignore
vendored
@ -1,5 +1,6 @@
|
|||||||
*.dat
|
*.dat
|
||||||
ex*
|
ex*
|
||||||
|
!ex29
|
||||||
!ex*.c
|
!ex*.c
|
||||||
devpkgzed
|
devpkgzed
|
||||||
*.log
|
*.log
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include "dbg.h"
|
|
||||||
#include <dlfcn.h>
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
1
lcthw-remnants-2/ex29/.gitignore
vendored
Normal file
1
lcthw-remnants-2/ex29/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
tests/your_library_tests
|
0
lcthw-remnants-2/ex29/LICENSE
Normal file
0
lcthw-remnants-2/ex29/LICENSE
Normal file
59
lcthw-remnants-2/ex29/Makefile
Normal file
59
lcthw-remnants-2/ex29/Makefile
Normal file
@ -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
|
0
lcthw-remnants-2/ex29/README.md
Normal file
0
lcthw-remnants-2/ex29/README.md
Normal file
30
lcthw-remnants-2/ex29/src/dbg.h
Normal file
30
lcthw-remnants-2/ex29/src/dbg.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef __dbg_h__
|
||||||
|
#define __dbg_h__
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#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
|
@ -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;
|
int i = 0;
|
||||||
|
|
||||||
// BUG: \0 termination problems
|
for(i = 0; i < count; i++) {
|
||||||
for(i = 0; msg[i] != '\0'; i++) {
|
|
||||||
printf("%c", toupper(msg[i]));
|
printf("%c", toupper(msg[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,12 +24,11 @@ int uppercase(const char *msg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lowercase(const char *msg)
|
int lowercase(const char *msg, int count)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
// BUG: \0 termination problems
|
for(i = 0; i < count; i++) {
|
||||||
for(i = 0; msg[i] != '\0'; i++) {
|
|
||||||
printf("%c", tolower(msg[i]));
|
printf("%c", tolower(msg[i]));
|
||||||
}
|
}
|
||||||
|
|
48
lcthw-remnants-2/ex29/tests/ex29_tests.c
Normal file
48
lcthw-remnants-2/ex29/tests/ex29_tests.c
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "dbg.h"
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
19
lcthw-remnants-2/ex29/tests/runtests.sh
Normal file
19
lcthw-remnants-2/ex29/tests/runtests.sh
Normal file
@ -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 ""
|
Loading…
Reference in New Issue
Block a user