Removed submodules

This commit is contained in:
2026-05-31 14:34:00 -04:00
commit 46c36b11da
352 changed files with 14792 additions and 0 deletions
+20
View File
@@ -0,0 +1,20 @@
# Ignore all compiled files regardless of location
**/*.o
# But not the private.o
!tests/private.o
# Ignore executables for this project
procs
testsuite
# Ignore test outputs
tests/ckstyle
tests/itests.txt
tests/outputs
tests/style.txt
tests/valgrind
tests/utests.txt
**/.nfs*
**/.vscode
+51
View File
@@ -0,0 +1,51 @@
#
# Simple Makefile
# Mike Lam, James Madison University, August 2016
#
# This makefile builds a simple application that contains a main module
# (specified by the EXE variable) and a predefined list of additional modules
# (specified by the MODS variable). If there are any external library
# dependencies (e.g., the math library, "-lm"), list them in the LIBS variable.
# If there are any precompiled object files, list them in the OBJS variable.
#
# By default, this makefile will build the project with debugging symbols and
# without optimization. To change this, edit or remove the "-g" and "-O0"
# options in CFLAGS and LDFLAGS accordingly.
#
# By default, this makefile build the application using the GNU C compiler,
# adhering to the C99 standard with all warnings enabled.
# application-specific settings and run target
EXE=procs
MODS=signals.o child.o
OBJS=
LIBS=
default: $(EXE)
test: $(EXE)
make -C tests test
# compiler/linker settings
CC=gcc
CFLAGS=-g -O0 -Wall -Werror --std=c99 -pedantic -D_POSIX_SOURCE
LDFLAGS=-g -O0 -pthread
# build targets
$(EXE): main.o $(MODS) $(OBJS)
$(CC) $(LDFLAGS) -o $(EXE) $^ $(LIBS)
%.o: %.c
$(CC) -c $(CFLAGS) $<
clean:
rm -f $(EXE) main.o $(MODS)
make -C tests clean
.PHONY: default clean
+39
View File
@@ -0,0 +1,39 @@
#include <assert.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
#include "child.h"
pid_t
run_child (int rc)
{
char *str = "I am the parent";
// TODO: Add code here to create a child process that prints
// "I am the child" and exits with return code passed as the rc
// parameter to this function. The parent must wait for the child
// to finish before printing the child's exit status (consult the
// textbook for this as needed) before printing "I am the parent".
// The parent should return the child's PID from this function.
int status = 0;
pid_t pid = fork ();
if (pid == 0)
{
printf ("I am the child\n");
exit (rc);
}
else
{
waitpid (pid, &status, 0);
}
printf ("Child exited with status %d\n", WEXITSTATUS (status));
printf ("%s\n", str);
return pid;
}
+6
View File
@@ -0,0 +1,6 @@
#ifndef __CS361_CHILD_H__
#define __CS361_CHILD_H__
pid_t run_child (int);
#endif
+87
View File
@@ -0,0 +1,87 @@
/*
* CS 361: Process management lab
*
* Name:
*/
#include <assert.h>
#include <getopt.h>
#include <inttypes.h>
#include <semaphore.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include "child.h"
#include "signals.h"
#define SIGNAL_MAX 20
int cmdline (int, char **, int *, char **);
void
usage (void)
{
printf ("Usage: procs [option]\n");
printf (" Options are:\n");
printf (" -e N Create a child that exits with status N\n");
printf (" -s N Override signal number N and run signal handler\n");
printf ("\n Default is to create a child process with normal exit\n");
}
int
main (int argc, char **argv)
{
char *signal_override = NULL;
int rc = 42;
if (cmdline (argc, argv, &rc, &signal_override) < 0)
{
usage ();
return EXIT_FAILURE;
}
// Set up a timeout to kill the process after 5 seconds
struct itimerval timeout;
memset (&timeout, 0, sizeof (timeout));
timeout.it_value.tv_sec = 5;
timeout.it_value.tv_usec = 0;
setitimer (ITIMER_REAL, &timeout, NULL);
if (signal_override == NULL)
run_child (rc);
else
override (signal_override);
return EXIT_SUCCESS;
}
/* DO NOT MODIFY THIS FUNCTION. Parses the command line arguments to get
the portion of the lab to run. */
int
cmdline (int argc, char **argv, int *rc, char **sig)
{
int option;
while ((option = getopt (argc, argv, "e:s:")) != -1)
{
switch (option)
{
case 'e':
*rc = (int)strtol (optarg, NULL, 10);
break;
case 's':
*sig = optarg;
break;
default:
return -1;
}
}
return 0;
}
+110
View File
@@ -0,0 +1,110 @@
#include <assert.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/prctl.h>
#include <sys/wait.h>
#include <unistd.h>
#include "signals.h"
static void catch_loop (int);
/* Convert the short signal name (NNN part of SIGNNN) to its number.
Consult /usr/include/asm/signal.h for the number mappings. For
this lab, hard-code the numbers; do not use the numeric constants.
Return -1 if the name isn't one you need to look up. */
int
signal_lookup (char *name)
{
// TODO: Look up the numbers for INT, SEGV, KILL, and TSTP
if (strcmp (name, "INT") == 0)
return 2;
if (strcmp (name, "SEGV") == 0)
return 11;
if (strcmp (name, "KILL") == 0)
return 9;
if (strcmp (name, "TSTP") == 0)
return 20;
return -1;
}
// Entry point for overriding a signal handler in this lab.
void
override (char *signal)
{
int sig = signal_lookup (signal);
if (sig == SIGKILL)
printf ("Received bad signal name: %s\n", signal);
else
catch_loop (sig);
}
// Generic signal handler. This function doesn't use the signal number
// in the provided distribution.
void
sig_handler (int signum __attribute__ ((unused)))
{
// TODO: Complete this signal handler so that it writes the message
// "Breaking out with signal %d\n" with the signal number that was
// passed. Note that you cannot use printf() in a signal handler.
// You must use write(). After writing the message, exit with return
// code 37.
//
// HINT: If you fail integration tests and get a message that the
// binary files are different, you may be writing an extra byte (the
// null byte). You can make sure you avoid this by using strlen()
// instead of trying to hard-code a length.
char buf[128];
snprintf (buf, 128, "Breaking out with signal %d\n", signum);
write (STDOUT_FILENO, buf, strlen (buf));
exit (37);
}
void
catch_loop (int signum)
{
// sigaction(signum)
// TODO: Override the signal handler for the signal number passed.
// Then create a child that runs the following code:
// prctl (PR_SET_PDEATHSIG, SIGKILL);
// printf ("Child has started\n");
// fflush (stdout);
// while (1) ;
struct sigaction sa = { 0 };
sa.sa_handler = sig_handler;
sigaction (signum, &sa, NULL);
pid_t pid = fork ();
if (pid == 0)
{
prctl (PR_SET_PDEATHSIG, SIGKILL);
printf ("Child has started\n");
fflush (stdout);
while (1)
pause ();
}
// HINT: You will NOT call sig_handler() directly here. Instead,
// you must use sigaction() to modify the signal's interrupt handler
// so that sig_handler() will be called later when the signal occurs.
// After starting the child, the parent will call sleep (1) to wait
// for 1 second before sending the signal to the child. The parent
// must wait for the child to run (and exit), then print
// "Child was stopped with status %d\n" with the child process's exit
// status code, retrieved with waitpid(). Note that you will need to
// call WEXITSTATUS() on the retrieved status code.
sleep (1);
int status = 0;
kill (pid, signum);
waitpid (pid, &status, 0);
printf ("Child was stopped with status %d\n", WEXITSTATUS (status));
}
+7
View File
@@ -0,0 +1,7 @@
#ifndef __CS361_SIGNALS_H__
#define __CS361_SIGNALS_H__
void override (char *);
int signal_lookup (char *);
#endif
+87
View File
@@ -0,0 +1,87 @@
#
# Simple Test Makefile
# Mike Lam, James Madison University, August 2016
#
# This version of the Makefile includes support for building a test suite. The
# recommended framework is Check (http://check.sourceforge.net/). To build and
# run the test suite, execute the "test" target. The test suite must be located
# in a module called "testsuite". The MODS, LIBS, and OBJS variables work as
# they do in the main Makefile.
#
# To change the default build target (which executes when you just type
# "make"), change the right-hand side of the definition of the "default"
# target.
#
# By default, this makefile will build the project with debugging symbols and
# without optimization. To change this, edit or remove the "-g" and "-O0"
# options in CFLAGS and LDFLAGS accordingly.
#
# By default, this makefile build the application using the GNU C compiler,
# adhering to the C99 standard with all warnings enabled.
# application-specific settings and run target
EXE=../sigs
TEST=testsuite
MODS=public.o
OBJS=../signals.o ../child.o
LIBS=
UTESTOUT=utests.txt
ITESTOUT=itests.txt
SCHECKOUT=style.txt
default: $(TEST)
$(EXE):
make -C ../
test: utest itest style
@echo "========================================"
utest: $(EXE) $(TEST)
@echo "========================================"
@echo " UNIT TESTS"
@./$(TEST) 2>/dev/null >$(UTESTOUT)
@cat $(UTESTOUT) | sed -n -e '/Checks/,$$p' | sed -e 's/^private.*:[EF]://g'
itest: $(EXE)
@echo "========================================"
@echo " INTEGRATION TESTS"
@./integration.sh | tee $(ITESTOUT)
style: $(EXE)
@echo "========================================"
@echo " CODING STYLE CHECK"
@./style.sh 2>/dev/null >$(SCHECKOUT)
@cat $(SCHECKOUT)
# compiler/linker settings
CC=gcc
CFLAGS=-g -O0 -Wall --std=c99 -pedantic
LDFLAGS=-g -O0
CFLAGS+=-I/opt/local/include -Wno-gnu-zero-variadic-macro-arguments
LDFLAGS+=-L/opt/local/lib
LIBS+=-lcheck -lm -lpthread
ifeq ($(shell uname -s),Linux)
LIBS+=-lrt -lsubunit
endif
# build targets
$(TEST): $(TEST).o $(MODS) $(OBJS)
$(CC) $(LDFLAGS) -o $(TEST) $^ $(LIBS)
%.o: %.c
$(CC) -c $(CFLAGS) $<
clean:
rm -rf $(TEST) $(TEST).o $(MODS) $(UTESTOUT) $(ITESTOUT) $(SCHECKOUT) outputs valgrind
.PHONY: default clean test unittest inttest
@@ -0,0 +1 @@
6037b06b79a54f57617de151d505444f78a23489
+1
View File
@@ -0,0 +1 @@
ebef9658a6b46bd9cfcfeaf732a6d2444fe0b98a
@@ -0,0 +1 @@
145cbab85e3834cf39635245272d5f80e6bd66f2
@@ -0,0 +1 @@
b4ec94fbc4feb8f7ce089341bd6c51e775fce9e1
@@ -0,0 +1 @@
fb52530bd8b6756b4acec57a42391f8b7c9c0e83
+3
View File
@@ -0,0 +1,3 @@
I am the child
Child exited with status 42
I am the parent
+1
View File
@@ -0,0 +1 @@
Received bad signal name: KILL
@@ -0,0 +1,3 @@
Child has started
Breaking out with signal 11
Child was stopped with status 37
@@ -0,0 +1,3 @@
Child has started
Breaking out with signal 2
Child was stopped with status 37
@@ -0,0 +1,3 @@
I am the child
Child exited with status 54
I am the parent
+75
View File
@@ -0,0 +1,75 @@
#!/bin/bash
EXE="../procs"
function run_test {
# parameters
TAG=$1
ARGS=$2
# file paths
OUTPUT=outputs/$TAG.txt
DIFF=outputs/$TAG.diff
EXPECT=expected/$TAG.txt
VALGRND=valgrind/$TAG.txt
# print tag format
PTAG=$(printf '%-30s' "$TAG")
# check for expected text that needs to be fixed
if [ ! -z "$(egrep "<<<<.*>>>>" "$EXPECT")" ] ; then
echo "$PTAG FAIL ($EXPECT not correct)"
return
fi
# compare the file
SHAOUT=$(shasum "$EXPECT" | awk '{print $1}')
SHAEXP=$(cat "expected/.$TAG.sha")
if [ "$SHAOUT" != "$SHAEXP" ] ; then
echo "$PTAG FAIL (expected file is not correct)"
return
fi
# run test and compare output to the expected version
$EXE $ARGS 2>/dev/null >"$OUTPUT"
diff -u "$OUTPUT" "$EXPECT" >"$DIFF"
if [ -s "$DIFF" ]; then
# try alternative solution (if it exists)
EXPECT=expected/$TAG-2.txt
if [ -e "$EXPECT" ]; then
diff -u "$OUTPUT" "$EXPECT" >"$DIFF"
if [ -s "$DIFF" ]; then
echo "$PTAG FAIL (see $DIFF for details)"
else
echo "$PTAG pass"
fi
else
echo "$PTAG FAIL (see $DIFF for details)"
fi
else
echo "$PTAG pass"
fi
# run valgrind
valgrind $EXE $ARGS &>$VALGRND
}
# initialize output folders
mkdir -p outputs
mkdir -p valgrind
rm -f outputs/* valgrind/*
# run individual tests
source itests.include
# check for memory leaks
LEAK=`cat valgrind/*.txt | grep 'definitely lost' | grep -v ' 0 bytes in 0 blocks'`
if [ -z "$LEAK" ]; then
echo "No memory leak found."
else
echo "Memory leak(s) found. See files listed below for details."
grep 'definitely lost' valgrind/*.txt | grep -v ' 0 bytes in 0 blocks' | sed -e 's/:.*$//g' | sed -e 's/^/ - /g'
fi
+10
View File
@@ -0,0 +1,10 @@
# list of integration tests
# format: run_test <TAG> <ARGS>
# <TAG> used as the root for all filenames (i.e., "expected/$TAG.txt")
# <ARGS> command-line arguments to test
run_test INTEG_child ""
run_test INTEG_status "-e 54"
run_test INTEG_sigint "-s INT"
run_test INTEG_segfault "-s SEGV"
run_test INTEG_kill "-s KILL"
Binary file not shown.
+46
View File
@@ -0,0 +1,46 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <signal.h>
#include <check.h>
#include "../signals.h"
START_TEST (UNIT_good_signals)
{
printf ("\n======================================\n");
printf ("UNIT good signals\n");
printf ("This test checks for signal name lookups\n");
char *names[] = { "INT", "KILL", "SEGV", "TSTP" };
int signals[] = { SIGINT, SIGKILL, SIGSEGV, SIGTSTP };
for (int i = 0; i < 4; i++)
{
int sig = signal_lookup (names[i]);
ck_assert_int_eq (signals[i], sig);
}
}
END_TEST
START_TEST (UNIT_bad_signals)
{
printf ("\n======================================\n");
printf ("UNIT bad signals\n");
printf ("This test checks for other signal name lookups\n");
char *names[] = { "HUP", "ALRM", "ILL", "KIL" };
for (int i = 0; i < 4; i++)
{
int sig = signal_lookup (names[i]);
ck_assert_int_eq (sig, -1);
}
}
END_TEST
void public_tests (Suite *s)
{
TCase *tc_public = tcase_create ("Public");
tcase_add_test (tc_public, UNIT_good_signals);
tcase_add_test (tc_public, UNIT_bad_signals);
suite_add_tcase (s, tc_public);
}
+53
View File
@@ -0,0 +1,53 @@
#!/bin/bash
STYLE="gnu"
IGNORE=()
FAIL=0
function comp_file {
SRC=$1
SRC_NAME=$2
# file paths
FORMAT=ckstyle/${SRC_NAME}.$STYLE
DIFF=ckstyle/${SRC_NAME}.diff
# run clang-format and compare results
clang-format --style=$STYLE $source > $FORMAT
diff -u $SRC $FORMAT >$DIFF
PTAG=$(printf '%-30s' "$SRC_NAME")
if [ -s $DIFF ]; then
echo "$PTAG FAIL (see $DIFF for details)"
FAIL=1
else
echo "$PTAG pass"
rm $DIFF
fi
rm $FORMAT
}
mkdir -p ckstyle
rm -f ckstyle/*
for source in $(ls ../*.c ../*.h) ; do
SKIP=0
src=$(basename $source)
for ignore in ${IGNORE[*]} ; do
if [ "$src" = "$ignore" ] ; then
SKIP=1
fi
done
if [ $SKIP = 0 ] ; then
comp_file $source $src
fi
done
if [ $FAIL != 0 ] ; then
echo "Code that does not adhere to GNU standards will not be accepted."
echo "You must fix these files before submission."
else
echo "Code correctly adheres to required style."
fi
+34
View File
@@ -0,0 +1,34 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
#include <time.h>
#include <check.h>
extern void public_tests (Suite *s);
//extern void private_tests (Suite *s);
Suite * test_suite (void)
{
Suite *s = suite_create ("Default");
public_tests (s);
//private_tests (s);
return s;
}
void run_testsuite ()
{
Suite *s = test_suite ();
SRunner *sr = srunner_create (s);
srunner_run_all (sr, CK_NORMAL);
srunner_free (sr);
}
int main (void)
{
srand((unsigned)time(NULL));
run_testsuite ();
return EXIT_SUCCESS;
}