summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVirtual Student <Cisco_vX78@laptop4.(none)>2016-06-21 12:27:39 -0400
committerVirtual Student <Cisco_vX78@laptop4.(none)>2016-06-21 12:27:39 -0400
commit5cfa2b1d9ed0ba4e35d051b1f5bd1ad8cae237fb (patch)
treecd6ddfb1a5318212d8b208ce32e504eea5dccc6b
initial commit
-rw-r--r--lab01/Makefile.debug08
-rw-r--r--lab01/Makefile.debug18
-rw-r--r--lab01/Makefile.hello8
-rw-r--r--lab01/debug0.c18
-rw-r--r--lab01/debug1.c25
-rw-r--r--lab04/Makefile8
-rw-r--r--lab04/mmu-solution.c22
-rw-r--r--lab04/mmu.c20
-rw-r--r--lab05/Makefile20
-rw-r--r--lab05/procs-solution.c18
-rw-r--r--lab05/procs.c22
-rw-r--r--lab05/sched-solution.c92
-rw-r--r--lab05/sched.c74
-rw-r--r--lab05/threads-solution.c52
-rw-r--r--lab05/threads.c59
-rw-r--r--lab06/Makefile8
-rw-r--r--lab06/server-solution.c59
-rw-r--r--lab06/server.c58
-rw-r--r--lab07/Makefile24
-rw-r--r--lab07/Makefile.libuser17
-rw-r--r--lab07/solution/Makefile.libuser.solution17
-rw-r--r--lab07/solution/Makefile.solution24
-rw-r--r--lab07/solution/libuser.c.solution18
-rw-r--r--lab07/test1.c4
-rw-r--r--lab07/test2.c4
-rw-r--r--lab07/test3.c4
-rw-r--r--lab08/Makefile.mutex11
-rw-r--r--lab08/Makefile.rec11
-rw-r--r--lab08/Makefile.snd11
-rw-r--r--lab08/mutex-solution.c212
-rw-r--r--lab08/mutex.c212
-rw-r--r--lab08/rec-solution.c83
-rw-r--r--lab08/rec.c72
-rw-r--r--lab08/snd-solution.c60
-rw-r--r--lab08/snd.c58
-rw-r--r--lab09/Makefile8
-rw-r--r--lab09/timer-solution.c35
-rw-r--r--lab09/timer.c33
-rw-r--r--lab10/Makefile8
-rw-r--r--lab10/net-solution.c103
-rw-r--r--lab10/net.c100
-rw-r--r--make/app-rules.mk12
-rw-r--r--make/defaults.mk3
43 files changed, 1723 insertions, 0 deletions
diff --git a/lab01/Makefile.debug0 b/lab01/Makefile.debug0
new file mode 100644
index 0000000..7ec22c3
--- /dev/null
+++ b/lab01/Makefile.debug0
@@ -0,0 +1,8 @@
+
+APP = debug0
+
+#############################################################################
+
+include ../make/defaults.mk
+include ../make/app-rules.mk
+
diff --git a/lab01/Makefile.debug1 b/lab01/Makefile.debug1
new file mode 100644
index 0000000..e110b8d
--- /dev/null
+++ b/lab01/Makefile.debug1
@@ -0,0 +1,8 @@
+
+APP = debug1
+
+#############################################################################
+
+include ../make/defaults.mk
+include ../make/app-rules.mk
+
diff --git a/lab01/Makefile.hello b/lab01/Makefile.hello
new file mode 100644
index 0000000..a0ed998
--- /dev/null
+++ b/lab01/Makefile.hello
@@ -0,0 +1,8 @@
+
+APP = hello
+
+#############################################################################
+
+include ../make/defaults.mk
+include ../make/app-rules.mk
+
diff --git a/lab01/debug0.c b/lab01/debug0.c
new file mode 100644
index 0000000..61ada07
--- /dev/null
+++ b/lab01/debug0.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <string.h>
+int *a;
+
+int main(int argc, char *argv[])
+{
+ int x=5;
+ int y;
+
+ sleep(4);
+
+ y = atoi(argv[1]);
+
+ printf("Hello World! x=%d, y=%d\n", x,y);
+
+ return(0);
+}
+
diff --git a/lab01/debug1.c b/lab01/debug1.c
new file mode 100644
index 0000000..198cf96
--- /dev/null
+++ b/lab01/debug1.c
@@ -0,0 +1,25 @@
+#include <stdio.h>
+
+int *a;
+
+void a_badidea(void);
+
+int main(int argc, char *argv[])
+{
+ int x=5;
+
+ int y;
+ int z = 16;
+
+ a_badidea();
+
+ printf("Hello World! x=%d, y=%d\n", x,y);
+
+ return(0);
+}
+
+void a_badidea (void)
+{
+ int z = 16;
+ *a = z;
+}
diff --git a/lab04/Makefile b/lab04/Makefile
new file mode 100644
index 0000000..120f406
--- /dev/null
+++ b/lab04/Makefile
@@ -0,0 +1,8 @@
+
+APP = mmu
+
+#############################################################################
+
+include ../make/defaults.mk
+include ../make/app-rules.mk
+
diff --git a/lab04/mmu-solution.c b/lab04/mmu-solution.c
new file mode 100644
index 0000000..6bb6768
--- /dev/null
+++ b/lab04/mmu-solution.c
@@ -0,0 +1,22 @@
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int bssvar;
+int datavar = 99;
+
+int main()
+{
+ int stackvar;
+ char *mallocptr = malloc(100);
+
+ printf("\n");
+ printf("Address of bss section var = 0x%08x\n", (unsigned)&bssvar);
+ printf("Address of data section var = 0x%08x\n", (unsigned)&datavar);
+ printf("Address of stack var = 0x%08x\n", (unsigned)&stackvar);
+ printf("Address of malloc'd space = 0x%08x\n", (unsigned)mallocptr);
+
+ while (1) {
+ sleep(10);
+ }
+}
diff --git a/lab04/mmu.c b/lab04/mmu.c
new file mode 100644
index 0000000..d8dc198
--- /dev/null
+++ b/lab04/mmu.c
@@ -0,0 +1,20 @@
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int bssvar;
+int datavar = 99;
+
+int main()
+{
+ int stackvar;
+ char *mallocptr = malloc(100);
+
+ printf("\n");
+ // print addresses of stack, BSS, data, heap segments
+
+ // for extra credit, print the address of the code segment
+ while (1) {
+ sleep(10);
+ }
+}
diff --git a/lab05/Makefile b/lab05/Makefile
new file mode 100644
index 0000000..67298b5
--- /dev/null
+++ b/lab05/Makefile
@@ -0,0 +1,20 @@
+
+#############################################################################
+
+include ../make/defaults.mk
+
+clean:
+ rm -f procs threads $(DESTDIR)/procs $(DESTDIR)/threads
+
+procs: procs.c Makefile
+ $(CC) -o $@ $<
+ cp procs $(DESTDIR)
+
+threads: threads.c Makefile
+ $(CC) -o $@ $< -lpthread
+ cp threads $(DESTDIR)
+
+sched: sched.c Makefile
+ $(CC) -o $@ $< -lpthread
+ cp sched $(DESTDIR)
+
diff --git a/lab05/procs-solution.c b/lab05/procs-solution.c
new file mode 100644
index 0000000..cf1a9ff
--- /dev/null
+++ b/lab05/procs-solution.c
@@ -0,0 +1,18 @@
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+
+int global;
+
+int main()
+{
+ if (fork()) { /* only the 1st parent enters here */
+ fork(); /* ...to fork() a 2nd child... */
+ }
+
+ /* All 3 processes (parent and children) run the following */
+
+ global = getpid(); /* set to a process-specific value */
+ sleep(1);
+ printf("PID is %d, global = %d\n", getpid(), global);
+}
diff --git a/lab05/procs.c b/lab05/procs.c
new file mode 100644
index 0000000..9128b19
--- /dev/null
+++ b/lab05/procs.c
@@ -0,0 +1,22 @@
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+
+int global;
+
+int main()
+{
+ /*
+ Have the parent fork() a child twice
+ Use the return value of fork() to make sure you're the
+ parent before forking a second child
+ */
+
+ /* Your code here */
+
+ /* All 3 processes (parent and children) run the following */
+
+ global = getpid(); /* set to a process-specific value */
+ sleep(1);
+ printf("PID is %d, global = %d\n", getpid(), global);
+}
diff --git a/lab05/sched-solution.c b/lab05/sched-solution.c
new file mode 100644
index 0000000..99b148b
--- /dev/null
+++ b/lab05/sched-solution.c
@@ -0,0 +1,92 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+volatile pthread_t running;
+volatile int thread_switches;
+volatile int done = 0;
+
+void * thread(void *x)
+{
+ pthread_t self = pthread_self();
+ long long self_count = 0;
+ long long avg = 0;
+ int avg_calculations = 0;
+
+ /* let all threads start */
+ sleep(1);
+
+ while(1) {
+ if (running == self) { /* still this thread running */
+ self_count++;
+ /*
+ * Safety net -- when running high priority we can prevent
+ * main() from running and stopping the program.
+ */
+ if (self_count > 100000000) break;
+ } else { /* just switched to this thread */
+ running = self;
+ thread_switches++;
+
+ if(self_count)
+ {
+ /* Re-calculate average */
+ avg *= avg_calculations;
+ avg += self_count;
+ avg_calculations++;
+ avg /= avg_calculations;
+ }
+
+ /*
+ * Another safety net
+ */
+ if (done || (thread_switches > 300)) break;
+
+ self_count = 1;
+ }
+ }
+ printf("Thread %d exiting, average count between switches = %lld, self_count = %lld\n",
+ *(int *)x, avg, self_count);
+ pthread_exit((void*) 0);
+}
+
+int main(void)
+{
+ void *status;
+ pthread_attr_t attr;
+ pthread_t t1, t2;
+ struct sched_param param;
+ int one=1;
+ int two=2;
+
+ /* Add your scheduler setup logic here */
+ pthread_attr_init(&attr);
+ pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
+
+ /* Use this line for the first run only */
+ pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
+ /* End of first run only code */
+
+ /* Use these lines for the second run only */
+// pthread_attr_setschedpolicy(&attr, SCHED_RR);
+// param.sched_priority = 10;
+// pthread_attr_setschedparam(&attr, &param);
+ /* End of second run only code */
+
+ /* Use these lines for the third run only */
+// pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
+// param.sched_priority = 10;
+// pthread_attr_setschedparam(&attr, &param);
+ /* End of third run only code */
+
+ if (pthread_create(&t1, &attr, thread, &one)) exit(1);
+ if (pthread_create(&t2, &attr, thread, &two)) exit(1);
+
+ sleep(10); /* let program run 10 seconds */
+ done = 1;
+ pthread_join(t1, &status);
+ pthread_join(t2, &status);
+ printf("Total thread switches: %d\n", thread_switches);
+ exit(0);
+}
diff --git a/lab05/sched.c b/lab05/sched.c
new file mode 100644
index 0000000..ee0d1ac
--- /dev/null
+++ b/lab05/sched.c
@@ -0,0 +1,74 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+volatile pthread_t running;
+volatile int thread_switches;
+volatile int done = 0;
+
+void * thread(void *x)
+{
+ pthread_t self = pthread_self();
+ long long self_count = 0;
+ long long avg = 0;
+ int avg_calculations = 0;
+
+ /* let all threads start */
+ sleep(1);
+
+ while(1) {
+ if (running == self) { /* still this thread running */
+ self_count++;
+ /*
+ * Safety net -- when running high priority we can prevent
+ * main() from running and stopping the program.
+ */
+ if (self_count > 100000000) break;
+ } else { /* just switched to this thread */
+ running = self;
+ thread_switches++;
+
+ if(self_count)
+ {
+ /* Re-calculate average */
+ avg *= avg_calculations;
+ avg += self_count;
+ avg_calculations++;
+ avg /= avg_calculations;
+ }
+
+ /*
+ * Another safety net
+ */
+ if (done || (thread_switches > 300)) break;
+
+ self_count = 1;
+ }
+ }
+ printf("Thread %d exiting, average count between switches = %lld, self_count = %lld\n",
+ *(int *)x, avg, self_count);
+ pthread_exit((void*) 0);
+}
+
+int main(void)
+{
+ void *status;
+ pthread_attr_t attr;
+ pthread_t t1, t2;
+ struct sched_param param;
+ int one=1;
+ int two=2;
+
+ /* Add your scheduler setup logic here */
+
+ if (pthread_create(&t1, &attr, thread, &one)) exit(1);
+ if (pthread_create(&t2, &attr, thread, &two)) exit(1);
+
+ sleep(10); /* let program run 10 seconds */
+ done = 1;
+ pthread_join(t1, &status);
+ pthread_join(t2, &status);
+ printf("Total thread switches: %d\n", thread_switches);
+ exit(0);
+}
diff --git a/lab05/threads-solution.c b/lab05/threads-solution.c
new file mode 100644
index 0000000..7437c0f
--- /dev/null
+++ b/lab05/threads-solution.c
@@ -0,0 +1,52 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+int global;
+
+void * thread(void *joiner)
+{
+ void *status;
+
+ global = pthread_self();
+ sleep(1);
+ printf("Parent PID is %d, TID is %d, global = %d\n",
+ getppid(), pthread_self(), global);
+
+ if (joiner) {
+ if (pthread_join((pthread_t)joiner, &status)) {
+ exit(1);
+ }
+ }
+
+ pthread_exit((void*) 0);
+}
+
+int main(void)
+{
+ void *status;
+ int x;
+ pthread_attr_t attr;
+ pthread_t curr_thr_id;
+ pthread_t prev_thr_id;
+
+ if (pthread_attr_init(&attr)) {
+ exit(1);
+ }
+ if (pthread_attr_setschedpolicy(&attr, SCHED_RR)) {
+ exit(1);
+ }
+
+ /* Start 3 threads */
+ prev_thr_id = 0;
+ for (x=0; x<3; x++) {
+ if (pthread_create(&curr_thr_id, &attr, thread, (void*)prev_thr_id)) {
+ exit(1);
+ }
+ prev_thr_id = curr_thr_id;
+ }
+
+ /* Join last thread */
+ pthread_join(curr_thr_id, &status);
+}
diff --git a/lab05/threads.c b/lab05/threads.c
new file mode 100644
index 0000000..feee49c
--- /dev/null
+++ b/lab05/threads.c
@@ -0,0 +1,59 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+int global;
+
+void * thread(void *joiner)
+{
+ void *status;
+
+ global = pthread_self();
+ sleep(1);
+ printf("Parent PID is %d, TID is %d, global = %d\n",
+ getppid(), pthread_self(), global);
+
+ if (joiner) {
+ if (pthread_join((pthread_t)joiner, &status)) {
+ exit(1);
+ }
+ }
+
+ pthread_exit((void*) 0);
+}
+
+int main(void)
+{
+ void *status;
+ int x;
+ pthread_attr_t attr;
+ pthread_t curr_thr_id;
+ pthread_t prev_thr_id;
+
+ if (pthread_attr_init(&attr)) {
+ exit(1);
+ }
+ if (pthread_attr_setschedpolicy(&attr, SCHED_OTHER)) {
+ exit(1);
+ }
+
+ /* Start 3 threads */
+ prev_thr_id = 0;
+ for (x=0; x<3; x++) {
+ /*
+ Fill in the code ala ...
+ if (pthread_create(&currentThreadID, &attribute,
+ thread, (void*)previousThreadID)) {
+ exit(1);
+ }
+ */
+
+ /* insert your code here */
+
+ prev_thr_id = curr_thr_id;
+ }
+
+ /* Join last thread */
+ pthread_join(curr_thr_id, &status);
+}
diff --git a/lab06/Makefile b/lab06/Makefile
new file mode 100644
index 0000000..aaa4bdf
--- /dev/null
+++ b/lab06/Makefile
@@ -0,0 +1,8 @@
+
+APP = server
+
+#############################################################################
+
+include ../make/defaults.mk
+include ../make/app-rules.mk
+
diff --git a/lab06/server-solution.c b/lab06/server-solution.c
new file mode 100644
index 0000000..0a0cbed
--- /dev/null
+++ b/lab06/server-solution.c
@@ -0,0 +1,59 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <syslog.h>
+#include <time.h>
+
+static void daemonize(void)
+{
+ int i;
+
+ /* fork once to go into the background */
+ switch(fork())
+ {
+ case 0: break; /* child */
+ case -1: exit(1); /* error */
+ default: exit(0); /* parent */
+ }
+
+ /* get a new process group/session, no controlling terminal */
+ if(setsid()<0) exit(1);
+
+ /* change the file mode mask */
+ umask(0);
+
+ /* close all descriptors */
+ for (i=sysconf(_SC_OPEN_MAX);i>=0;--i) close(i);
+
+ /* run in a specific directory */
+ chdir("/");
+
+ /* redirect stdio */
+ open ("/dev/null",O_RDWR);
+ (void) dup(0);
+ (void) dup(0);
+
+ /* we are now a daemon */
+}
+
+void hup_handler(int x)
+{
+ syslog(LOG_DAEMON | LOG_INFO, "Server received SIGHUP at %d\n",
+ time(0));
+ signal(SIGHUP, hup_handler);
+}
+
+int main()
+{
+ daemonize();
+ if (signal(SIGHUP, hup_handler) == SIG_ERR) {
+ syslog(LOG_DAEMON | LOG_INFO, "Server failed to install signal handler\n");
+ }
+
+ while(1) {
+ sleep(1);
+ }
+}
diff --git a/lab06/server.c b/lab06/server.c
new file mode 100644
index 0000000..978db64
--- /dev/null
+++ b/lab06/server.c
@@ -0,0 +1,58 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <syslog.h>
+#include <time.h>
+
+static void daemonize(void)
+{
+ int i;
+
+ /* fork once to go into the background */
+ switch(fork())
+ {
+ case 0: break; /* child */
+ case -1: exit(1); /* error */
+ default: exit(0); /* parent */
+ }
+
+ /* get a new process group/session, no controlling terminal */
+ if(setsid()<0) exit(1);
+
+ /* change the file mode mask */
+ umask(0);
+
+ /* close all descriptors */
+ for (i=sysconf(_SC_OPEN_MAX);i>=0;--i) close(i);
+
+ /* run in a specific directory */
+ chdir("/");
+
+ /* redirect stdio */
+ open ("/dev/null",O_RDWR);
+ (void) dup(0);
+ (void) dup(0);
+
+ /* we are now a daemon */
+}
+
+void hup_handler(int x)
+{
+ syslog(LOG_DAEMON | LOG_INFO, "Server received SIGHUP at %d\n",
+ time(0));
+ signal(SIGHUP, hup_handler);
+}
+
+int main()
+{
+ /* insert code to daemonize here */
+
+ /* install signal handler here */
+
+ while(1) {
+ sleep(1);
+ }
+}
diff --git a/lab07/Makefile b/lab07/Makefile
new file mode 100644
index 0000000..9137600
--- /dev/null
+++ b/lab07/Makefile
@@ -0,0 +1,24 @@
+CC=/home/student/crosstools/arm-2010.09/bin/arm-none-linux-gnueabi-gcc
+
+all: install
+
+# link .o's together with correct soname and real name
+libmy-utils.so.1.0 : test1.o test2.o test3.o
+ $(CC)
+
+test1.o : test1.c # compile test1 w/ correct flags and output test1.o
+ $(CC)
+
+test2.o : test2.c # compile test2 w/ correct flags and output test2.o
+ $(CC)
+
+test3.o : test3.c # compile test3 w/ correct flags and output test3.o
+ $(CC)
+
+clean:
+ rm -f *.o *.so.*
+
+install: libmy-utils.so.1.0
+ cp $< /home/student/targetfs/usr/local/lib
+
+
diff --git a/lab07/Makefile.libuser b/lab07/Makefile.libuser
new file mode 100644
index 0000000..713cc94
--- /dev/null
+++ b/lab07/Makefile.libuser
@@ -0,0 +1,17 @@
+APP = libuser
+
+#############################################################################
+
+include ../make/defaults.mk
+
+all: install
+
+clean:
+ rm -f $(APP) $(DESTDIR)/$(APP)
+
+$(APP): $(APP).c Makefile
+ $(CC) -o $@ $< # add the lib search path and lib name
+
+install: $(APP)
+ cp $< $(DESTDIR)
+
diff --git a/lab07/solution/Makefile.libuser.solution b/lab07/solution/Makefile.libuser.solution
new file mode 100644
index 0000000..3e9e891
--- /dev/null
+++ b/lab07/solution/Makefile.libuser.solution
@@ -0,0 +1,17 @@
+APP = libuser
+
+#############################################################################
+
+include ../make/defaults.mk
+
+all: install
+
+clean:
+ rm -f $(APP) $(DESTDIR)/$(APP)
+
+$(APP): $(APP).c Makefile
+ $(CC) -o $@ $< -L. -lmy-utils # add the lib search path and lib name
+
+install: $(APP)
+ cp $< $(DESTDIR)
+
diff --git a/lab07/solution/Makefile.solution b/lab07/solution/Makefile.solution
new file mode 100644
index 0000000..63087a4
--- /dev/null
+++ b/lab07/solution/Makefile.solution
@@ -0,0 +1,24 @@
+CC=/home/student/crosstools/arm-2010.09/bin/arm-none-linux-gnueabi-gcc
+
+all: install
+
+# link .o's together with correct soname and real name
+libmy-utils.so.1.0 : test1.o test2.o test3.o
+ $(CC) -o libmy-utils.so.1.0 test1.o test2.o test3.o -shared -Wl,-soname=libmy-utils.so.1
+
+test1.o : test1.c # compile test1 w/ correct flags and output test1.o
+ $(CC) -o test1.o -fPIC -c test1.c
+
+test2.o : test2.c # compile test2 w/ correct flags and output test2.o
+ $(CC) -o test2.o -fPIC -c test2.c
+
+test3.o : test3.c # compile test3 w/ correct flags and output test3.o
+ $(CC) -o test3.o -fPIC -c test3.c
+
+clean:
+ rm -f *.o *.so.*
+
+install: libmy-utils.so.1.0
+ cp $< /home/student/targetfs/usr/local/lib
+
+
diff --git a/lab07/solution/libuser.c.solution b/lab07/solution/libuser.c.solution
new file mode 100644
index 0000000..2fecec3
--- /dev/null
+++ b/lab07/solution/libuser.c.solution
@@ -0,0 +1,18 @@
+#include "stdio.h"
+#include "stdlib.h"
+
+int main (int argc, char *argv[])
+{
+ int i = atoi(argv[1]);
+ int result = 0;
+
+ result = increment(i);
+ printf("%d\n", result);
+ result = decrement(i);
+ printf("%d\n", result);
+ result = mult2(i);
+ printf("%d\n", result);
+
+ return(0);
+}
+
diff --git a/lab07/test1.c b/lab07/test1.c
new file mode 100644
index 0000000..ca5de68
--- /dev/null
+++ b/lab07/test1.c
@@ -0,0 +1,4 @@
+int increment (int x)
+{
+ return(x+1);
+}
diff --git a/lab07/test2.c b/lab07/test2.c
new file mode 100644
index 0000000..48e542d
--- /dev/null
+++ b/lab07/test2.c
@@ -0,0 +1,4 @@
+int mult2 (int x)
+{
+ return(x*4);
+}
diff --git a/lab07/test3.c b/lab07/test3.c
new file mode 100644
index 0000000..bb4f10d
--- /dev/null
+++ b/lab07/test3.c
@@ -0,0 +1,4 @@
+int decrement (int x)
+{
+ return(x-1);
+}
diff --git a/lab08/Makefile.mutex b/lab08/Makefile.mutex
new file mode 100644
index 0000000..7632b5a
--- /dev/null
+++ b/lab08/Makefile.mutex
@@ -0,0 +1,11 @@
+
+APP = mutex
+
+#############################################################################
+
+include ../make/defaults.mk
+
+CC := $(CC) -lpthread
+
+include ../make/app-rules.mk
+
diff --git a/lab08/Makefile.rec b/lab08/Makefile.rec
new file mode 100644
index 0000000..4ff8f41
--- /dev/null
+++ b/lab08/Makefile.rec
@@ -0,0 +1,11 @@
+
+APP = rec
+
+#############################################################################
+
+include ../make/defaults.mk
+
+CC := $(CC) -lrt
+
+include ../make/app-rules.mk
+
diff --git a/lab08/Makefile.snd b/lab08/Makefile.snd
new file mode 100644
index 0000000..df37639
--- /dev/null
+++ b/lab08/Makefile.snd
@@ -0,0 +1,11 @@
+
+APP = snd
+
+#############################################################################
+
+include ../make/defaults.mk
+
+CC := $(CC) -lrt
+
+include ../make/app-rules.mk
+
diff --git a/lab08/mutex-solution.c b/lab08/mutex-solution.c
new file mode 100644
index 0000000..9a67a32
--- /dev/null
+++ b/lab08/mutex-solution.c
@@ -0,0 +1,212 @@
+/* Example code to demonstrate behavior of multi-core, threaded application
+ *
+ * Written by: Mike Anderson
+ * The PTR Group, Inc.
+ * mike@theptrgroup.com
+ *
+ * License: GPLv2
+ *
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <signal.h>
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+
+pthread_mutex_t mutex_fix; /* protect the critical region */
+
+pthread_t looperThId;
+pthread_t conflictThId;
+
+volatile int value1;
+volatile int value2;
+volatile int counter = 0;
+volatile int bTimeToExit = FALSE;
+
+int bUseMutex = FALSE; /* The "s" option */
+
+
+/* Conflict thread */
+void *conflictTh(void *arg)
+{
+ int same;
+ unsigned long loopCount = 0;
+ struct timespec sleep_time = {
+ .tv_sec = 0,
+ .tv_nsec = 7 * 1000 * 1000,
+ };
+
+ while (!bTimeToExit) {
+ if (bUseMutex) {
+ pthread_mutex_lock(&mutex_fix);
+ }
+
+ same = (value1 == value2);
+ if (!same)
+ printf("\nHey! value1 = %d, value2 = %d\n", value1,
+ value2);
+
+ loopCount++;
+ if ((loopCount % 1000) == 0) {
+ printf("\nConflict thread Counter = %lu \n", loopCount);
+ fflush(stdout);
+ counter = 0;
+ }
+
+ if (bUseMutex) {
+ pthread_mutex_unlock(&mutex_fix);
+ }
+
+ /* Sleep for 7ms */
+ nanosleep(&sleep_time, NULL);
+ }
+
+ return NULL;
+}
+
+/* Main loop thread */
+void *looperTh(void *arg)
+{
+ int counterTemp;
+ struct timespec sleep_time = {
+ .tv_sec = 0,
+ .tv_nsec = 13 * 1000 * 1000,
+ };
+
+
+ /* give the conflict thread a chance to start */
+ sleep(1);
+
+ while (!bTimeToExit) {
+ if (bUseMutex) {
+ pthread_mutex_lock(&mutex_fix);
+ }
+
+ value1 = counter;
+ value2 = counter;
+ counterTemp = counter++;
+
+ if (bUseMutex) {
+ pthread_mutex_unlock(&mutex_fix);
+ }
+
+ if ((counterTemp % 1000000) == 0) {
+ printf("Main loop counter = %d \r", counterTemp);
+ fflush(stdout);
+
+ /* Sleep for 13ms */
+ nanosleep(&sleep_time, NULL);
+ }
+ }
+
+ return NULL;
+}
+
+/* Ctrl-C Signal Handler */
+void gotCtrlC(int sig)
+{
+ printf("\nGot Ctrl-C! Shutting down...\n");
+
+ bTimeToExit = TRUE;
+}
+
+void print_usage(char *program)
+{
+ fprintf(stderr, "Usage: %s [options]\n%s", program,
+ "-h This help\n"
+ "-s (Use mutex to enforce synchronization)\n");
+}
+
+void parse_options(int argc, char *argv[])
+{
+ int c;
+
+ opterr = 0; /* get opt stuff */
+
+ while ((c = getopt(argc, argv, "hs")) != -1) {
+ switch (c) {
+ case 's':
+ bUseMutex = TRUE;
+ break;
+ case '?':
+ if (isprint(optopt))
+ fprintf(stderr, "Unknown option '-%c'.\n",
+ optopt);
+ else
+ fprintf(stderr,
+ "Unknown option character '\\x%x'.\n",
+ optopt);
+ /*FALLTHRU*/
+ case 'h':
+ default:
+ print_usage(argv[0]);
+ exit(EXIT_SUCCESS);
+ }
+ }
+
+ printf("Options in effect:\n");
+ if (bUseMutex)
+ printf(" Thread synchronization using mutexes is in effect \n");
+ else
+ printf(" Mutex-based thread synchronization is off \n");
+}
+
+int main(int argc, char *argv[])
+{
+ int res;
+
+ /* Parse the command line arguments */
+ parse_options(argc, argv);
+
+ printf("\nUse ^C to exit application...\n");
+
+ /* Set up the ^C signal handler so we can shut down cleanly */
+ (void)signal(SIGINT, gotCtrlC);
+
+ /* Go ahead and initialize the mutex in case we need it */
+ res = pthread_mutex_init(&mutex_fix, NULL);
+ if (res != 0) {
+ perror("Mutex initialization failed");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Create the main loop thread */
+ res = pthread_create(&looperThId, NULL, looperTh, NULL);
+ if (res != 0) {
+ perror("Main loop thread creation failed");
+ exit(EXIT_FAILURE);
+ }
+
+
+ /* Create the conflict thread */
+ res = pthread_create(&conflictThId, NULL, conflictTh, NULL);
+ if (res != 0) {
+ perror("Conflict thread creation failed");
+ exit(EXIT_FAILURE);
+ }
+
+ printf("\nMain is waiting for threads to finish...\n");
+ res = pthread_join(conflictThId, NULL);
+ if (res != 0) {
+ perror("Thread join with conflictTh() failed");
+ exit(EXIT_FAILURE);
+ }
+ res = pthread_join(looperThId, NULL);
+ if (res != 0) {
+ perror("Thread join with looperTh() failed");
+ exit(EXIT_FAILURE);
+ }
+
+ printf("Threads joined -- exiting main\n");
+ pthread_mutex_destroy(&mutex_fix);
+
+ return EXIT_SUCCESS;
+}
diff --git a/lab08/mutex.c b/lab08/mutex.c
new file mode 100644
index 0000000..7015569
--- /dev/null
+++ b/lab08/mutex.c
@@ -0,0 +1,212 @@
+/* Example code to demonstrate behavior of multi-core, threaded application
+ *
+ * Written by: Mike Anderson
+ * The PTR Group, Inc.
+ * mike@theptrgroup.com
+ *
+ * License: GPLv2
+ *
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <signal.h>
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+
+pthread_mutex_t mutex_fix; /* protect the critical region */
+
+pthread_t looperThId;
+pthread_t conflictThId;
+
+volatile int value1;
+volatile int value2;
+volatile int counter = 0;
+volatile int bTimeToExit = FALSE;
+
+int bUseMutex = FALSE; /* The "s" option */
+
+
+/* Conflict thread */
+void *conflictTh(void *arg)
+{
+ int same;
+ unsigned long loopCount = 0;
+ struct timespec sleep_time = {
+ .tv_sec = 0,
+ .tv_nsec = 7 * 1000 * 1000,
+ };
+
+ while (!bTimeToExit) {
+ if (bUseMutex) {
+ // Acquire mutex using pthread_mutex_lock(3p)
+ }
+
+ same = (value1 == value2);
+ if (!same)
+ printf("\nHey! value1 = %d, value2 = %d\n", value1,
+ value2);
+
+ loopCount++;
+ if ((loopCount % 1000) == 0) {
+ printf("\nConflict thread Counter = %lu \n", loopCount);
+ fflush(stdout);
+ counter = 0;
+ }
+
+ if (bUseMutex) {
+ // Release mutex using pthread_mutex_unlock(3p);
+ }
+
+ /* Sleep for 7ms */
+ nanosleep(&sleep_time, NULL);
+ }
+
+ return NULL;
+}
+
+/* Main loop thread */
+void *looperTh(void *arg)
+{
+ int counterTemp;
+ struct timespec sleep_time = {
+ .tv_sec = 0,
+ .tv_nsec = 13 * 1000 * 1000,
+ };
+
+
+ /* give the conflict thread a chance to start */
+ sleep(1);
+
+ while (!bTimeToExit) {
+ if (bUseMutex) {
+ // Acquire mutex using pthread_mutex_lock(3p)
+ }
+
+ value1 = counter;
+ value2 = counter;
+ counterTemp = counter++;
+
+ if (bUseMutex) {
+ // Release mutex using pthread_mutex_unlock(3p);
+ }
+
+ if ((counterTemp % 1000000) == 0) {
+ printf("Main loop counter = %d \r", counterTemp);
+ fflush(stdout);
+
+ /* Sleep for 13ms */
+ nanosleep(&sleep_time, NULL);
+ }
+ }
+
+ return NULL;
+}
+
+/* Ctrl-C Signal Handler */
+void gotCtrlC(int sig)
+{
+ printf("\nGot Ctrl-C! Shutting down...\n");
+
+ bTimeToExit = TRUE;
+}
+
+void print_usage(char *program)
+{
+ fprintf(stderr, "Usage: %s [options]\n%s", program,
+ "-h This help\n"
+ "-s (Use mutex to enforce synchronization)\n");
+}
+
+void parse_options(int argc, char *argv[])
+{
+ int c;
+
+ opterr = 0; /* get opt stuff */
+
+ while ((c = getopt(argc, argv, "hs")) != -1) {
+ switch (c) {
+ case 's':
+ bUseMutex = TRUE;
+ break;
+ case '?':
+ if (isprint(optopt))
+ fprintf(stderr, "Unknown option '-%c'.\n",
+ optopt);
+ else
+ fprintf(stderr,
+ "Unknown option character '\\x%x'.\n",
+ optopt);
+ /*FALLTHRU*/
+ case 'h':
+ default:
+ print_usage(argv[0]);
+ exit(EXIT_SUCCESS);
+ }
+ }
+
+ printf("Options in effect:\n");
+ if (bUseMutex)
+ printf(" Thread synchronization using mutexes is in effect \n");
+ else
+ printf(" Mutex-based thread synchronization is off \n");
+}
+
+int main(int argc, char *argv[])
+{
+ int res;
+
+ /* Parse the command line arguments */
+ parse_options(argc, argv);
+
+ printf("\nUse ^C to exit application...\n");
+
+ /* Set up the ^C signal handler so we can shut down cleanly */
+ (void)signal(SIGINT, gotCtrlC);
+
+ /* Go ahead and initialize the mutex in case we need it */
+ // Initialize the mutex using pthread_mutex_init(3p)
+ if (res != 0) {
+ perror("Mutex initialization failed");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Create the main loop thread */
+ res = pthread_create(&looperThId, NULL, looperTh, NULL);
+ if (res != 0) {
+ perror("Main loop thread creation failed");
+ exit(EXIT_FAILURE);
+ }
+
+
+ /* Create the conflict thread */
+ res = pthread_create(&conflictThId, NULL, conflictTh, NULL);
+ if (res != 0) {
+ perror("Conflict thread creation failed");
+ exit(EXIT_FAILURE);
+ }
+
+ printf("\nMain is waiting for threads to finish...\n");
+ res = pthread_join(conflictThId, NULL);
+ if (res != 0) {
+ perror("Thread join with conflictTh() failed");
+ exit(EXIT_FAILURE);
+ }
+ res = pthread_join(looperThId, NULL);
+ if (res != 0) {
+ perror("Thread join with looperTh() failed");
+ exit(EXIT_FAILURE);
+ }
+
+ printf("Threads joined -- exiting main\n");
+ // Destroy the mutex using pthread_mutex_destroy(3p);
+
+ return EXIT_SUCCESS;
+}
diff --git a/lab08/rec-solution.c b/lab08/rec-solution.c
new file mode 100644
index 0000000..b07beb2
--- /dev/null
+++ b/lab08/rec-solution.c
@@ -0,0 +1,83 @@
+#include "stdio.h"
+#include "stdlib.h"
+#include "mqueue.h"
+#include "sys/stat.h"
+#include "string.h"
+#include "signal.h"
+#include "setjmp.h"
+
+int msg_analyze (char *);
+
+int main (void)
+{
+ int status = 0;
+
+ mqd_t analyze_q;
+ struct mq_attr attr =
+ {
+ .mq_flags = 0,
+ .mq_maxmsg = 10,
+ .mq_msgsize = 100,
+ };
+
+ char recd_msg[100];
+
+ /* create message queue ptr_q */
+ analyze_q = mq_open("/analyze_q",O_RDONLY|O_CREAT,S_IWUSR|S_IRUSR, &attr);
+ if (0 > analyze_q)
+ {
+ perror("mq_open");
+ exit(1);
+ }
+
+ while (1)
+ {
+
+ status = mq_receive(analyze_q,(void *)&recd_msg[0],100,NULL);
+
+ status = msg_analyze(recd_msg);
+
+ }
+
+ status = mq_close(analyze_q);
+ status = mq_unlink("/analyze_q");
+
+ return(0);
+}
+
+int msg_analyze (char *msg)
+{
+ int status = 0;
+ int msg_len = 0;
+ int ndigit = 0;
+ int nlower = 0;
+ int nupper = 0;
+ int nother = 0;
+
+ int i;
+
+ status = msg_len = strlen(msg);
+
+ for (i=0;i<msg_len;i++)
+ {
+ if ('0' <= msg[i] && '9' >= msg[i])
+ ++ndigit;
+ else
+ if ('a' <= msg[i] && 'z' >= msg[i])
+ ++nlower;
+ else
+ if ('A' <= msg[i] && 'Z' >= msg[i])
+ ++nupper;
+ else
+ ++nother;
+ }
+
+ printf("\n\nThe message:\n\n\"%s\"\n\nhas %d characters,\n", msg, msg_len);
+ printf("of which %d are digits,\n", ndigit);
+ printf("%d are lowercase characters,\n", nlower);
+ printf("%d are uppercase characters,\n", nupper);
+ printf("and %d are white space or punctuation.\n", nother);
+
+ return(0);
+}
+
diff --git a/lab08/rec.c b/lab08/rec.c
new file mode 100644
index 0000000..11467a5
--- /dev/null
+++ b/lab08/rec.c
@@ -0,0 +1,72 @@
+#include "stdio.h"
+#include "stdlib.h"
+#include "mqueue.h" /* this header file is required */
+#include "sys/stat.h"
+#include "string.h"
+#include "signal.h"
+#include "setjmp.h"
+
+int msg_analyze (char *);
+
+int main (void)
+{
+ int status = 0;
+
+ /* create the message queue variable */
+
+ /* create and initialize the message queue attribute structure */
+ /* don't forget the type for the structure */
+ struct "type" attr =
+ {
+ };
+
+ char recd_msg[100];
+
+ /* create message queue analyze_q. check that the call succeeds */
+
+ /* make the message queue receive call here */
+
+ /* this call analyzes the string received from the queue */
+ status = msg_analyze(recd_msg);
+
+ /* use the close and unlink calls to make debugging easier */
+
+ return(0);
+}
+
+int msg_analyze (char *msg)
+{
+ int status = 0;
+ int msg_len = 0;
+ int ndigit = 0;
+ int nlower = 0;
+ int nupper = 0;
+ int nother = 0;
+
+ int i;
+
+ status = msg_len = strlen(msg);
+
+ for (i=0;i<msg_len;i++)
+ {
+ if ('0' <= msg[i] && '9' >= msg[i])
+ ++ndigit;
+ else
+ if ('a' <= msg[i] && 'z' >= msg[i])
+ ++nlower;
+ else
+ if ('A' <= msg[i] && 'Z' >= msg[i])
+ ++nupper;
+ else
+ ++nother;
+ }
+
+ printf("\n\nThe message:\n\n\"%s\"\n\nhas %d characters,\n", msg, msg_len);
+ printf("of which %d are digits,\n", ndigit);
+ printf("%d are lowercase characters,\n", nlower);
+ printf("%d are uppercase characters,\n", nupper);
+ printf("and %d are white space or punctuation.\n", nother);
+
+ return(0);
+}
+
diff --git a/lab08/snd-solution.c b/lab08/snd-solution.c
new file mode 100644
index 0000000..76e0a76
--- /dev/null
+++ b/lab08/snd-solution.c
@@ -0,0 +1,60 @@
+#include "stdio.h"
+#include "stdlib.h"
+#include "mqueue.h"
+#include "sys/stat.h"
+#include "string.h"
+#include "time.h"
+
+#define MAX_CHAR 127
+#define STR_SIZE 100
+
+void give_string(char *);
+
+int main (void)
+{
+ int status = 0;
+ mqd_t analyze_q;
+ char *sent_msg;
+ struct mq_attr attr;
+
+ analyze_q = mq_open("/analyze_q", O_WRONLY, S_IRUSR|S_IWUSR, NULL);
+ if (0 > analyze_q)
+ {
+ perror("mq_open");
+ exit(1);
+ }
+
+ sent_msg = (char *) malloc (100);
+ if (NULL == sent_msg)
+ {
+ perror("malloc");
+ exit(1);
+ }
+
+ give_string(sent_msg);
+
+ status = mq_getattr(analyze_q,&attr);
+ status = mq_send(analyze_q,(void *)&sent_msg[0],attr.mq_msgsize,(unsigned)NULL);
+
+ free(sent_msg);
+
+ status = mq_close(analyze_q);
+
+ return(0);
+}
+
+
+void give_string(char *result)
+{
+ int j = 0;
+ int i = 0;
+
+ srand((unsigned)time(NULL));
+
+ for (i=0;i<100;i++)
+ {
+ result[i] = (char) (1 + (int) (MAX_CHAR * (rand() / (RAND_MAX + 1.0))) );
+ }
+
+}
+
diff --git a/lab08/snd.c b/lab08/snd.c
new file mode 100644
index 0000000..0b8fbd6
--- /dev/null
+++ b/lab08/snd.c
@@ -0,0 +1,58 @@
+#include "stdio.h"
+#include "stdlib.h"
+#include "mqueue.h" /* this header file is required */
+#include "sys/stat.h"
+#include "string.h"
+#include "time.h"
+
+#define MAX_CHAR 127
+#define STR_SIZE 100
+
+void give_string(char *);
+
+int main (void)
+{
+ int status = 0;
+ /* declare a message queue variable */
+
+ char *sent_msg;
+ struct mq_attr attr;
+
+ /* open the message queue for writing. don't forget to check the return value */
+
+ sent_msg = (char *) malloc (100);
+ if (NULL == sent_msg)
+ {
+ perror("malloc");
+ exit(1);
+ }
+
+ /* give_string(sent_msg); this function generates a random string */
+ /* you can use this or just send your own string */
+
+ /* get the message queue attribute structure */
+
+ /* send a message */
+
+ free(sent_msg);
+
+ status = mq_close(analyze_q);
+
+ return(0);
+}
+
+
+void give_string(char *result)
+{
+ int j = 0;
+ int i = 0;
+
+ srand((unsigned)time(NULL));
+
+ for (i=0;i<100;i++)
+ {
+ result[i] = (char) (1 + (int) (MAX_CHAR * (rand() / (RAND_MAX + 1.0))) );
+ }
+
+}
+
diff --git a/lab09/Makefile b/lab09/Makefile
new file mode 100644
index 0000000..0875293
--- /dev/null
+++ b/lab09/Makefile
@@ -0,0 +1,8 @@
+
+APP = timer
+
+#############################################################################
+
+include ../make/defaults.mk
+include ../make/app-rules.mk
+
diff --git a/lab09/timer-solution.c b/lab09/timer-solution.c
new file mode 100644
index 0000000..467b3b4
--- /dev/null
+++ b/lab09/timer-solution.c
@@ -0,0 +1,35 @@
+#include <signal.h>
+#include <sys/time.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define RATE 5 /* 5 Hz */
+
+int count = 0;
+
+void alarm_handler(int x) {
+ count++;
+ if ((count > 0) && ((count % 10) == 0)) {
+ printf("Number of timer callbacks: %d\n", count);
+ }
+ signal(SIGALRM, alarm_handler);
+}
+
+int main()
+{
+ struct timeval initial = {0, 1000000/RATE};
+ struct timeval interval = {0, 1000000/RATE};
+ struct itimerval t;
+
+ t.it_value = initial;
+ t.it_interval = interval;
+ if (signal(SIGALRM, alarm_handler) != SIG_ERR) {
+ if (!setitimer(ITIMER_REAL, &t, 0)) {
+ /* Perform other tasks waiting for our SIGALRMs */
+ while(count <= 50) {
+ ;
+ }
+ }
+ }
+ exit(0);
+}
diff --git a/lab09/timer.c b/lab09/timer.c
new file mode 100644
index 0000000..6c609f5
--- /dev/null
+++ b/lab09/timer.c
@@ -0,0 +1,33 @@
+#include <signal.h>
+#include <sys/time.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define RATE 5 /* 5 Hz */
+
+int count = 0;
+
+void alarm_handler(int x) {
+ count++;
+ if ((count > 0) && ((count % 10) == 0)) {
+ printf("Number of timer callbacks: %d\n", count);
+ }
+ signal(SIGALRM, alarm_handler);
+}
+
+int main()
+{
+ /* define the initial and interval to run at 5 hz */
+ struct timeval initial = {0, ???/RATE};
+ struct timeval interval = {0, ???/RATE};
+ struct itimerval t;
+
+ t.it_value = initial;
+ t.it_interval = interval;
+
+ /* install a signal handler for SIGALRM and start timer ticking */
+
+ /* use the count variable to terminate after 10 seconds */
+
+ exit(0);
+}
diff --git a/lab10/Makefile b/lab10/Makefile
new file mode 100644
index 0000000..bfa648f
--- /dev/null
+++ b/lab10/Makefile
@@ -0,0 +1,8 @@
+
+APP = net
+
+#############################################################################
+
+include ../make/defaults.mk
+include ../make/app-rules.mk
+
diff --git a/lab10/net-solution.c b/lab10/net-solution.c
new file mode 100644
index 0000000..bc811a0
--- /dev/null
+++ b/lab10/net-solution.c
@@ -0,0 +1,103 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define SOCKET_PATHNAME "/root/unixsock"
+#define BUFSIZE 200
+
+void consumer()
+{
+ struct sockaddr_un peer_addr;
+ int len;
+ int size;
+ char buf[BUFSIZE];
+
+ /* Attach to server socket */
+ int sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (sock < 0) {
+ printf("consumer: error opening socket\n");
+ exit(1);
+ }
+
+ printf("consumer connecting to producer\n");
+
+ peer_addr.sun_family = AF_UNIX;
+ strcpy(peer_addr.sun_path, SOCKET_PATHNAME);
+ len = strlen(SOCKET_PATHNAME) + sizeof(peer_addr.sun_family);
+ if (connect(sock, (struct sockaddr*)&peer_addr, len) < 0) {
+ printf("consumer: error in connect\n");
+ exit(1);
+ }
+
+ printf("consumer connected to producer\n");
+
+ size = recv(sock, &buf[0], BUFSIZE, 0);
+ if (size < 0) {
+ printf("consumer: error in recv\n");
+ exit(1);
+ }
+
+ printf("consumer received message: %s\n", &buf[0]);
+}
+
+void producer()
+{
+ struct sockaddr_un my_addr;
+ struct sockaddr_un peer_addr;
+ int status;
+ int connsock;
+ int len;
+ socklen_t peeraddrlen;
+ char *msg = "this is a message from producer to consumer";
+
+ /* Create server socket, UNIX domain */
+ int sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (sock < 0) {
+ printf("producer: error opening socket\n");
+ exit(1);
+ }
+
+ /* Await connections */
+ my_addr.sun_family = AF_UNIX;
+ strcpy(my_addr.sun_path, SOCKET_PATHNAME);
+ len = strlen(SOCKET_PATHNAME) + sizeof(my_addr.sun_family);
+ unlink(SOCKET_PATHNAME);
+ status = bind(sock, (struct sockaddr*)&my_addr, len);
+ if (status < 0) {
+ printf("producer failed to bind\n");
+ exit(1);
+ }
+ if (listen(sock, 5) < 0) {
+ printf("producer failed to listen\n");
+ exit(1);
+ }
+ connsock = accept(sock, (struct sockaddr*)&peer_addr, &peeraddrlen);
+ if (connsock < 0) {
+ printf("producer failed to accept\n");
+ exit(1);
+ }
+
+ /* Send out message on socket */
+ status = send(connsock, &msg[0], strlen(msg)+1, 0);
+ if (status < 0) {
+ printf("producer failed to send\n");
+ exit(1);
+ }
+}
+
+int main()
+{
+ if (fork() == 0) {
+ /* start the producer/server first */
+ producer();
+ exit(0);
+ }
+ /* parent process proceeds here */
+ sleep(1);
+ consumer();
+ exit(0);
+}
diff --git a/lab10/net.c b/lab10/net.c
new file mode 100644
index 0000000..7f52e20
--- /dev/null
+++ b/lab10/net.c
@@ -0,0 +1,100 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define SOCKET_PATHNAME "/root/unixsock"
+#define BUFSIZE 200
+
+void consumer()
+{
+ struct sockaddr_un peer_addr;
+ int len;
+ int size;
+ char buf[BUFSIZE];
+
+ /* Attach to server socket */
+ int sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (sock < 0) {
+ printf("consumer: error opening socket\n");
+ exit(1);
+ }
+
+ printf("consumer connecting to producer\n");
+
+ peer_addr.sun_family = AF_UNIX;
+ strcpy(peer_addr.sun_path, SOCKET_PATHNAME);
+ len = strlen(SOCKET_PATHNAME) + sizeof(peer_addr.sun_family);
+ if (connect(sock, (struct sockaddr*)&peer_addr, len) < 0) {
+ printf("consumer: error in connect\n");
+ exit(1);
+ }
+
+ printf("consumer connected to producer\n");
+
+ size = recv(sock, &buf[0], BUFSIZE, 0);
+ if (size < 0) {
+ printf("consumer: error in recv\n");
+ exit(1);
+ }
+
+ printf("consumer received message: %s\n", &buf[0]);
+}
+
+void producer()
+{
+ struct sockaddr_un my_addr;
+ struct sockaddr_un peer_addr;
+ int status;
+ int connsock;
+ int len;
+ socklen_t peeraddrlen;
+ char *msg = "this is a message from producer to consumer";
+
+ /* Create server socket, UNIX domain */
+ int sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (sock < 0) {
+ printf("producer: error opening socket\n");
+ exit(1);
+ }
+
+ /* Await connections */
+ my_addr.sun_family = AF_UNIX;
+ strcpy(my_addr.sun_path, SOCKET_PATHNAME);
+ len = strlen(SOCKET_PATHNAME) + sizeof(my_addr.sun_family);
+ unlink(SOCKET_PATHNAME);
+ status = bind(sock, (struct sockaddr*)&my_addr, len);
+ if (status < 0) {
+ printf("producer failed to bind\n");
+ exit(1);
+ }
+ if (listen(sock, 5) < 0) {
+ printf("producer failed to listen\n");
+ exit(1);
+ }
+ connsock = accept(sock, (struct sockaddr*)&peer_addr, &peeraddrlen);
+ if (connsock < 0) {
+ printf("producer failed to accept\n");
+ exit(1);
+ }
+
+ /* Send out message on socket */
+ status = send(connsock, &msg[0], strlen(msg)+1, 0);
+ if (status < 0) {
+ printf("producer failed to send\n");
+ exit(1);
+ }
+}
+
+int main()
+{
+ /* fork a child, if I'm the child, call producer and exit */
+
+ /* if I'm the parent, sleep for 1 second and call the consumer */
+
+ /* parent process proceeds here */
+ exit(0);
+}
diff --git a/make/app-rules.mk b/make/app-rules.mk
new file mode 100644
index 0000000..c66eca4
--- /dev/null
+++ b/make/app-rules.mk
@@ -0,0 +1,12 @@
+
+all: install
+
+clean:
+ rm -f $(APP) $(DESTDIR)/$(APP)
+
+$(APP): $(APP).c
+ $(CC) -g3 -o $@ $<
+
+install: $(APP)
+ cp $< $(DESTDIR)
+
diff --git a/make/defaults.mk b/make/defaults.mk
new file mode 100644
index 0000000..bec7ca0
--- /dev/null
+++ b/make/defaults.mk
@@ -0,0 +1,3 @@
+DESTDIR = /home/student/targetfs/root
+CC = $(CROSS_COMPILE)gcc
+