├── .DS_Store ├── README.md ├── lec ├── .DS_Store ├── Week 1 - L00 - Introduction to the course.pdf ├── Week 1 - L01 - Memory and Introduction to C.pdf ├── Week 10 - L10 - Further Thread Synchronisation.pdf ├── Week 10 - L10 - Thread Synchronisation.pdf ├── Week 11 - L11 - Scalable algorithmic templates.pdf ├── Week 12 - L12 - Performance of parallel programs.pdf ├── Week 2 - L02 - Pointers.pdf ├── Week 3 - L03 - Aggregates and Files.pdf ├── Week 4 - L04 - Linked Lists.pdf ├── Week 4 - L04 - Memory Management.pdf ├── Week 5 - L05 - Function pointers, Signals and Low level file IO.pdf ├── Week 6 - L06 - Part 1 - Preprocessor and Linking.pdf ├── Week 6 - L06 - Part 2 - Make.pdf ├── Week 7 - L07 - Processes and Fork.pdf ├── Week 8 - L08 - InterProcess Communication [IPC].pdf ├── Week 9 - L09 - Parallelism .pdf ├── Week 9 - L09 - pthreads.pdf ├── lec10-code │ ├── .DS_Store │ ├── count.c │ ├── mutex_styles.c │ ├── mutex_styles_synchronised.c │ ├── pingpong.c │ └── semaphore.h ├── lec11-code │ └── merge-sort.c ├── lec3-code │ ├── .DS_Store │ ├── files │ │ ├── .DS_Store │ │ ├── feof1.c │ │ ├── feof2.c │ │ ├── feof3.c │ │ ├── fgets.c │ │ └── twonum.txt │ ├── sizeof_item.c │ ├── struct-stack-copy.c │ ├── struct1-initialise.c │ ├── struct1-simple.c │ └── struct1-variations.c ├── lec4-code │ ├── .DS_Store │ ├── linked_list │ │ ├── .DS_Store │ │ ├── list.c │ │ ├── list1.c │ │ ├── list2.c │ │ └── list3.c │ └── memory_management │ │ ├── .DS_Store │ │ ├── array.c │ │ ├── array2.c │ │ ├── mem1.c │ │ ├── mem2.c │ │ ├── mem3.c │ │ ├── mem4.c │ │ ├── mem5.c │ │ ├── stack.c │ │ └── static.c ├── lec5-code │ ├── .DS_Store │ ├── branch.c │ ├── branch.s │ ├── branch2.c │ ├── branch2.s │ ├── branch3.c │ ├── branch3.s │ ├── errno-ex.c │ ├── errno-ex2.c │ ├── list4.c │ ├── list5_add_rand.c │ ├── read-sig.c │ ├── read-sig2.c │ ├── sig-alarm.c │ ├── sig-int.c │ ├── simple_function_pointer.c │ └── skinner.txt ├── lec6-code │ ├── .DS_Store │ ├── dlist.c │ ├── dlist.h │ ├── foo.c │ ├── foo_preprocessor.txt │ ├── hello.c │ ├── hello_gcc_verbose.txt │ ├── hello_preprocessor.txt │ ├── strace_hello.txt │ └── vprintf.c ├── lec7-code │ ├── .DS_Store │ ├── env_check.c │ ├── exec_prog1.c │ ├── exec_prog2.c │ ├── exec_prog3.c │ ├── exec_prog_example.sh │ ├── exec_test.c │ ├── exec_test1.c │ ├── fork_ex.c │ ├── fork_ex1.c │ ├── fork_ex2.c │ ├── fork_ex3.c │ ├── fork_ex4.c │ ├── fork_exec_wait.c │ ├── fork_wait0.c │ ├── fork_wait1.c │ ├── mini-shell1.c │ └── simple.c ├── lec8-code │ ├── .DS_Store │ ├── nb.c │ ├── nb_select.c │ ├── nb_select_pipe.c │ ├── nb_stdin.c │ ├── pipe.c │ ├── process_pipe.c │ ├── process_pipe_single.c │ └── select.c └── lec9-code │ ├── .DS_Store │ ├── a.out │ ├── mutex_simple.c │ └── mutex_simple_no_lock.c ├── sem ├── .DS_Store ├── sem10 │ ├── datarace.c │ ├── linkedlist.c │ └── pattern.c ├── sem11 │ ├── .DS_Store │ ├── fork_server.c │ └── thread_server.c ├── sem12 │ ├── iterator.c │ ├── iterator.h │ ├── linkedlist.c │ └── linkedlist.h ├── sem2 │ ├── appendStack.c │ ├── appendString.c │ ├── average.c │ └── compare.c ├── sem3 │ ├── .DS_Store │ ├── flip.c │ └── tictactoe.c ├── sem4 │ ├── crc32.c │ ├── ex │ ├── example1.c │ ├── firmware.c │ ├── firmware_maker │ ├── firmware_reader │ ├── firmware_reader.c │ ├── greader │ ├── greader.c │ ├── test1.bin │ ├── test2.bin │ ├── test3.bin │ ├── test4.bin │ ├── test5.bin │ └── test6.bin ├── sem5 │ ├── jaggy.c │ └── stack.c ├── sem6 │ ├── .DS_Store │ ├── MYSTDERR │ ├── my_text.txt │ ├── q1.c │ ├── q2.c │ ├── q3.c │ ├── q4.c │ ├── q5.c │ ├── q6.c │ └── script.sh ├── sem7 │ ├── tree.c │ ├── tree.h │ └── tree_program.c ├── sem8 │ ├── myprocess.c │ ├── mystdout.txt │ ├── redirect.c │ └── stdout.txt └── sem9 │ ├── mypipe.c │ └── shared.c └── tut ├── .DS_Store ├── Week 10 - Parallelism with POSIX threads and Optimisations.pdf ├── Week 11 - Synchronisation and Atomics.pdf ├── Week 12 - Recursion and Aliasing.pdf ├── Week 13 - Revision.pdf ├── Week 2 - Introduction To C.pdf ├── Week 3 - Addressable Memory and Standard Library Functions.pdf ├── Week 4 - Structs, Unions, Bitfields and Files.pdf ├── Week 5 - Dynamic Memory.pdf ├── Week 6 - File IO, Function Pointers and Signals.pdf ├── Week 7 - Compiler pipeline, Signals, Makefile and Shared library.pdf ├── Week 8 - Introduction To Processes.pdf ├── Week 9 - IPC, Shared Memory and Pipes.pdf ├── tut10 ├── .DS_Store ├── false-sharing-correct.c ├── false-sharing-false.c ├── q1.c ├── q2.c ├── q3.c ├── q4.c └── q5.c ├── tut11 ├── .DS_Store ├── dining_philosophers.c ├── q3.c ├── q4.c ├── q5_sem.c ├── q5_unsolved.c ├── q6.c └── semaphore.h ├── tut12 ├── .DS_Store ├── a.out ├── q1.c ├── q3.c └── q4.c ├── tut2 ├── .DS_Store ├── q1.c ├── q10.c ├── q11.c ├── q2.c ├── q3.c ├── q4.c ├── q5a.c ├── q5b.c ├── q7.c ├── q8.c └── q9.c ├── tut3 ├── .DS_Store ├── myfile.txt ├── printf.c ├── q1.c ├── q10.c ├── q11.c ├── q12.c ├── q2.c ├── q4.c ├── q6.c ├── q7.c ├── q8.c ├── q9.c └── scanf.c ├── tut4 ├── .DS_Store ├── astley.tct ├── astley.txt ├── batters.csv ├── gamepad.sh ├── myfile.txt ├── pokemon.dex ├── q1.c ├── q10.c ├── q2.c ├── q3.c ├── q4.c ├── q6.c ├── q7.c ├── q8.c ├── q9.c └── rick.txt ├── tut5 ├── .DS_Store ├── circular-linked-list.c ├── q1.c ├── q2.c ├── q3.c ├── q4.c ├── q5.c ├── q6 └── q6.c ├── tut6 ├── .DS_Store ├── a.out ├── q1.c ├── q4.c ├── q5.c ├── q6.c ├── q7.c ├── q8.c ├── q9.c └── time ├── tut7 ├── .DS_Store ├── list-example │ ├── .DS_Store │ ├── Makefile │ ├── list.c │ ├── list.h │ ├── list.o │ ├── tasks.c │ └── tasks.o ├── q2.c ├── q3 │ ├── .DS_Store │ ├── Makefile │ ├── main.c │ ├── stack.c │ ├── stack.h │ └── test.c ├── q5 │ ├── .DS_Store │ ├── rbuf.c │ └── rbuf.h ├── q6 │ ├── .DS_Store │ ├── cmocka.h │ ├── key_value.c │ ├── key_value.h │ ├── key_value_test.c │ └── libcmocka-static.a └── q7 │ ├── .DS_Store │ ├── librbuf.a │ ├── rbuf.c │ ├── rbuf.h │ ├── rbuf.o │ ├── shared_library.sh │ └── test.c ├── tut8 ├── .DS_Store ├── q1.c ├── q2.c ├── q3.c ├── q4.c ├── q5.c ├── say_hello_100.py └── test.out └── tut9 ├── fseek-with-files.c ├── mkfifo.c ├── mmap-with-files.c ├── q1.c ├── q2.c ├── q2_time.c ├── q3.c ├── q4.c └── share-between.c /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # COMP2017-Study-Notes 2 | Study Notes for COMP2017 at USYD 3 | 4 | ## COMP2017: Systems Programming 5 | 6 | In this unit of study, elementary methods for developing robust, efficient, and re-usable software will be covered. The unit is taught in C, in a Unix environment. Specific coding topics include memory management, the pragmatic aspects of implementing data structures such as lists and hash tables and managing concurrent threads. Debugging tools and techniques are discussed and common programming errors are considered along with defensive programming techniques to avoid such errors. Emphasis is placed on using common Unix tools to manage aspects of the software construction process, such as version control and regression testing. The subject is taught from a practical viewpoint and it includes a considerable amount of programming practice. 7 | -------------------------------------------------------------------------------- /lec/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/.DS_Store -------------------------------------------------------------------------------- /lec/Week 1 - L00 - Introduction to the course.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/Week 1 - L00 - Introduction to the course.pdf -------------------------------------------------------------------------------- /lec/Week 1 - L01 - Memory and Introduction to C.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/Week 1 - L01 - Memory and Introduction to C.pdf -------------------------------------------------------------------------------- /lec/Week 10 - L10 - Further Thread Synchronisation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/Week 10 - L10 - Further Thread Synchronisation.pdf -------------------------------------------------------------------------------- /lec/Week 10 - L10 - Thread Synchronisation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/Week 10 - L10 - Thread Synchronisation.pdf -------------------------------------------------------------------------------- /lec/Week 11 - L11 - Scalable algorithmic templates.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/Week 11 - L11 - Scalable algorithmic templates.pdf -------------------------------------------------------------------------------- /lec/Week 12 - L12 - Performance of parallel programs.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/Week 12 - L12 - Performance of parallel programs.pdf -------------------------------------------------------------------------------- /lec/Week 2 - L02 - Pointers.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/Week 2 - L02 - Pointers.pdf -------------------------------------------------------------------------------- /lec/Week 3 - L03 - Aggregates and Files.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/Week 3 - L03 - Aggregates and Files.pdf -------------------------------------------------------------------------------- /lec/Week 4 - L04 - Linked Lists.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/Week 4 - L04 - Linked Lists.pdf -------------------------------------------------------------------------------- /lec/Week 4 - L04 - Memory Management.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/Week 4 - L04 - Memory Management.pdf -------------------------------------------------------------------------------- /lec/Week 5 - L05 - Function pointers, Signals and Low level file IO.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/Week 5 - L05 - Function pointers, Signals and Low level file IO.pdf -------------------------------------------------------------------------------- /lec/Week 6 - L06 - Part 1 - Preprocessor and Linking.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/Week 6 - L06 - Part 1 - Preprocessor and Linking.pdf -------------------------------------------------------------------------------- /lec/Week 6 - L06 - Part 2 - Make.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/Week 6 - L06 - Part 2 - Make.pdf -------------------------------------------------------------------------------- /lec/Week 7 - L07 - Processes and Fork.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/Week 7 - L07 - Processes and Fork.pdf -------------------------------------------------------------------------------- /lec/Week 8 - L08 - InterProcess Communication [IPC].pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/Week 8 - L08 - InterProcess Communication [IPC].pdf -------------------------------------------------------------------------------- /lec/Week 9 - L09 - Parallelism .pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/Week 9 - L09 - Parallelism .pdf -------------------------------------------------------------------------------- /lec/Week 9 - L09 - pthreads.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/Week 9 - L09 - pthreads.pdf -------------------------------------------------------------------------------- /lec/lec10-code/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/lec10-code/.DS_Store -------------------------------------------------------------------------------- /lec/lec10-code/count.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define MAX 2 5 | #define MAX_ITER 100000000 6 | 7 | long counter = 0; 8 | 9 | void * thread_function(void * arg) { 10 | long l; 11 | for (l = 0; l < MAX_ITER; l++) 12 | counter++; //critical section 13 | return NULL; 14 | } 15 | 16 | int main(void) { 17 | pthread_t mythread[MAX]; int t = 0; 18 | 19 | for (t = 0; t < MAX; t++) 20 | pthread_create( &mythread[t], NULL, thread_function, NULL); 21 | 22 | for (t = 0; t < MAX; t++) 23 | pthread_join ( mythread[t], NULL); 24 | 25 | printf("Expected counter value: %d, observed counter value: %ld\n", MAX_ITER * MAX, counter); 26 | printf("You experienced %ld race conditions, or %ld%% of all accesses to the shared variable.\n", MAX_ITER * MAX - counter, 100 - 100 * counter / (MAX_ITER * MAX)); 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /lec/lec10-code/pingpong.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "semaphore.h" 7 | 8 | sem_t ping_lock; 9 | sem_t pong_lock; 10 | 11 | void * T1(void * arg) { 12 | for (;;) { 13 | printf("%d\n", sem_wait(&ping_lock)); 14 | printf("ping\n"); 15 | // sleep half a second 16 | usleep(500000); 17 | printf("%d\n", sem_post(&pong_lock)); 18 | // sem_post(&pong_lock); 19 | } 20 | } 21 | 22 | void * T2(void * arg) { 23 | for (;;) { 24 | sem_wait(&pong_lock); 25 | printf ("pong\n"); 26 | // sleep one second 27 | usleep(1000000); 28 | sem_post(&ping_lock); 29 | } 30 | } 31 | 32 | int main() { 33 | 34 | // ping to go first 35 | sem_init(&ping_lock, 0, 1); 36 | sem_init(&pong_lock, 0, 0); 37 | 38 | pthread_t th[2]; 39 | pthread_create(th+0, NULL, T1, NULL); 40 | pthread_create(th+1, NULL, T2, NULL); 41 | 42 | // wait for threads to finish 43 | pthread_join(th[0], NULL); 44 | pthread_join(th[1], NULL); 45 | 46 | return 0; 47 | } -------------------------------------------------------------------------------- /lec/lec10-code/semaphore.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. The rights granted to you under the License 10 | * may not be used to create, or enable the creation or redistribution of, 11 | * unlawful or unlicensed copies of an Apple operating system, or to 12 | * circumvent, violate, or enable the circumvention or violation of, any 13 | * terms of an Apple operating system software license agreement. 14 | * 15 | * Please obtain a copy of the License at 16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 | * 18 | * The Original Code and all software distributed under the License are 19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 | * Please see the License for the specific language governing rights and 24 | * limitations under the License. 25 | * 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 | */ 28 | /* @(#)semaphore.h 1.0 2/29/00 */ 29 | 30 | 31 | 32 | /* 33 | * semaphore.h - POSIX semaphores 34 | * 35 | * HISTORY 36 | * 29-Feb-00 A.Ramesh at Apple 37 | * Created for Mac OS X 38 | */ 39 | 40 | #ifndef _SYS_SEMAPHORE_H_ 41 | #define _SYS_SEMAPHORE_H_ 42 | 43 | typedef int sem_t; 44 | 45 | /* this should go in limits.h> */ 46 | #define SEM_VALUE_MAX 32767 47 | #define SEM_FAILED ((sem_t *)-1) 48 | 49 | #include 50 | 51 | __BEGIN_DECLS 52 | int sem_close(sem_t *); 53 | int sem_destroy(sem_t *); 54 | int sem_getvalue(sem_t * __restrict, int * __restrict); 55 | int sem_init(sem_t *, int, unsigned int); 56 | sem_t * sem_open(const char *, int, ...); 57 | int sem_post(sem_t *); 58 | int sem_trywait(sem_t *); 59 | int sem_unlink(const char *); 60 | int sem_wait(sem_t *) __DARWIN_ALIAS_C(sem_wait); 61 | __END_DECLS 62 | 63 | 64 | #endif /* _SYS_SEMAPHORE_H_ */ 65 | 66 | -------------------------------------------------------------------------------- /lec/lec3-code/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/lec3-code/.DS_Store -------------------------------------------------------------------------------- /lec/lec3-code/files/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/lec3-code/files/.DS_Store -------------------------------------------------------------------------------- /lec/lec3-code/files/feof1.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | while ( ! feof(stdin) ) { 6 | int num; 7 | fscanf(stdin, "%d", &num); 8 | fprintf(stdout, "num: %d\n", num); 9 | } 10 | 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /lec/lec3-code/files/feof2.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | while ( ! feof(stdin) ) { 6 | int num; 7 | int nread = fscanf(stdin, "%d", &num); 8 | if (nread <= 0) 9 | break; 10 | fprintf(stdout, "num: %d\n", num); 11 | } 12 | 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /lec/lec3-code/files/feof3.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | FILE *fp = fopen("twonum.txt", "r"); 6 | if (fp == NULL) { 7 | fprintf(stderr, "could not open file for reading\n"); 8 | return 1; 9 | } 10 | while ( ! feof(fp) ) { 11 | int num; 12 | int nread = fscanf(fp, "%d", &num); 13 | if (nread <= 0) 14 | break; 15 | fprintf(stdout, "num: %d\n", num); 16 | } 17 | fclose(fp); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /lec/lec3-code/files/fgets.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define BUFLEN (12) 5 | 6 | int main(int argc, char **argv) 7 | { 8 | FILE* fp; 9 | const char *fname = "sample.txt"; 10 | 11 | fp = fopen(fname, "r"); 12 | if (fp == NULL) { 13 | fprintf(stderr, "could not open file %s\n", fname); 14 | return 1; 15 | } 16 | 17 | int len; 18 | char buf[BUFLEN]; 19 | while (fgets(buf, BUFLEN, fp) != NULL) { 20 | len = strlen(buf); 21 | printf("line is :%s and length is: %d\n", buf, len); 22 | } 23 | 24 | fclose(fp); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /lec/lec3-code/files/twonum.txt: -------------------------------------------------------------------------------- 1 | 78 2 | 104 3 | -------------------------------------------------------------------------------- /lec/lec3-code/sizeof_item.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | struct item { 7 | char barcode[6]; 8 | const char *name; 9 | float price; 10 | }; 11 | 12 | struct item tomatoes; 13 | printf("sizeof(struct item): %zu\n", sizeof(struct item)); 14 | printf("sizeof(tomatoes): %zu\n", sizeof(tomatoes)); 15 | 16 | struct item *tincan; 17 | printf("sizeof(struct item *): %zu\n", sizeof(struct item*)); 18 | printf("sizeof(tincan): %zu\n", sizeof(tincan)); 19 | 20 | tincan = NULL; 21 | printf("sizeof(peaches): %zu\n", sizeof(tincan)); 22 | 23 | tincan = &tomatoes; 24 | printf("sizeof(peaches): %zu\n", sizeof(tincan)); 25 | 26 | printf("sizeof(tomatoes.barcode): %zu\n", sizeof(tomatoes.barcode)); 27 | printf("sizeof(tincan->barcode): %zu\n", sizeof(tincan->barcode)); 28 | 29 | printf("sizeof(tomatoes.name): %zu\n", sizeof(tomatoes.name)); 30 | printf("sizeof(tincan->name): %zu\n", sizeof(tincan->name)); 31 | 32 | tomatoes.name = "The Greatest Tomatoes in a can"; 33 | printf("sizeof(tomatoes.name): %zu\n", sizeof(tomatoes.name)); 34 | printf("strlen(tomatoes.name): %zu\n", strlen(tomatoes.name)); 35 | 36 | tomatoes.name = "TGT"; 37 | printf("sizeof(tomatoes.name): %zu\n", sizeof(tomatoes.name)); 38 | printf("strlen(tomatoes.name): %zu\n", strlen(tomatoes.name)); 39 | 40 | printf("sizeof(tomatoes.price): %zu\n", sizeof(tomatoes.price)); 41 | printf("sizeof(tincan->price): %zu\n", sizeof(tincan->price)); 42 | 43 | // pointer arithmetic 44 | printf("tomatoes: %p\n", &tomatoes); 45 | printf("tomatoes barcode: %zu\n", (void*)&(tomatoes.barcode) - (void*)&tomatoes); 46 | printf("tomatoes name: %zu\n", (void*)&(tomatoes.name) - (void*)&tomatoes); 47 | printf("tomatoes price: %zu\n", (void*)&(tomatoes.price) - (void*)&tomatoes); 48 | 49 | return 0; 50 | } -------------------------------------------------------------------------------- /lec/lec3-code/struct-stack-copy.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // idiom 4 | // find the first occurrence of f(x) == TRUE 5 | // where f(x) = (x % 2 == 0) 6 | // return the *both* the value and the index 7 | 8 | struct pair { 9 | int value; 10 | int index; 11 | }; 12 | 13 | // if no data then return -1 index; 14 | struct pair get_best_index(int *data, size_t n) { 15 | 16 | struct pair pair; 17 | 18 | pair.index = -1; 19 | pair.value = -1; 20 | 21 | if (data == NULL || n <= 0) { 22 | return pair; 23 | } 24 | 25 | pair.index = 0; 26 | pair.value = data[0]; 27 | 28 | int i; 29 | for (i = 0; i < n; i++) { 30 | v = data[i]; 31 | if ( v % 2 == 0 ) { 32 | pair.value = v; 33 | pair.index = i; 34 | break; 35 | } 36 | } 37 | 38 | return pair; // copy operation 39 | } 40 | 41 | int main() 42 | { 43 | 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /lec/lec3-code/struct1-initialise.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct item { 5 | char barcode[6]; 6 | const char *name; 7 | float price; 8 | }; 9 | 10 | // function prototype 11 | float items_sum( struct item *items, size_t n ); 12 | 13 | // initialise a structure with values 14 | // pass in the memory address of structure 15 | // Warning: assume name has preallocated memory 16 | void item_init( struct item *item, 17 | const char *barcode, const char *name, float price) { 18 | 19 | if (item == NULL || 20 | barcode == NULL || 21 | name == NULL) 22 | return; // raise an error? 23 | 24 | strncpy(item->barcode, barcode, 6); 25 | item->name = name; // warning 26 | item->price = price; 27 | } 28 | 29 | int main() { 30 | // create array 31 | struct item items[2]; 32 | 33 | // initialise elements 34 | item_init( &(items[0]), "DFH291", "Big tuna", 1.25); 35 | item_init( &(items[1]), "FGD135", "Tin can", 3.50); 36 | 37 | float sum = items_sum(items, 2); 38 | printf("sum: %.2f\n", sum); 39 | 40 | return 0; 41 | } 42 | 43 | 44 | 45 | 46 | // sum all prices 47 | float items_sum( struct item *items, size_t n ) { 48 | float sum = 0; 49 | 50 | int i = 0; 51 | for ( ; i < n; ++i) { 52 | sum += items[i].price; 53 | } 54 | return sum; 55 | } 56 | -------------------------------------------------------------------------------- /lec/lec3-code/struct1-simple.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct item { 5 | char barcode[6]; 6 | const char *name; 7 | float price; 8 | }; 9 | 10 | // memory input 11 | // given an array of structs 12 | 13 | // idiom 14 | // sum all prices 15 | float items_sum( struct item *items, int n ) 16 | { 17 | float sum = 0; 18 | 19 | int i = 0; 20 | for ( ; i < n; ++i) { 21 | sum += items[i].price; 22 | } 23 | return sum; 24 | } 25 | 26 | int main() 27 | { 28 | // create array 29 | struct item items[2]; 30 | 31 | // initialise elements 32 | // man strncpy - see warning 33 | strncpy(items[0].barcode, "DFH291", 6); 34 | items[0].name = "Big tuna"; 35 | items[0].price = 1.25; 36 | 37 | // init each field (man strncpy) 38 | strncpy(items[1].barcode, "FGD135", 6); 39 | items[1].name = "Tin can"; 40 | items[1].price = 3.50; 41 | 42 | float sum = items_sum(items, 2); 43 | printf("sum: %.2f\n", sum); 44 | 45 | return 0; 46 | } -------------------------------------------------------------------------------- /lec/lec3-code/struct1-variations.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct item { 4 | char barcode[6]; 5 | char *name; 6 | float price; 7 | }; 8 | 9 | // memory input 10 | // 1. given an array of structs 11 | // 2. given an array of pointers to structs 12 | // 3. given a pointer to an array of structs 13 | 14 | // idioms 15 | // A. sum all prices 16 | // B. find all items >= price 17 | // C. does barcode FGD135 exist? 18 | // D. find all items with barcode prefix "OPE" 19 | // E. find items containing the word "can" 20 | 21 | int main() 22 | { 23 | return 0; 24 | } -------------------------------------------------------------------------------- /lec/lec4-code/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/lec4-code/.DS_Store -------------------------------------------------------------------------------- /lec/lec4-code/linked_list/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/lec4-code/linked_list/.DS_Store -------------------------------------------------------------------------------- /lec/lec4-code/linked_list/list.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct list { 4 | int data; 5 | struct list *next; 6 | }; 7 | 8 | int main() { 9 | 10 | struct list *cursor; 11 | 12 | struct list a, b, c; 13 | 14 | printf("addr of a is: %p\n", &a); 15 | printf("addr of b is: %p\n", &b); 16 | printf("addr of c is: %p\n", &c); 17 | 18 | a.data = 'a'; 19 | a.next = NULL; 20 | 21 | b.data = 'b'; 22 | b.next = &c; 23 | 24 | c.data = 'c'; 25 | c.next = NULL; 26 | 27 | cursor = &b; 28 | 29 | printf("cursor is at : %c\n", cursor->data); 30 | printf("cursor addr is : %p\n", cursor); 31 | printf("cursor->next addr is : %p\n", cursor->next); 32 | 33 | cursor = &a; 34 | 35 | printf("cursor is at : %c\n", cursor->data); 36 | printf("cursor addr is : %p\n", cursor); 37 | printf("cursor->next addr is : %p\n", cursor->next); 38 | 39 | a.next = &b; 40 | 41 | printf("cursor is at : %c\n", cursor->data); 42 | printf("cursor addr is : %p\n", cursor); 43 | printf("cursor->next addr is : %p\n", cursor->next); 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /lec/lec4-code/linked_list/list1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct list { 5 | int data; 6 | struct list *next; 7 | }; 8 | 9 | int main() { 10 | struct list *cursor; 11 | struct list *a; 12 | struct list *b; 13 | struct list *c; 14 | 15 | a = (struct list*)malloc(sizeof(struct list)); 16 | b = (struct list*)malloc(sizeof(struct list)); 17 | c = (struct list*)malloc(sizeof(struct list)); 18 | 19 | a->data = 'a'; 20 | a->next = NULL; 21 | 22 | b->data = 'b'; 23 | b->next = c; 24 | 25 | c->data = 'c'; 26 | c->next = NULL; 27 | 28 | cursor = b; 29 | 30 | printf("cursor is at : %c\n", cursor->data); 31 | printf("cursor addr is : %p\n", cursor); 32 | printf("cursor->next addr is : %p\n", cursor->next); 33 | 34 | cursor = a; 35 | 36 | printf("cursor is at : %c\n", cursor->data); 37 | printf("cursor addr is : %p\n", cursor); 38 | printf("cursor->next addr is : %p\n", cursor->next); 39 | 40 | a->next = b; 41 | 42 | printf("cursor is at : %c\n", cursor->data); 43 | printf("cursor addr is : %p\n", cursor); 44 | printf("cursor->next addr is : %p\n", cursor->next); 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /lec/lec4-code/linked_list/list2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct list { 5 | int data; 6 | struct list *next; 7 | }; 8 | 9 | int main() { 10 | 11 | struct list *cursor; 12 | 13 | cursor = (struct list*)malloc(sizeof(struct list)); 14 | 15 | cursor->data = 'b'; 16 | cursor->next = (struct list*)malloc(sizeof(struct list)); 17 | 18 | struct list *tmp = cusor->next; 19 | tmp->data = 'c'; 20 | tmp->next = NULL; 21 | 22 | struct list *a = (struct list*)malloc(sizeof(struct list)); 23 | a.data = 'a'; 24 | 25 | // correct 26 | a->next = cursor; 27 | cursor = a; 28 | 29 | // incorrect 30 | cursor = a; 31 | a->next = cursor; 32 | 33 | return 0; 34 | } 35 | 36 | 37 | -------------------------------------------------------------------------------- /lec/lec4-code/linked_list/list3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct list { 5 | int data; 6 | struct list *next; 7 | }; 8 | 9 | void print_list(struct list *head) { 10 | 11 | // empty list check 12 | if (head == NULL) { 13 | printf("empty list!\n"); 14 | return; 15 | } 16 | 17 | // guaranteed non-empty list 18 | struct list *cursor = head; 19 | 20 | while (cursor != NULL) 21 | { 22 | printf("cursor element is : %c\n", cursor->data); 23 | cursor = cursor->next; 24 | } 25 | /* 26 | if (cursor == NULL) 27 | return; 28 | 29 | printf("cursor element is : %c\n", cursor->data); 30 | cursor = cursor->next; 31 | if (cursor == NULL) 32 | return; 33 | 34 | printf("cursor element is : %c\n", cursor->data); 35 | cursor = cursor->next; 36 | */ 37 | } 38 | 39 | void pfree(void *address) { 40 | 41 | struct list *tmp = (struct list*)address; 42 | printf("freeing %p %c\n", address, tmp->data); 43 | free(address); 44 | } 45 | 46 | void list_free(struct list *head) 47 | { 48 | if (head == NULL) 49 | return; 50 | 51 | // at this point 1+ elements 52 | struct list *cursor = head; 53 | 54 | if (cursor->next == NULL) { 55 | // element 1 only case 56 | pfree(head); 57 | return; 58 | } 59 | 60 | // at this point 2+ cases 61 | struct list *tmp; 62 | while (cursor != NULL) 63 | { 64 | tmp = cursor->next; 65 | pfree(cursor); 66 | cursor = tmp; 67 | } 68 | } 69 | 70 | int main() { 71 | struct list *cursor; 72 | 73 | cursor = (struct list*)malloc(sizeof(struct list)); 74 | 75 | cursor->data = 'b'; 76 | cursor->next = (struct list*)malloc(sizeof(struct list)); 77 | 78 | struct list *tmp = cursor->next; 79 | tmp->data = 'c'; 80 | tmp->next = (struct list *)malloc(sizeof(struct list)); 81 | 82 | tmp->next->data = 'd'; 83 | tmp->next->next = NULL; 84 | 85 | print_list(cursor); 86 | 87 | list_free(cursor->next); 88 | 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /lec/lec4-code/memory_management/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/lec4-code/memory_management/.DS_Store -------------------------------------------------------------------------------- /lec/lec4-code/memory_management/array.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // lifetime of memory and where does it exist? 4 | 5 | int nums_global[10]; 6 | 7 | void foo() { 8 | int nums_local[10]; 9 | 10 | return ; 11 | } 12 | 13 | int main() 14 | { 15 | foo(); 16 | 17 | int *other_nums = (int*)malloc(sizeof(int) * 10); 18 | 19 | free(other_nums); 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /lec/lec4-code/memory_management/array2.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // initialise an n sized array of ints 4 | void array_init_1(int n, int *nums) { 5 | if (n <= 0) 6 | return; 7 | int i = 0; 8 | for (i = 0; i < n; ++i) 9 | nums[i] = 1; 10 | } 11 | 12 | // initialise an n sized array of ints 13 | void array_print(int n, int *nums) { 14 | if (n <= 0) 15 | return; 16 | int i = 0; 17 | for (i = 0; i < n; ++i) 18 | printf("%d ", nums[i]); 19 | printf("\n"); 20 | } 21 | 22 | // create an return a n sized array of ints 23 | int * array_new(int n) { 24 | int *tmp = (int*)malloc(sizeof(int) * n); 25 | if (tmp == NULL) 26 | ; // something terribly wrong 27 | 28 | return tmp; 29 | } 30 | 31 | int main() 32 | { 33 | int *nums = array_new(10); 34 | 35 | array_print(nums); 36 | array_init_1(nums); 37 | array_print(nums); 38 | 39 | // never forget! 40 | free(nums); 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /lec/lec4-code/memory_management/mem1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | 6 | int *nums = NULL; 7 | 8 | nums = (int*)malloc(sizeof(int) * 10); 9 | int i; 10 | for (i = 0; i < 10; ++i) { 11 | nums[i] = 9990 + i; 12 | printf("%d: %d\n", i, nums[i]); 13 | } 14 | 15 | free(nums); 16 | 17 | nums = NULL; 18 | 19 | for (i = 0; i < 10; ++i) { 20 | printf("%d: %d\n", i, nums[i]); 21 | } 22 | 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /lec/lec4-code/memory_management/mem2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | char *text; 6 | text = (char*)malloc(sizeof(char) * 10); 7 | 8 | int i; 9 | for (i = 0; i < 6; ++i) 10 | text[i] = "catdog"[i]; 11 | text[i] = '\0'; 12 | 13 | const char *the_text = text; 14 | printf("text is %s\n", text); 15 | printf("the_text is %s\n", the_text); 16 | printf("addr of text is %p\n", text); 17 | 18 | text = (char*)realloc(text, sizeof(char) * 10000); 19 | printf("text is %s\n", text); 20 | printf("addr of text is %p\n", text); 21 | 22 | for (i = 0; i < 6; ++i) 23 | printf("the_text is %d\n", the_text[i]); 24 | 25 | struct book { 26 | char *text; 27 | }; 28 | struct book *bookp = (struct book*)malloc(sizeof(struct book)); 29 | if (bookp == NULL) { 30 | fprintf(stderr, "cannot allocate %zu bytes\n", sizeof(struct book)); 31 | return 1; 32 | } 33 | bookp->text = text; 34 | printf("book text is: %s\n", bookp->text); 35 | free(bookp); 36 | bookp = NULL; 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | // purposely entered garbage there 45 | unsigned char *ptr = (unsigned char*)bookp; 46 | for (i = 0; i < sizeof(struct book); ++i) 47 | ptr[i] = i+1; 48 | 49 | struct book *bookp2 = (struct book*)malloc(sizeof(struct book)); 50 | printf("book text is: %s\n", bookp->text); 51 | 52 | free(text); 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /lec/lec4-code/memory_management/mem3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | 6 | int *nums; 7 | nums = (int*)malloc(10); 8 | if ( nums == NULL) { 9 | /// ... 10 | return 1; 11 | } 12 | 13 | int i; 14 | for (i = 0; i < 10; ++i) 15 | nums[i] = i+1; 16 | 17 | for (i = 0; i < 10; ++i) 18 | printf("%d is %d\n", i , nums[i]); 19 | 20 | free(nums); 21 | nums = NULL; 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /lec/lec4-code/memory_management/mem4.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() { 6 | 7 | char *chars; 8 | chars = (char*)malloc(10); 9 | 10 | memset(chars, 0x01, 10); 11 | if ( chars == NULL) { 12 | /// ... 13 | return 1; 14 | } 15 | 16 | int i; 17 | for (i = 0; i < 4; ++i) 18 | chars[i] = 'a' + i; 19 | chars[i] = '\0'; 20 | chars[4] = '\0'; 21 | 22 | for (i = 0; i < 10; ++i) 23 | printf("%d is %c\n", i , chars[i]); 24 | printf("chars is: %s\n", chars); 25 | 26 | free(chars); 27 | chars = NULL; 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /lec/lec4-code/memory_management/mem5.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | 6 | void *ptr = malloc(0); 7 | 8 | printf("%p\n", ptr); 9 | 10 | free(ptr); 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /lec/lec4-code/memory_management/stack.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int foo(int n, int m) { 4 | 5 | int x = 2; 6 | int y = 5; 7 | 8 | printf("addr of n is: %p\n", &n); 9 | printf("addr of m is: %p\n", &m); 10 | printf("addr of x is: %p\n", &x); 11 | printf("addr of y is: %p\n", &y); 12 | 13 | return 3; 14 | } 15 | 16 | int main() { 17 | 18 | // line 18 19 | 20 | int ret = foo(4, 2); 21 | // line 20 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /lec/lec4-code/memory_management/static.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int doit(int c) { 4 | float f = 3.0f; 5 | 6 | static int d = 0; 7 | 8 | d++; 9 | printf("addr of c is %p\n", &c); 10 | printf("addr of f is %p\n", &f); 11 | printf("addr of d is %p\n", &d); 12 | printf("addr of \"hello\" is %p\n", "hello"); 13 | 14 | return d; 15 | } 16 | 17 | int main() { 18 | 19 | int res = doit(4); 20 | res = doit(4); 21 | printf("res is : %d\n", res); 22 | 23 | return 0; 24 | } 25 | 26 | -------------------------------------------------------------------------------- /lec/lec5-code/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/lec5-code/.DS_Store -------------------------------------------------------------------------------- /lec/lec5-code/branch.c: -------------------------------------------------------------------------------- 1 | int main() 2 | { 3 | int x = 33; 4 | if (x == 33) { 5 | x = 480+7; 6 | } 7 | x += 768; 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /lec/lec5-code/branch.s: -------------------------------------------------------------------------------- 1 | .file "branch.c" 2 | .text 3 | .globl main 4 | .type main, @function 5 | main: 6 | .LFB0: 7 | .cfi_startproc 8 | pushq %rbp 9 | .cfi_def_cfa_offset 16 10 | .cfi_offset 6, -16 11 | movq %rsp, %rbp 12 | .cfi_def_cfa_register 6 13 | movl $33, -4(%rbp) 14 | cmpl $33, -4(%rbp) 15 | jne .L2 16 | movl $487, -4(%rbp) 17 | .L2: 18 | addl $768, -4(%rbp) 19 | movl $0, %eax 20 | popq %rbp 21 | .cfi_def_cfa 7, 8 22 | ret 23 | .cfi_endproc 24 | .LFE0: 25 | .size main, .-main 26 | .ident "GCC: (GNU) 8.2.1 20181127" 27 | .section .note.GNU-stack,"",@progbits 28 | -------------------------------------------------------------------------------- /lec/lec5-code/branch2.c: -------------------------------------------------------------------------------- 1 | int foo() 2 | { 3 | return 999; 4 | } 5 | int main() 6 | { 7 | int x = 33; 8 | if (x == 33) { 9 | x = 480+7; 10 | foo(); 11 | } 12 | x += 768; 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /lec/lec5-code/branch2.s: -------------------------------------------------------------------------------- 1 | .file "branch2.c" 2 | .text 3 | .globl foo 4 | .type foo, @function 5 | foo: 6 | .LFB0: 7 | .cfi_startproc 8 | pushq %rbp 9 | .cfi_def_cfa_offset 16 10 | .cfi_offset 6, -16 11 | movq %rsp, %rbp 12 | .cfi_def_cfa_register 6 13 | movl $999, %eax 14 | popq %rbp 15 | .cfi_def_cfa 7, 8 16 | ret 17 | .cfi_endproc 18 | .LFE0: 19 | .size foo, .-foo 20 | .globl main 21 | .type main, @function 22 | main: 23 | .LFB1: 24 | .cfi_startproc 25 | pushq %rbp 26 | .cfi_def_cfa_offset 16 27 | .cfi_offset 6, -16 28 | movq %rsp, %rbp 29 | .cfi_def_cfa_register 6 30 | subq $16, %rsp 31 | movl $33, -4(%rbp) 32 | cmpl $33, -4(%rbp) 33 | jne .L4 34 | movl $487, -4(%rbp) 35 | movl $0, %eax 36 | call foo 37 | .L4: 38 | addl $768, -4(%rbp) 39 | movl $0, %eax 40 | leave 41 | .cfi_def_cfa 7, 8 42 | ret 43 | .cfi_endproc 44 | .LFE1: 45 | .size main, .-main 46 | .ident "GCC: (GNU) 8.2.1 20181127" 47 | .section .note.GNU-stack,"",@progbits 48 | -------------------------------------------------------------------------------- /lec/lec5-code/branch3.c: -------------------------------------------------------------------------------- 1 | int foo() 2 | { 3 | return 999; 4 | } 5 | int main() 6 | { 7 | int (*fptr)() = foo; 8 | 9 | int x = 33; 10 | if (x == 33) { 11 | x = 480+7; 12 | fptr(); 13 | } 14 | x += 768; 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /lec/lec5-code/branch3.s: -------------------------------------------------------------------------------- 1 | .file "branch3.c" 2 | .text 3 | .globl foo 4 | .type foo, @function 5 | foo: 6 | .LFB0: 7 | .cfi_startproc 8 | pushq %rbp 9 | .cfi_def_cfa_offset 16 10 | .cfi_offset 6, -16 11 | movq %rsp, %rbp 12 | .cfi_def_cfa_register 6 13 | movl $999, %eax 14 | popq %rbp 15 | .cfi_def_cfa 7, 8 16 | ret 17 | .cfi_endproc 18 | .LFE0: 19 | .size foo, .-foo 20 | .globl main 21 | .type main, @function 22 | main: 23 | .LFB1: 24 | .cfi_startproc 25 | pushq %rbp 26 | .cfi_def_cfa_offset 16 27 | .cfi_offset 6, -16 28 | movq %rsp, %rbp 29 | .cfi_def_cfa_register 6 30 | subq $16, %rsp 31 | leaq foo(%rip), %rax 32 | movq %rax, -8(%rbp) 33 | movl $33, -12(%rbp) 34 | cmpl $33, -12(%rbp) 35 | jne .L4 36 | movl $487, -12(%rbp) 37 | movq -8(%rbp), %rdx 38 | movl $0, %eax 39 | call *%rdx 40 | .L4: 41 | addl $768, -12(%rbp) 42 | movl $0, %eax 43 | leave 44 | .cfi_def_cfa 7, 8 45 | ret 46 | .cfi_endproc 47 | .LFE1: 48 | .size main, .-main 49 | .ident "GCC: (GNU) 8.2.1 20181127" 50 | .section .note.GNU-stack,"",@progbits 51 | -------------------------------------------------------------------------------- /lec/lec5-code/errno-ex.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // extern int errno; 4 | 5 | #include 6 | #include 7 | 8 | void foo() { 9 | FILE *fp = fopen("doesn't exist", "r"); 10 | } 11 | 12 | int main() { 13 | 14 | perror("first line of code"); 15 | 16 | foo(); 17 | printf("errno: %d\n", errno); 18 | perror("we tried to read a file"); 19 | 20 | errno = 0; 21 | 22 | int x = 5; 23 | printf("errno: %d\n", errno); 24 | 25 | void *data = malloc(-1); 26 | printf("errno: %d\n", errno); 27 | 28 | free(data); 29 | printf("errno: %d\n", errno); 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /lec/lec5-code/errno-ex2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void foo() { 6 | FILE *fp = fopen("doesn't exist", "r"); 7 | } 8 | 9 | int main() { 10 | foo(); 11 | printf("errno: %d\n", errno); 12 | perror(""); 13 | 14 | int x = 5; 15 | printf("errno: %d\n", errno); 16 | perror(""); 17 | 18 | void *data = (void*)malloc(1); 19 | printf("errno: %d\n", errno); 20 | perror(""); 21 | 22 | free(data); 23 | printf("errno: %d\n", errno); 24 | perror(""); 25 | 26 | FILE *fp2 = fopen("skinner.txt", "r"); 27 | printf("errno: %d\n", errno); 28 | perror(""); 29 | 30 | return 0; 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /lec/lec5-code/list4.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // our node structure 5 | struct node { 6 | int value; 7 | struct node *next; 8 | }; 9 | 10 | struct node *list_append(struct node *head, struct node *n); 11 | void list_free(struct node *head); 12 | void pfree(void *address); 13 | void print_list(struct node *head); 14 | 15 | // create a new node with value 16 | struct node *node_create(int value) { 17 | struct node *n = (struct node*)malloc(sizeof(struct node)); 18 | n->value = value; 19 | n->next = NULL; 20 | return n; 21 | } 22 | 23 | // adds a node to the end of the linked list 24 | // returns the new head of the linked list 25 | struct node *list_append(struct node *head, struct node *n) { 26 | if (head == NULL) 27 | return n; 28 | 29 | struct node *cursor = head; 30 | while (cursor->next != NULL) 31 | cursor = cursor->next; 32 | 33 | cursor->next = n; 34 | return head; 35 | } 36 | 37 | int main() { 38 | struct node *head; 39 | 40 | head = node_create(28); 41 | head = list_append( head, node_create(14) ); 42 | head = list_append( head, node_create(3) ); 43 | head = list_append( head, node_create(7) ); 44 | 45 | print_list(head); 46 | 47 | list_free(head); 48 | 49 | return 0; 50 | } 51 | 52 | void print_list(struct node *head) { 53 | if (head == NULL) { 54 | printf("empty list!\n"); 55 | return; 56 | } 57 | struct node *cursor = head; 58 | while (cursor != NULL) { 59 | printf("cursor element is : %d\n", cursor->value); 60 | cursor = cursor->next; 61 | } 62 | } 63 | 64 | void pfree(void *address) { 65 | struct node *tmp = (struct node*)address; 66 | printf("freeing %p %d\n", address, tmp->value); 67 | free(address); 68 | } 69 | 70 | void list_free(struct node *head) 71 | { 72 | if (head == NULL) 73 | return; 74 | 75 | // at this point 1+ elements 76 | struct node *cursor = head; 77 | 78 | if (cursor->next == NULL) { 79 | // element 1 only case 80 | pfree(head); 81 | return; 82 | } 83 | 84 | // at this point 2+ cases 85 | struct node *tmp; 86 | while (cursor != NULL) { 87 | tmp = cursor->next; 88 | pfree(cursor); 89 | cursor = tmp; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /lec/lec5-code/read-sig.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | volatile int flag = 0; 7 | 8 | // signal handler 9 | void interrupted(int val) { 10 | flag = 1; 11 | } 12 | 13 | int main() { 14 | void (*old_sig_int_handler)(int); 15 | int res; 16 | 17 | // get the old handler 18 | old_sig_int_handler = signal(SIGINT, interrupted); 19 | if (old_sig_int_handler == SIG_ERR) { 20 | perror("could not change signal handler"); 21 | return -1; 22 | } 23 | 24 | char buffer[100]; 25 | flag = 0; 26 | ssize_t result = read(0, buffer, 100); 27 | 28 | // check for errors 29 | int error_val = errno; 30 | if (error_val != 0) { 31 | printf("\n"); 32 | printf("error_val: %d\n", error_val); 33 | printf("read() was interrupted by a signal\n"); 34 | printf("flag is: %d\n", flag); 35 | perror("hmm errno non zero ---> "); 36 | } 37 | 38 | fprintf(stderr, "managed to read: %d characters\n", result); 39 | 40 | printf("buffer contains: "); 41 | int i; 42 | for (i = 0; i < result; ++i) 43 | printf("_%c", buffer[i]); 44 | printf("\n"); 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /lec/lec5-code/read-sig2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | volatile int flag = 0; 7 | 8 | // signal handler 9 | void interrupted(int val) { 10 | flag = 1; 11 | } 12 | 13 | int main() 14 | { 15 | struct sigaction old_sig_int, new_sig_int; 16 | int res; 17 | 18 | // 19 | // get the old handler 20 | res = sigaction (SIGINT, NULL, &old_sig_int); 21 | if (0 != res) { 22 | perror("could not obtain old handler"); 23 | return -1; 24 | } 25 | 26 | // 27 | // setup new handler 28 | // function pointer for caught signal 29 | new_sig_int.sa_handler = interrupted; 30 | new_sig_int.sa_flags = 0; 31 | 32 | // install the new handler 33 | res = sigaction(SIGINT, &new_sig_int, NULL); 34 | if (0 != res) { 35 | perror("could not install new handler"); 36 | return -2; 37 | } 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | char buffer[100]; 47 | flag = 0; 48 | ssize_t result = read(0, buffer, 100); 49 | 50 | // check for errors 51 | int error_val = errno; 52 | if (error_val != 0) { 53 | printf("\n"); 54 | printf("error_val: %d\n", error_val); 55 | printf("read() was interrupted by a signal\n"); 56 | printf("flag is: %d\n", flag); 57 | perror("hmm errno non zero ---> "); 58 | } 59 | 60 | fprintf(stderr, "managed to read: %d characters\n", result); 61 | 62 | printf("buffer contains: "); 63 | int i; 64 | for (i = 0; i < result + 20; ++i) 65 | printf("_%c", buffer[i]); 66 | printf("\n"); 67 | 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /lec/lec5-code/sig-alarm.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | // for alarm 6 | #include 7 | 8 | int toolong = 0; 9 | 10 | void wakeup(int arg) 11 | { 12 | toolong = 1; 13 | } 14 | 15 | int main() 16 | { 17 | toolong = 0; 18 | signal(SIGALRM, wakeup); 19 | alarm(3); 20 | printf("You have 3 seconds to enter a number: "); 21 | int x; 22 | scanf("%d", &x); 23 | if (toolong == 1) { 24 | printf("Sorry, you took to long\n"); 25 | printf("Program terminated\n"); 26 | return 1; 27 | } 28 | 29 | printf("blue skies, happiness and unicorns %d\n", x); 30 | 31 | return 0; 32 | } 33 | 34 | -------------------------------------------------------------------------------- /lec/lec5-code/sig-int.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | volatile int interrupted = 0; 6 | 7 | void impatient(int arg) 8 | { 9 | interrupted = 1; 10 | } 11 | 12 | int main() 13 | { 14 | void (*variable)(int) = impatient; 15 | signal(SIGINT, variable); 16 | printf("We are going to do something for a long time\n"); 17 | 18 | while (!interrupted) 19 | usleep(10); 20 | 21 | printf("Oh..you didn't like waiting\n"); 22 | printf("Program terminated\n"); 23 | 24 | return 0; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /lec/lec5-code/simple_function_pointer.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | 5 | printf("function pointer: %p\n", main); 6 | 7 | return 0; 8 | 9 | } 10 | 11 | -------------------------------------------------------------------------------- /lec/lec5-code/skinner.txt: -------------------------------------------------------------------------------- 1 | Skinner said the teachers will crack any minute Purple Monkey Dishwasher 2 | -------------------------------------------------------------------------------- /lec/lec6-code/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/lec6-code/.DS_Store -------------------------------------------------------------------------------- /lec/lec6-code/dlist.c: -------------------------------------------------------------------------------- 1 | /* dlist.c */ 2 | 3 | #include 4 | 5 | #include "dlist.h" 6 | 7 | int dlist_size; 8 | 9 | 10 | -------------------------------------------------------------------------------- /lec/lec6-code/dlist.h: -------------------------------------------------------------------------------- 1 | /* dlist.h */ 2 | 3 | struct dlist { 4 | 5 | void * data; 6 | 7 | 8 | struct dlist *next; 9 | struct dlist *prev; 10 | }; 11 | 12 | extern int dlist_size; 13 | -------------------------------------------------------------------------------- /lec/lec6-code/foo.c: -------------------------------------------------------------------------------- 1 | /* foo.c */ 2 | 3 | // symbol for linker 4 | const char* foo() { 5 | return "foo has finished."; 6 | } 7 | -------------------------------------------------------------------------------- /lec/lec6-code/foo_preprocessor.txt: -------------------------------------------------------------------------------- 1 | # 1 "foo.c" 2 | # 1 "" 3 | # 1 "" 4 | # 31 "" 5 | # 1 "/usr/include/stdc-predef.h" 1 3 4 6 | # 32 "" 2 7 | # 1 "foo.c" 8 | 9 | 10 | 11 | const char* foo() { 12 | return "foo has finished."; 13 | } 14 | -------------------------------------------------------------------------------- /lec/lec6-code/hello.c: -------------------------------------------------------------------------------- 1 | /* hello.c */ 2 | #include 3 | 4 | // symbol for linker 5 | extern const char * foo(); 6 | 7 | // symbol for linker 8 | int global_size = 0; 9 | 10 | // local variables to the module 11 | static char *msg = "Sometihng special"; 12 | 13 | // local functions 14 | static void print_message() { 15 | printf("%s\n", msg); 16 | } 17 | 18 | // symbol for linker 19 | int main() { 20 | 21 | // local variables to the function 22 | int x = 0; 23 | int y = 1 - x; 24 | 25 | const char *string = foo(); 26 | printf("%s\n", string); 27 | 28 | printf("%p: \n", foo); 29 | 30 | // substitute msg -> 0x3017 31 | printf("%s\n", msg); 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /lec/lec6-code/strace_hello.txt: -------------------------------------------------------------------------------- 1 | $ strace ./hello 2 | execve("./hello", ["./hello"], [/* 19 vars */]) = 0 3 | brk(NULL) = 0x55ecadb68000 4 | access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) 5 | mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0d37d2c000 6 | access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) 7 | open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 8 | fstat(3, {st_mode=S_IFREG|0644, st_size=177281, ...}) = 0 9 | mmap(NULL, 177281, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f0d37d00000 10 | close(3) = 0 11 | access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) 12 | open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 13 | read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320\3\2\0\0\0\0\0"..., 832) = 832 14 | fstat(3, {st_mode=S_IFREG|0755, st_size=1689360, ...}) = 0 15 | mmap(NULL, 3795360, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f0d3776d000 16 | mprotect(0x7f0d37902000, 2097152, PROT_NONE) = 0 17 | mmap(0x7f0d37b02000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x195000) = 0x7f0d37b02000 18 | mmap(0x7f0d37b08000, 14752, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f0d37b08000 19 | close(3) = 0 20 | mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0d37cfe000 21 | arch_prctl(ARCH_SET_FS, 0x7f0d37cfe700) = 0 22 | mprotect(0x7f0d37b02000, 16384, PROT_READ) = 0 23 | mprotect(0x55ecac6fd000, 4096, PROT_READ) = 0 24 | mprotect(0x7f0d37d2f000, 4096, PROT_READ) = 0 25 | munmap(0x7f0d37d00000, 177281) = 0 26 | fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0 27 | brk(NULL) = 0x55ecadb68000 28 | brk(0x55ecadb89000) = 0x55ecadb89000 29 | write(1, "0x55ecac4fd844\n", 150x55ecac4fd844 30 | ) = 15 31 | write(1, "foo has finished.\n", 18foo has finished. 32 | ) = 18 33 | write(1, "0x55ecac4fd844: \n", 170x55ecac4fd844: 34 | ) = 17 35 | write(1, "Sometihng special\n", 18Sometihng special 36 | ) = 18 37 | exit_group(0) = ? 38 | +++ exited with 0 +++ 39 | -------------------------------------------------------------------------------- /lec/lec7-code/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/lec7-code/.DS_Store -------------------------------------------------------------------------------- /lec/lec7-code/env_check.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char *argv[], char *envp[]) 4 | { 5 | int i = 0; 6 | 7 | printf("string %p\n", "constant string"); 8 | printf("address of argv[1] is %p\n", argv[1]); 9 | printf("address of i %p\n", &i); 10 | 11 | while (1) 12 | { 13 | printf("%s\n", envp[i]); 14 | i++; 15 | if (envp[i] == NULL) 16 | break; 17 | } 18 | 19 | return 0; 20 | } -------------------------------------------------------------------------------- /lec/lec7-code/exec_prog1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | printf("hello, I am program 1: %d\n", getpid()); 7 | 8 | int i; 9 | for (i = 0; i < argc; ++i) 10 | printf("%d: %s\n", i, argv[i]); 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /lec/lec7-code/exec_prog2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | printf("hello, I am program 2: %d\n", getpid()); 7 | 8 | int i; 9 | for (i = 0; i < argc; ++i) 10 | printf("%d: %s\n", i, argv[i]); 11 | 12 | if (-1 == execl("exec_prog1", "Silly executable name", "1st arg", "2nd arg", 0)) 13 | perror("could not execute exec_prog1"); 14 | 15 | printf("program 2 continues sadly: %d\n", getpid()); 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /lec/lec7-code/exec_prog3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | printf("hello, I am program 3: %d\n", getpid()); 7 | 8 | int i; 9 | for (i = 0; i < argc; ++i) 10 | printf("%d: %s\n", i, argv[i]); 11 | 12 | if (-1 == execl("exec_prog2", "exec_prog2", "index[1]", "index[2]", "index[3]", 0 )) 13 | perror("could not execute exec_prog2"); 14 | 15 | printf("program 3 continues sadly: %d\n", getpid()); 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /lec/lec7-code/exec_prog_example.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | gcc -o exec_prog1 exec_prog1.c 4 | gcc -o exec_prog2 exec_prog2.c 5 | gcc -o exec_prog3 exec_prog3.c 6 | 7 | echo "run the executable" 8 | echo "example: " 9 | echo "./exec_prog3 zee zoo zip!" 10 | -------------------------------------------------------------------------------- /lec/lec7-code/exec_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | printf("hello: %d\n", getpid()); 7 | 8 | int result = execl("/usr/sbin/echo", "echo", "Moe", 0); 9 | if (-1 == result) 10 | perror("could not exec program"); 11 | else { 12 | printf("This should never happen\n"); 13 | } 14 | 15 | // if execl succeeds, we never reach here 16 | printf("world: %d\n", getpid()); 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /lec/lec7-code/exec_test1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | 6 | printf("hello: %d\n", getpid()); 7 | char *chunk = (char*)malloc(10000); 8 | 9 | int result = execl("simple", "echo", "Moe", 0); 10 | if (-1 == result) { 11 | perror("could not exec program"); 12 | // unallocated memory does not matter if execl succeeds! 13 | // this code will execute when it fails 14 | free(chunk); 15 | return 1; 16 | } 17 | 18 | // essentially unreachable if C implementation done correctly! 19 | 20 | // unallocated memory does not matter if execl succeeds! 21 | // this code will execute when it fails 22 | free(chunk); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /lec/lec7-code/fork_ex.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | int main() { 6 | 7 | printf("hello: %d\n", getpid()); 8 | 9 | int result = fork(); 10 | 11 | char *owner = "parent"; 12 | if (result == 0){ 13 | printf("I am the child: %d\n", getpid()); 14 | owner = "child"; 15 | } else { 16 | usleep(10); 17 | printf("I am the parent: %d\n", getpid()); 18 | } 19 | 20 | printf("%s world\n", owner); 21 | 22 | return 0; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /lec/lec7-code/fork_ex1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | 6 | printf("hello: %d\n", getpid()); 7 | 8 | fork(); 9 | 10 | printf("world: %d\n", getpid()); 11 | 12 | return 0; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /lec/lec7-code/fork_ex2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int *numbers = NULL; 6 | int numbers_size = 0; 7 | 8 | int main() { 9 | 10 | numbers = (int*)malloc(10 * sizeof(int)); 11 | numbers_size = 10; 12 | numbers[0] = 999; 13 | 14 | printf("hello: %d\n", getpid()); 15 | 16 | int result = fork(); 17 | 18 | char *owner = "parent"; 19 | if (result == 0){ 20 | printf("I am the child: %d\n", getpid()); 21 | owner = "child"; 22 | printf("%s: numbers_size: %d\n", owner, numbers_size); 23 | printf("%s: numbers[0]: %d\n", owner, numbers[0]); 24 | free(numbers); 25 | return 0; // terminate program 26 | } else { 27 | usleep(10); 28 | printf("I am the parent: %d\n", getpid()); 29 | printf("%s: numbers_size: %d\n", owner, numbers_size); 30 | printf("%s: numbers[0]: %d\n", owner, numbers[0]); 31 | numbers[0] = 876; 32 | printf("%s: numbers[0]: %d\n", owner, numbers[0]); 33 | free(numbers); 34 | } 35 | 36 | printf("%s world: %d\n", owner, getpid()); 37 | 38 | return 0; // terminate program 39 | } 40 | -------------------------------------------------------------------------------- /lec/lec7-code/fork_ex3.c: -------------------------------------------------------------------------------- 1 | void foo(char *str, char increment) { 2 | static int x = 0; 3 | 4 | if (increment) { 5 | x++; 6 | printf("%s incrementing x: %d\n", str, x); 7 | } 8 | else { 9 | printf("%s reporting x: %d\n", str, x); 10 | } 11 | } 12 | 13 | int main() { 14 | foo("prefork", 1); 15 | foo("prefork", 1); 16 | foo("prefork", 0); 17 | 18 | int result = fork(); 19 | char *owner = "parent"; 20 | if (result == 0){ 21 | owner = "child"; 22 | printf("I am the child: %d\n", getpid()); 23 | foo(owner, 0); 24 | foo(owner, 1); 25 | foo(owner, 1); 26 | foo(owner, 0); 27 | printf("%s done\n", owner); 28 | } else { 29 | printf("I am the parent: %d\n", getpid()); 30 | foo(owner, 0); 31 | foo(owner, 0); 32 | foo(owner, 0); 33 | foo(owner, 1); 34 | foo(owner, 1); 35 | foo(owner, 1); 36 | foo(owner, 1); 37 | foo(owner, 1); 38 | printf("%s done\n", owner); 39 | } 40 | 41 | return 0; // terminate program 42 | } 43 | -------------------------------------------------------------------------------- /lec/lec7-code/fork_ex4.c: -------------------------------------------------------------------------------- 1 | void foo(char *str, char increment) { 2 | static int x = 0; 3 | 4 | if (increment) { 5 | x++; 6 | printf("%s incrementing x: %d\n", str, x); 7 | } 8 | else { 9 | printf("%s reporting x: %d\n", str, x); 10 | } 11 | } 12 | 13 | int main() { 14 | foo("prefork", 1); 15 | foo("prefork", 1); 16 | foo("prefork", 0); 17 | 18 | int result = fork(); 19 | char *owner = "parent"; 20 | if (result == 0){ 21 | owner = "child"; 22 | printf("I am the child: %d\n", getpid()); 23 | int i = 0; 24 | while (i < 1000) { 25 | foo(owner, rand()%2); // 1 in 2 chance increment 26 | i++; 27 | } 28 | } else { 29 | printf("I am the parent: %d\n", getpid()); 30 | int i = 0; 31 | while (i < 1000) { 32 | foo(owner, rand()%100==0); // 1 in 100 chance increment 33 | i++; 34 | } 35 | } 36 | 37 | usleep(1000); 38 | foo(owner, 0); 39 | printf("%s done\n", owner); 40 | 41 | return 0; // terminate program 42 | } 43 | -------------------------------------------------------------------------------- /lec/lec7-code/fork_exec_wait.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() { 6 | // parent prints things before child 7 | 8 | // point of choosing which process to execute 9 | int pid = fork(); 10 | if (pid == 0) { 11 | printf("I am the child: %d\n", getpid()); 12 | printf("child is searching for something special\n"); 13 | int result = execl("/usr/sbin/grep", "grep", "-n", "special", "simple.c", 0); 14 | if (-1 == result) { 15 | perror("failed to run program"); 16 | return result; 17 | } 18 | // we never return ... 19 | } else if (pid > 0) { 20 | printf("I am the parent: %d\n", getpid()); 21 | 22 | printf("parent is %d and waiting for child %d\n", getpid(), pid); 23 | int status; 24 | int result = wait(&status); 25 | if (-1 == result) { 26 | // failed case 27 | perror("could not wait for child process"); 28 | } else { 29 | printf("child status code: %d\n", status); 30 | if (0 != status) 31 | printf("child failed to do its task\n"); 32 | else 33 | printf("child was successful!\n"); 34 | } 35 | } else { 36 | // fail case 37 | perror("failed to fork"); 38 | } 39 | 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /lec/lec7-code/fork_wait0.c: -------------------------------------------------------------------------------- 1 | /* What the operating system does with scheduling of two processes? 2 | */ 3 | #include 4 | #include 5 | #include 6 | 7 | int main() { 8 | 9 | // point of choosing which process to execute 10 | int pid = fork(); 11 | 12 | if (pid == 0) { 13 | printf("I am the child: %d\n", getpid()); 14 | int i; 15 | for (i = 0; i < 100; ++i) 16 | printf("child: %d\n", i); 17 | printf("\n"); 18 | 19 | return 0; 20 | } else if (pid > 0) { 21 | printf("I am the parent: %d\n", getpid()); 22 | 23 | int i; 24 | for (i = 0; i < 100; ++i) 25 | printf("parent: %d\n", i); 26 | printf("\n"); 27 | 28 | } else { 29 | // fail case 30 | } 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /lec/lec7-code/fork_wait1.c: -------------------------------------------------------------------------------- 1 | /* Forcing sychronisation between parent and child 2 | */ 3 | #include 4 | #include 5 | #include 6 | 7 | int main() { 8 | // point of choosing which process to execute 9 | int pid = fork(); 10 | 11 | if (pid == 0) 12 | { 13 | printf("I am the child: %d\n", getpid()); 14 | int i; 15 | for (i = 0; i < 100; ++i) 16 | printf("child: %d\n", i); 17 | printf("\n"); 18 | 19 | return 0; 20 | } else if (pid > 0) { 21 | printf("I am the parent: %d\n", getpid()); 22 | 23 | int status; 24 | int result = wait(&status); 25 | if (-1 == result) { 26 | // failed case 27 | } 28 | 29 | int i; 30 | for (i = 0; i < 100; ++i) 31 | printf("parent: %d\n", i); 32 | printf("\n"); 33 | 34 | } else { 35 | // fail case 36 | } 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /lec/lec7-code/mini-shell1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main() { 7 | while (1) { 8 | printf("Enter command: \n"); 9 | char buffer[2048]; 10 | char *line = fgets(buffer, 2048, stdin); 11 | 12 | char *command = NULL; 13 | int cmd_code = 0; 14 | if (0 == strncmp(line, "sort", 4)) { 15 | command = "/usr/sbin/sort"; 16 | cmd_code = 1; 17 | } else if (0 == strncmp(line, "echo", 4)) { 18 | command = "/usr/sbin/echo"; 19 | cmd_code = 2; 20 | } else if (0 == strncmp(line, "sleep", 5)) { 21 | command = "/usr/sbin/sleep"; 22 | cmd_code = 3; 23 | } else if (0 == strncmp(line, "quit", 4)) { 24 | printf("User ended session: Bye!\n"); 25 | break; 26 | } 27 | if (command == NULL) { 28 | printf("bad command: %s\n", line); 29 | continue; 30 | } 31 | printf("command is: %s\n", command); 32 | printf("line is: %s\n", line); 33 | 34 | // tokenise arguments (generic) 35 | // ...left as exercise for reader 36 | // hint: strsep or strtok with delimiter ' ' 37 | 38 | // hackery: replace new line with null byte 39 | strchr(line, '\n')[0] = '\0'; // <-- scream about pointers here 40 | // hackery: get next string at first space char 41 | char *first_arg = strchr(line, ' '); 42 | if (first_arg) 43 | first_arg++; // exists, move after space 44 | 45 | int pid = fork(); 46 | if (pid == 0) { 47 | int result = 0; 48 | switch(cmd_code) { 49 | case 1: 50 | result = execl(command, "sort", "numbers.txt", 0); 51 | break; 52 | case 2: 53 | result = execl(command, "echo", first_arg, 0); 54 | break; 55 | case 3: 56 | result = execl(command, "sleep", first_arg, 0); 57 | break; 58 | default: 59 | fprintf(stderr, "unknown command code: %d\n", cmd_code); 60 | break; 61 | } 62 | return 0; 63 | } else if (pid > 0) { 64 | // wait for child process to finish 65 | int status; 66 | int result = wait(&status); 67 | } 68 | } // while loop 69 | 70 | return 0; 71 | } -------------------------------------------------------------------------------- /lec/lec7-code/simple.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void special_function() { 4 | printf("%s executed!\n", __FUNCTION__); 5 | } 6 | 7 | int main() { 8 | printf("foreign program here\n"); 9 | special_function(); 10 | 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /lec/lec8-code/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/lec8-code/.DS_Store -------------------------------------------------------------------------------- /lec/lec8-code/nb.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int main() { 11 | int fd = open("tmpfile", O_RDONLY | O_NONBLOCK); 12 | if (-1 == fd) { 13 | perror("failed to open file"); 14 | return 1; 15 | } 16 | 17 | printf("fd: %d\n", fd); 18 | fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); 19 | 20 | char buffer[100]; 21 | while (1) { 22 | ssize_t nread = read(fd, buffer, 10); 23 | if (-1 == nread) { 24 | if (errno == EAGAIN) { 25 | printf("stop the blocking call to read\n"); 26 | } else { 27 | perror("something wrong"); 28 | } 29 | sleep(1); 30 | continue; 31 | } 32 | else if (0 == nread) { 33 | if (errno == EAGAIN) { 34 | printf("stop the blocking call to read\n"); 35 | sleep(1); 36 | continue; 37 | } else { 38 | // end of file? 39 | break; 40 | } 41 | } else { 42 | buffer[nread] = '\0'; 43 | printf("new data: %s\n", buffer); 44 | } 45 | } 46 | printf("Program ended\n"); 47 | close(fd); 48 | 49 | return 0; 50 | } 51 | 52 | -------------------------------------------------------------------------------- /lec/lec8-code/nb_stdin.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int main() { 11 | int fd = 0; 12 | printf("fd: %d\n", fd); 13 | fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); 14 | 15 | char buffer[100]; 16 | while (1) { 17 | ssize_t nread = read(fd, buffer, 10); 18 | if (-1 == nread) { 19 | if (errno == EAGAIN) { 20 | printf("stop the blocking call to read\n"); 21 | } else { 22 | perror("something wrong"); 23 | } 24 | sleep(1); 25 | continue; 26 | } 27 | else if (0 == nread) { 28 | if (errno == EAGAIN) { 29 | printf("stop the blocking call to read\n"); 30 | sleep(1); 31 | continue; 32 | } else { 33 | // could be end of file 34 | break; 35 | } 36 | } else { 37 | buffer[nread] = '\0'; 38 | printf("new data: %s\n", buffer); 39 | } 40 | } 41 | printf("Program ended\n"); 42 | close(fd); 43 | return 0; 44 | } 45 | 46 | -------------------------------------------------------------------------------- /lec/lec8-code/pipe.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() { 6 | int fd[2] = {-1}; 7 | int ret = pipe(fd); 8 | 9 | char buffer_in[20]; 10 | ssize_t nread2 = read(0, buffer_in, 20); 11 | buffer_in[nread2] = '\0'; 12 | 13 | ssize_t nwritten = write(fd[1], buffer_in, strlen(buffer_in) ); 14 | if (-1 == nwritten) { 15 | perror("error"); 16 | } else { 17 | printf("bytes has written: %zd\n", nwritten); 18 | } 19 | 20 | char buffer[20]; 21 | strncpy(buffer, "This is a long sentence, much longer than 20 characters", 20); 22 | 23 | // ssize_t nread = read(fd[0], buffer_in, 19); 24 | ssize_t nread = read(fd[0], buffer, 19); 25 | 26 | if (-1 == nread) { 27 | perror("error"); 28 | } else { 29 | buffer[nread] = '\0'; 30 | printf("bytes has read: %zd\n", nread); 31 | printf("text has read: %s\n", buffer); 32 | } 33 | 34 | close(fd[0]); 35 | close(fd[1]); 36 | return 0; 37 | 38 | } 39 | -------------------------------------------------------------------------------- /lec/lec8-code/process_pipe_single.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() { 6 | int fd[2] = {-1}; 7 | printf("fd1: %d %d\n", fd[0], fd[1]); 8 | 9 | int ret = pipe(fd); 10 | printf("fd2: %d %d\n", fd[0], fd[1]); 11 | 12 | char buffer_in[20]; 13 | puts("1"); 14 | ssize_t nread2 = read(0, buffer_in, 20); 15 | puts("2"); 16 | buffer_in[nread2] = '\0'; 17 | 18 | int pid = fork(); 19 | if (0 == pid) { 20 | 21 | // child 22 | char buffer[20]; 23 | strncpy(buffer, "This is a long sentence, much longer than 20 characters", 20); 24 | 25 | printf("Child is waiting for input..\n"); 26 | ssize_t nread = read(fd[0], buffer, 19); 27 | if (-1 == nread) { 28 | perror("error"); 29 | } else { 30 | buffer[nread] = '\0'; 31 | printf("nread: %zd\n", nread); 32 | printf("%s\n", buffer); 33 | } 34 | 35 | } else { 36 | 37 | sleep(1); 38 | 39 | // parent 40 | printf("child pid is %d\n", pid); 41 | 42 | ssize_t nwritten = write(fd[1], buffer_in, strlen(buffer_in) ); 43 | if (-1 == nwritten) { 44 | perror("error"); 45 | } else { 46 | printf("%zd bytes written\n", nwritten); 47 | } 48 | printf("parent has completed\n"); 49 | 50 | } 51 | 52 | close(fd[0]); 53 | close(fd[1]); 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /lec/lec8-code/select.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main() { 7 | 8 | fd_set allfds; 9 | //FD_ZERO(&allfds); 10 | //FD_SET(0, &allfds); 11 | 12 | int maxfd = 0 + 1; 13 | 14 | struct timeval timeout; 15 | 16 | while (1) { 17 | timeout.tv_sec = 0; 18 | timeout.tv_usec = 100; 19 | 20 | FD_ZERO(&allfds); 21 | FD_SET(0, &allfds); 22 | int ret = select(maxfd, &allfds, NULL, NULL, &timeout); 23 | if (0 == ret) { 24 | printf("Nothing to report\n"); 25 | 26 | } else { 27 | printf("%d file descriptors ready\n", ret); 28 | 29 | int modified = FD_ISSET(0, &allfds); 30 | printf("modified: %d\n", modified); 31 | 32 | char buffer[100]; 33 | int nread = read(0, buffer, 100); 34 | if (-1 == nread) { 35 | perror("failed to read"); 36 | } else { 37 | buffer[nread] = '\0'; 38 | printf("received %s\n", buffer); 39 | if (strncmp(buffer, "quit", 4) == 0) 40 | break; 41 | } 42 | } 43 | } 44 | 45 | return 0; 46 | } 47 | 48 | -------------------------------------------------------------------------------- /lec/lec9-code/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/lec9-code/.DS_Store -------------------------------------------------------------------------------- /lec/lec9-code/a.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/lec/lec9-code/a.out -------------------------------------------------------------------------------- /lec/lec9-code/mutex_simple.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | char *message = "Chocolate microscopes?"; 6 | int mindex = 0; 7 | pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; 8 | size_t message_len = 0; 9 | 10 | pthread_t my_thread; 11 | 12 | void* threadF(void *arg) { 13 | while (1) { 14 | pthread_mutex_lock(&lock); 15 | if (mindex < message_len) { 16 | printf("%c", message[mindex]); 17 | mindex++; 18 | } else { 19 | pthread_mutex_unlock(&lock); 20 | break; 21 | } 22 | pthread_mutex_unlock(&lock); 23 | } 24 | printf("Thread end at %d.\n", mindex); 25 | return NULL; 26 | } 27 | 28 | int main(void) { 29 | message_len = strlen(message); 30 | pthread_create(&my_thread,NULL,threadF,NULL); 31 | 32 | while (1) { 33 | pthread_mutex_lock(&lock); 34 | if (mindex < message_len) { 35 | printf("%c", message[mindex]); 36 | mindex++; 37 | } else { 38 | pthread_mutex_unlock(&lock); 39 | break; 40 | } 41 | pthread_mutex_unlock(&lock); 42 | } 43 | printf("main end at %d.\n", mindex); 44 | pthread_join(my_thread, NULL); 45 | printf("\n"); 46 | printf("all threads ended: %d.\n", mindex); 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /lec/lec9-code/mutex_simple_no_lock.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | char *message = "Chocolate microscopes?"; 6 | int mindex = 0; 7 | size_t message_len = 0; 8 | 9 | pthread_t my_thread; 10 | 11 | void* threadF(void *arg) { 12 | while (1) { 13 | if (mindex < message_len) { 14 | printf("%c", message[mindex]); 15 | mindex++; 16 | } else 17 | break; 18 | } 19 | printf("Thread ended at %d.\n", mindex); 20 | return NULL; 21 | } 22 | 23 | int main(void) { 24 | message_len = strlen(message); 25 | pthread_create(&my_thread,NULL,threadF,NULL); 26 | 27 | while (1) { 28 | if (mindex < message_len) { 29 | printf("%c", message[mindex]); 30 | mindex++; 31 | } else { 32 | break; 33 | } 34 | } 35 | printf("main ended at %d.\n", mindex); 36 | pthread_join(my_thread, NULL); 37 | printf("\n"); 38 | printf("all threads ended: %d.\n", mindex); 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /sem/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/sem/.DS_Store -------------------------------------------------------------------------------- /sem/sem10/datarace.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #define NTHREADS (4) 6 | 7 | struct thread_data { 8 | pthread_mutex_t mutex_t1; 9 | pthread_mutex_t mutex_t2; 10 | int data; 11 | }; 12 | 13 | void* work1(void* arg) { 14 | struct thread_data* data = (struct thread_data*) arg; 15 | for(int i = 0; i < 10000; i++) { 16 | pthread_mutex_lock(&(data->mutex_t1)); 17 | 18 | pthread_mutex_lock(&(data->mutex_t2)); 19 | data->data += 1; 20 | printf("%d\n", data->data); 21 | pthread_mutex_unlock(&(data->mutex_t1)); 22 | pthread_mutex_unlock(&(data->mutex_t2)); 23 | } 24 | return NULL; 25 | } 26 | 27 | 28 | void* work2(void* arg) { 29 | 30 | struct thread_data* data = (struct thread_data*) arg; 31 | for(int i = 0; i < 10000; i++) { 32 | pthread_mutex_lock(&(data->mutex_t2)); 33 | //Only a thread that has locked mutex_t2 can be here 34 | 35 | pthread_mutex_lock(&(data->mutex_t1)); 36 | //Only a thread that has locked mutex_t1 can be here 37 | 38 | data->data += 1; 39 | printf("%d\n", data->data); 40 | 41 | pthread_mutex_unlock(&(data->mutex_t1)); 42 | pthread_mutex_unlock(&(data->mutex_t2)); 43 | } 44 | 45 | 46 | return NULL; 47 | } 48 | 49 | 50 | int main() { 51 | 52 | struct thread_data data = { PTHREAD_MUTEX_INITIALIZER, 53 | PTHREAD_MUTEX_INITIALIZER, 54 | 0 55 | }; 56 | 57 | pthread_t threads[2]; 58 | pthread_create(threads, NULL, work1, &data); 59 | pthread_create(threads+1, NULL, work2, &data); 60 | 61 | 62 | for(int i = 0; i < 2; i++) { 63 | pthread_join(threads[i], NULL); 64 | } 65 | 66 | return 0; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /sem/sem10/pattern.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int i = 0; 4 | 5 | void* state1(); 6 | void* f(); 7 | 8 | void* state1() { 9 | i++; 10 | puts("Hello from state1"); 11 | if((i % 2) == 0) { 12 | return state1; 13 | } else { 14 | return f; 15 | } 16 | } 17 | 18 | 19 | 20 | void* f() { 21 | i++; 22 | puts("Hello from f"); 23 | if((i % 2) == 0) { 24 | return state1; 25 | } else { 26 | return f; 27 | } 28 | } 29 | 30 | 31 | int main() { 32 | void* (*fn)() = f; 33 | 34 | fn = fn(); 35 | fn = fn(); 36 | fn = fn(); 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /sem/sem11/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/sem/sem11/.DS_Store -------------------------------------------------------------------------------- /sem/sem11/fork_server.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define SERVER_MSG ("Hello User! Welcome to my server!\n") 11 | 12 | int main(int argc, char** argv) { 13 | 14 | int serversocket_fd = -1; 15 | int clientsocket_fd = -1; 16 | 17 | // > 1024 18 | int port = 9000; 19 | struct sockaddr_in address; 20 | int option = 1; 21 | 22 | char buffer[1024]; 23 | serversocket_fd = socket(AF_INET, SOCK_STREAM, 0); 24 | 25 | if(serversocket_fd < 0) { 26 | puts("This failed!"); 27 | exit(1); 28 | } 29 | 30 | address.sin_family = AF_INET; 31 | address.sin_addr.s_addr = INADDR_ANY; 32 | address.sin_port = htons(port); 33 | 34 | setsockopt(serversocket_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &option, sizeof(int)); 35 | 36 | if(bind(serversocket_fd, (struct sockaddr*) &address, sizeof(struct sockaddr_in))) { 37 | puts("This broke! :("); 38 | exit(1); 39 | } 40 | 41 | listen(serversocket_fd, 4); 42 | while(1) { 43 | uint32_t addrlen = sizeof(struct sockaddr_in); 44 | clientsocket_fd = accept(serversocket_fd, (struct sockaddr*) &address, &addrlen); 45 | pid_t p = fork(); 46 | 47 | if(p == 0) { 48 | read(clientsocket_fd, buffer, 1024); 49 | puts(buffer); 50 | write(clientsocket_fd, SERVER_MSG, strlen(SERVER_MSG)+1); 51 | 52 | close(clientsocket_fd); 53 | exit(1); 54 | } 55 | } 56 | close(serversocket_fd); 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /sem/sem11/thread_server.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define SERVER_MSG ("Hello User! Welcome to my server!") 12 | 13 | struct connection_data { 14 | int socketfd; 15 | char* msg; 16 | size_t msg_len; 17 | }; 18 | 19 | void* connection_handler(void* arg) { 20 | struct connection_data* data = (struct connection_data*) arg; 21 | char buffer[1024]; 22 | memset(buffer, 0, 1024); 23 | read(data->socketfd, buffer, 1024); 24 | write(data->socketfd, data->msg, data->msg_len); 25 | close(data->socketfd); 26 | free(data); 27 | return NULL; 28 | } 29 | 30 | int main(int argc, char** argv) { 31 | 32 | int serversocket_fd = -1; 33 | int clientsocket_fd = -1; 34 | 35 | // > 1024 36 | int port = 9000; 37 | struct sockaddr_in address; 38 | int option = 1; 39 | 40 | char buffer[1024]; 41 | serversocket_fd = socket(AF_INET, SOCK_STREAM, 0); 42 | 43 | if(serversocket_fd < 0) { 44 | puts("This failed!"); 45 | exit(1); 46 | } 47 | 48 | address.sin_family = AF_INET; 49 | address.sin_addr.s_addr = INADDR_ANY; 50 | address.sin_port = htons(port); 51 | 52 | setsockopt(serversocket_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &option, sizeof(int)); 53 | 54 | if(bind(serversocket_fd, (struct sockaddr*) &address, sizeof(struct sockaddr_in))) { 55 | puts("This broke! :("); 56 | exit(1); 57 | } 58 | 59 | listen(serversocket_fd, 4); 60 | while(1) { 61 | uint32_t addrlen = sizeof(struct sockaddr_in); 62 | clientsocket_fd = accept(serversocket_fd, (struct sockaddr*) &address, &addrlen); 63 | 64 | struct connection_data* d = malloc(sizeof(struct connection_data)); 65 | d->socketfd = clientsocket_fd; 66 | d->msg = SERVER_MSG; 67 | d->msg_len = strlen(SERVER_MSG)+1; 68 | pthread_t thread; 69 | pthread_create(&thread, NULL, connection_handler, d); 70 | 71 | } 72 | close(serversocket_fd); 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /sem/sem12/iterator.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "iterator.h" 4 | #include "linkedlist.h" 5 | 6 | void iter_traverse(struct iterator* iter, void(*fn)(void*)) { 7 | if(iter) { 8 | void* element = NULL; 9 | while((element = iter->next(iter)) != NULL) { 10 | //Do something here 11 | fn(element); 12 | } 13 | } 14 | } 15 | 16 | void print_int(void* data) { 17 | int* p = (int*) data; 18 | printf("%d\n", *p); 19 | } 20 | 21 | 22 | int main() { 23 | printf("%lu %lu\n", sizeof(struct ll_node), sizeof(struct iterator)); 24 | 25 | struct ll_node* head = NULL; 26 | for(int i = 0; i < 10; i++) { 27 | int* j = malloc(sizeof(int)); 28 | *j = i; 29 | ll_append(&head, j); 30 | } 31 | 32 | struct iterator iter = { .cursor = head, .next = ll_next }; 33 | iter_traverse(&iter, print_int); 34 | ll_destroy(&head); 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /sem/sem12/iterator.h: -------------------------------------------------------------------------------- 1 | #ifndef ITERATOR_H 2 | #define ITERATOR_H 3 | 4 | struct iterator { 5 | void* cursor; 6 | void* (*next)(void*); 7 | }; 8 | 9 | void iter_traverse(struct iterator* iter, void(*fn)(void*)); 10 | #endif 11 | -------------------------------------------------------------------------------- /sem/sem12/linkedlist.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "linkedlist.h" 4 | #include "iterator.h" 5 | 6 | void ll_append(struct ll_node** n, void* value) { 7 | if(n) { 8 | struct ll_node* p = malloc(sizeof(struct ll_node)); 9 | p->next = NULL; 10 | p->element = value; 11 | if(*n) { //Head has been assigned 12 | struct ll_node* cursor = *n; 13 | while(cursor->next != NULL) { 14 | cursor = cursor->next; 15 | } 16 | cursor->next = p; 17 | } else { 18 | *n = p; 19 | } 20 | } 21 | } 22 | 23 | void ll_destroy(struct ll_node** n) { 24 | if(n) { 25 | struct ll_node* cursor = *n; 26 | 27 | while(cursor != NULL) { 28 | struct ll_node* temp = cursor->next; 29 | free(cursor->element); 30 | free(cursor); 31 | cursor = temp; 32 | } 33 | 34 | } 35 | } 36 | 37 | void* ll_next(void* iter) { 38 | if(iter) { 39 | 40 | struct iterator* i = (struct iterator*) iter; 41 | void* v = NULL; 42 | if(i->cursor) { 43 | struct ll_node* n = (struct ll_node*) i->cursor; 44 | 45 | v = n->element; 46 | n = n->next; 47 | i->cursor = n; 48 | 49 | } 50 | return v; 51 | } else { 52 | return NULL; 53 | } 54 | } 55 | 56 | -------------------------------------------------------------------------------- /sem/sem12/linkedlist.h: -------------------------------------------------------------------------------- 1 | #ifndef LINKEDLIST_H 2 | #define LINKEDLIST_H 3 | 4 | #include 5 | #include 6 | 7 | 8 | struct ll_node { 9 | struct ll_node* next; 10 | void* element; 11 | }; 12 | 13 | void ll_append(struct ll_node** n, void* value); 14 | 15 | void ll_destroy(struct ll_node** n); 16 | 17 | void* ll_next(void* iter); 18 | #endif 19 | -------------------------------------------------------------------------------- /sem/sem2/appendStack.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // append string to another #ifndef 6 | char* append_stack(char* base, char* str){ 7 | // get the length of base 8 | int base_len = 0; 9 | char* cur = base; 10 | while(*cur){ 11 | base_len++; 12 | cur++; 13 | } 14 | 15 | // get the length of str 16 | int str_len = 0; 17 | cur = str; 18 | while(*cur){ 19 | str_len++; 20 | cur++; 21 | } 22 | 23 | char result = [base_len + str_len + 1]; 24 | for (int i = 0; i < base_len; i++) { 25 | result[i] = base[i]; 26 | } 27 | for (int i = 0; i < str_len; i++) { 28 | result[base_len + i] = str[i]; 29 | } 30 | 31 | return result; 32 | } 33 | 34 | int main(){ 35 | char array[50] = "Hello, "; 36 | 37 | // change the rest in rest to 1 38 | for (int i = strlen(array) + 1; i < 50; i++) { 39 | array[i] = 1; 40 | } 41 | 42 | char* result1 = append_stack(array, "World!"); 43 | char* result2 = append_stack(array, "123"); 44 | printf("%s\n", result1); // Hello, Wor123 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /sem/sem2/appendString.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // append string to another #ifndef 6 | void append_string(char* base, char* str){ 7 | // get the len of base 8 | int base_len = 0; 9 | char* cur = base; 10 | // iterate through the string 11 | // null terminator correspond to zero 12 | while(*cur){ 13 | base_len++; 14 | cur++; 15 | } 16 | 17 | // append str to base 18 | cur = str; 19 | int str_len = 0; 20 | while(*cur){ 21 | base[base_len + str_len] = *cur; 22 | str_len++; 23 | cur++; 24 | } 25 | // indicate where to terminate 26 | base[base_len + str_len] = '\0'; 27 | } 28 | 29 | int main(){ 30 | char array[50] = "Hello, "; 31 | 32 | // change the rest in rest to 1 33 | for (int i = strlen(array) + 1; i < 50; i++) { 34 | array[i] = 1; 35 | } 36 | // strlen not include null terminator 37 | printf("%lu\n", strlen(array)); // 7 38 | 39 | append_string(array, "World!"); 40 | printf("%s\n", array); // Hello, World! 41 | 42 | printf("%lu\n", strlen(array)); // 13 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /sem/sem2/average.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define ARRAY_LEN (5) 3 | 4 | // calculate the average of an int array 5 | float average(int* arr, unsigned int len){ 6 | float sum = 0; 7 | for(int i = 0; i < len; i++){ 8 | sum += arr[i]; 9 | } 10 | return sum / len; 11 | } 12 | 13 | int main(){ 14 | int arr[] = {1, 2, 3, 4, 50}; 15 | printf("%f\n", average(arr, ARRAY_LEN)); // 12 16 | printf("%f\n", average(arr, 4)); // 2.5 17 | printf("%f\n", average(arr+2, 2)); // 3.5 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /sem/sem2/compare.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // comapsre String to substring 4 | int compare_string(char* haystack, char* needle){ 5 | int haystack_len = 0; 6 | char* cur = haystack; 7 | while(*cur){ 8 | haystack_len++; 9 | cur++; 10 | } 11 | 12 | int needle_len = 0; 13 | cur = needle; 14 | while(*cur){ 15 | needle_len++; 16 | cur++; 17 | } 18 | 19 | // can not found it 20 | if(needle_len > haystack_len){ 21 | return -1; 22 | } 23 | 24 | int result = 0; 25 | for(int i = 0; i <= (haystack_len - needle_len); i++){ 26 | int match = 1; 27 | for(int j = 0; j < needle_len; j++){ 28 | if(haystack[i + j] != needle[j]){ 29 | match = 0; // 0 i ndicate false 30 | } 31 | } 32 | if(match == 1){ // 1 indicate true 33 | result = 1; 34 | break; 35 | } 36 | } 37 | return result; 38 | } 39 | 40 | 41 | int main(){ 42 | printf("%s %s %d\n", "Woman", "man", compare_string("Woman", "man")); 43 | printf("%s %s %d\n", "Woman", "mannnnnn", compare_string("Woman", "mannnnnn")); 44 | printf("%s %s %d\n", "Woman", "mj", compare_string("Woman", "mj")); 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /sem/sem3/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/sem/sem3/.DS_Store -------------------------------------------------------------------------------- /sem/sem3/flip.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void my_strcpy(void* dest, void* src, unsigned no_bytes) { 5 | int i = 0; // make sure we have terminator 6 | for (i = 0; i < no_bytes; i++) { 7 | char* d = dest; 8 | char* s = src; 9 | d[i] = s[i]; 10 | } 11 | // dest[i] = '\0'; 12 | // do not need terminator this time 13 | } 14 | 15 | int main() { 16 | char buf[50]; 17 | int array[10]; 18 | int garbage[] = { 1, 2, 3, 4, 5, 6 }; 19 | 20 | my_strcpy(buf, "Hello World", 12); 21 | printf("%s\n", buf); 22 | 23 | my_strcpy(array, garbage, sizeof(garbage)); 24 | for (int i = 0; i < 10; i++) { 25 | printf("%d ", array[i]); 26 | } 27 | puts(""); 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /sem/sem4/crc32.c: -------------------------------------------------------------------------------- 1 | /* 2 | NOT MY OWN WORK 3 | 4 | From: https://rosettacode.org/wiki/CRC-32#C 5 | 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | uint32_t crc32(uint32_t crc, const char *buf, size_t len) 13 | { 14 | static uint32_t table[256]; 15 | static int have_table = 0; 16 | uint32_t rem; 17 | uint8_t octet; 18 | int i, j; 19 | const char *p, *q; 20 | 21 | /* This check is not thread safe; there is no mutex. */ 22 | if (have_table == 0) { 23 | /* Calculate CRC table. */ 24 | for (i = 0; i < 256; i++) { 25 | rem = i; /* remainder from polynomial division */ 26 | for (j = 0; j < 8; j++) { 27 | if (rem & 1) { 28 | rem >>= 1; 29 | rem ^= 0xedb88320; 30 | } else 31 | rem >>= 1; 32 | } 33 | table[i] = rem; 34 | } 35 | have_table = 1; 36 | } 37 | 38 | crc = ~crc; 39 | q = buf + len; 40 | for (p = buf; p < q; p++) { 41 | octet = *p; /* Cast to unsigned octet. */ 42 | crc = (crc >> 8) ^ table[(crc & 0xff) ^ octet]; 43 | } 44 | return ~crc; 45 | } 46 | -------------------------------------------------------------------------------- /sem/sem4/ex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/sem/sem4/ex -------------------------------------------------------------------------------- /sem/sem4/example1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | size_t i = -1; 6 | 7 | printf("%lu", i); 8 | } 9 | -------------------------------------------------------------------------------- /sem/sem4/firmware.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | /* 8 | We want to firstly create a method to generate firmware files 9 | even if the data is garbage 10 | 11 | magic: 4bytes, unsigned integer 12 | timestamp: 4bytes, integer 13 | author: 4bytes, char array 14 | crc: 4bytes, unsigned integer. 15 | */ 16 | 17 | 18 | extern uint32_t crc32(uint32_t crc, const char* buf, size_t len); 19 | 20 | struct firmware_header { 21 | unsigned int magic; 22 | int timestamp; 23 | char author[4]; 24 | unsigned int crc; 25 | }; 26 | 27 | #define N_PARTITIONS (12) 28 | #define FIRMWARE_MAGIC (60232) 29 | 30 | 31 | int main(int argc, char** argv) { 32 | 33 | if(argc > 1) { 34 | 35 | struct firmware_header header; 36 | FILE* file = fopen(argv[1], "w"); 37 | int array[64*N_PARTITIONS]; 38 | 39 | srand(time(NULL)); 40 | 41 | for(int i = 0; i < 64*N_PARTITIONS; i++) { 42 | array[i] = rand(); 43 | } 44 | 45 | unsigned int crcval = crc32(0, (char*) array, (64*N_PARTITIONS)*sizeof(int)); 46 | 47 | header.magic = FIRMWARE_MAGIC; 48 | header.timestamp = time(NULL); 49 | strcpy(header.author, "JSH"); 50 | header.crc = crcval; 51 | 52 | 53 | fwrite(&header, sizeof(struct firmware_header), 1, file); 54 | fwrite(array, sizeof(int), (64*N_PARTITIONS), file); 55 | 56 | fclose(file); 57 | 58 | } 59 | } 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /sem/sem4/firmware_maker: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/sem/sem4/firmware_maker -------------------------------------------------------------------------------- /sem/sem4/firmware_reader: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/sem/sem4/firmware_reader -------------------------------------------------------------------------------- /sem/sem4/firmware_reader.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | /* 8 | We want to firstly create a method to generate firmware files 9 | even if the data is garbage 10 | 11 | magic: 4bytes, unsigned integer 12 | timestamp: 4bytes, integer 13 | author: 4bytes, char array 14 | crc: 4bytes, unsigned integer. 15 | */ 16 | 17 | 18 | extern uint32_t crc32(uint32_t crc, const char* buf, size_t len); 19 | 20 | struct firmware_header { 21 | unsigned int magic; 22 | int timestamp; 23 | char author[4]; 24 | unsigned int crc; 25 | }; 26 | 27 | #define N_PARTITIONS (12) 28 | #define FIRMWARE_MAGIC (60232) 29 | 30 | 31 | int main(int argc, char** argv) { 32 | 33 | if(argc > 1) { 34 | 35 | struct firmware_header header; 36 | FILE* file = fopen(argv[1], "r"); 37 | int array[64*N_PARTITIONS]; 38 | 39 | fread(&header, sizeof(struct firmware_header), 1, file); 40 | fread(array, sizeof(int), 64*N_PARTITIONS, file); 41 | 42 | unsigned int crcval = crc32(0, (char*) array, (64*N_PARTITIONS)*sizeof(int)); 43 | 44 | printf("EXPECTED MAGIC: %u\n", FIRMWARE_MAGIC); 45 | printf("EXPECTED CRC: %u\n", header.crc); 46 | printf("TIMESTAMP: %u\n", header.timestamp); 47 | printf("AUTHOR: %s\n", header.author); 48 | 49 | printf("COMPUTED CRC_VALUE: %u\n", crcval); 50 | printf("EXTRACTED MAGIC: %u\n", header.magic); 51 | 52 | 53 | fclose(file); 54 | 55 | 56 | } 57 | } 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /sem/sem4/greader: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/sem/sem4/greader -------------------------------------------------------------------------------- /sem/sem4/greader.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | typedef struct { 7 | unsigned int id:8; 8 | unsigned int locked:8; 9 | unsigned int x:1; 10 | unsigned int y:1; 11 | unsigned int z:1; 12 | unsigned int w:1; 13 | unsigned int a:1; 14 | unsigned int b:1; 15 | unsigned int c:1; 16 | unsigned int d:1; 17 | unsigned int l:1; 18 | unsigned int r:1; 19 | unsigned int st:1; 20 | unsigned int sel:1; 21 | } gamepad_data; 22 | 23 | 24 | void print_components(gamepad_data* data) { 25 | printf("%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u\n", 26 | data->id, data->locked, data->x, data->y, data->y, data->z, data->w, 27 | data->a, data->b, data->c, data->d, data->l, data->r, data->st, data->sel); 28 | 29 | 30 | } 31 | 32 | 33 | /* 34 | * 35 | */ 36 | int main(int argc, char** argv) { 37 | srand(time(NULL)); 38 | FILE* f = fopen(argv[1], "r"); 39 | int n_pkts = strtol(argv[2], NULL, 10); 40 | gamepad_data data; 41 | if(f != NULL) { 42 | for(int i = 0; i < n_pkts; i++) { 43 | fread(&data, sizeof(gamepad_data), 1, f); 44 | print_components(&data); 45 | } 46 | } 47 | fclose(f); 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /sem/sem4/test1.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/sem/sem4/test1.bin -------------------------------------------------------------------------------- /sem/sem4/test2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/sem/sem4/test2.bin -------------------------------------------------------------------------------- /sem/sem4/test3.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/sem/sem4/test3.bin -------------------------------------------------------------------------------- /sem/sem4/test4.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/sem/sem4/test4.bin -------------------------------------------------------------------------------- /sem/sem4/test5.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/sem/sem4/test5.bin -------------------------------------------------------------------------------- /sem/sem4/test6.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/sem/sem4/test6.bin -------------------------------------------------------------------------------- /sem/sem5/jaggy.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* 5 | 6 | We will be building a jagged array, this will 7 | be used to look into how dynamic memory works with 8 | nested pointers 9 | 10 | 11 | */ 12 | 13 | int main() { 14 | //Number of rows 15 | int lens[] = { 2, 4, 6, 10 }; 16 | int** rows = malloc(sizeof(int*)*4); 17 | 18 | //Prints out the pointers 19 | for(int i = 0; i < 4; i++) { 20 | printf("%p\n", rows+i); 21 | } 22 | 23 | rows[0] = malloc(sizeof(int)*lens[0]); 24 | rows[1] = malloc(sizeof(int)*lens[1]); 25 | rows[2] = malloc(sizeof(int)*lens[2]); 26 | rows[3] = malloc(sizeof(int)*lens[3]); 27 | 28 | puts("Printing each malloc'd object"); 29 | 30 | for(int i = 0; i < 4; i++) { 31 | for(int j = 0; j < lens[i]; j++) { 32 | *((*(rows+i))+j) = j+1; 33 | } 34 | } 35 | 36 | 37 | for(int i = 0; i < 4; i++) { 38 | for(int j = 0; j < lens[i]; j++) { 39 | printf("%d ", rows[i][j]); 40 | } 41 | puts(""); 42 | } 43 | 44 | 45 | 46 | //Not freeing the memory yet! 47 | 48 | 49 | for(int i = 0; i < 4; i++) { 50 | free(rows[i]); 51 | } 52 | free(rows); 53 | } 54 | -------------------------------------------------------------------------------- /sem/sem6/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/sem/sem6/.DS_Store -------------------------------------------------------------------------------- /sem/sem6/MYSTDERR: -------------------------------------------------------------------------------- 1 | Hello from stderr file!This is another line from me! -------------------------------------------------------------------------------- /sem/sem6/my_text.txt: -------------------------------------------------------------------------------- 1 | We are now using the FILE* type now with more fputs!! 2 | -------------------------------------------------------------------------------- /sem/sem6/q1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | int fd = open("./my_text.txt", O_CREAT | O_WRONLY | O_TRUNC); 6 | char str[] = "This is new text!"; 7 | write(fd, str, sizeof(str)); 8 | 9 | 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /sem/sem6/q2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() { 6 | /* 7 | 0 - stdin 8 | 1 - stdout 9 | 2 - stderr 10 | ... rest newly opened files 11 | 3 - my_text.txt 12 | 13 | 14 | */ 15 | 16 | 17 | int fd = open("./my_text.txt", O_CREAT | O_WRONLY | O_TRUNC); 18 | FILE* file = fdopen(fd, "w"); 19 | char str[] = "We are now using the FILE* type now with more fputs!!\n"; 20 | fputs(str, file); 21 | 22 | fclose(file); 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /sem/sem6/q3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | 7 | int main() { 8 | 9 | /* 10 | e.g. a read only file 11 | 1 0 1 1 12 | Create Write Read Execute 13 | */ 14 | l 15 | int fd = open("MYSTDERR", O_CREAT | O_WRONLY); 16 | close(STDERR_FILENO); 17 | 18 | dup(fd); 19 | 20 | char str[40] = "Hello from stderr file!"; 21 | write(STDERR_FILENO, str, sizeof(str)); 22 | 23 | fprintf(stderr, "This is another line from me!"); 24 | close(fd); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /sem/sem6/q4.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | int str_cmp(const void* a, const void* b) { 7 | return strcmp(a, b); 8 | } 9 | 10 | 11 | int main() { 12 | 13 | char strs[5][20] = { 14 | "Jeff", 15 | "John", 16 | "Corona", 17 | "Tyson", 18 | "Scomo" 19 | }; 20 | 21 | // qsort(strs, 5, 20, str_cmp); 22 | 23 | /*for(int i = 0; i < 5; i++) { 24 | puts(strs[i]); 25 | }*/ 26 | 27 | char* s = bsearch("Scomo", strs, 5, 20, str_cmp); 28 | 29 | puts(s); 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /sem/sem6/q5.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int finished = 0; 6 | 7 | void int_handler(int signo) { 8 | puts("INT Handler"); 9 | finished = 1; 10 | printf("%d\n", signo); 11 | } 12 | 13 | 14 | 15 | 16 | int main() { 17 | signal(SIGINT, int_handler); 18 | signal(SIGHUP, int_handler); 19 | signal(SIGUSR1, int_handler); 20 | while(!finished) { 21 | } 22 | 23 | puts("We are finishing up!"); 24 | } 25 | -------------------------------------------------------------------------------- /sem/sem6/q6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | int f(int x, int y) { 6 | return x + y; 7 | } 8 | 9 | 10 | void g(int y) { 11 | 12 | } 13 | 14 | 15 | int main() { 16 | int (*fn)(int, int) = f; 17 | 18 | int res = fn(1, 5); 19 | printf("%d\n", res); 20 | fn = g; 21 | 22 | res = fn(5, 6); 23 | 24 | printf("%d\n", res); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /sem/sem6/script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Hello World!" 4 | -------------------------------------------------------------------------------- /sem/sem7/tree.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_H 2 | #define TREE_H 3 | 4 | #include 5 | 6 | struct bintree_entry { 7 | void* key; 8 | void* element; 9 | }; 10 | 11 | struct bintree_node { 12 | struct bintree_node* left; 13 | struct bintree_node* right; 14 | struct bintree_entry entry; 15 | }; 16 | 17 | struct bintree { 18 | struct bintree_node* root; 19 | int (*cmp)(void*, void*); 20 | size_t n_elements; 21 | }; 22 | 23 | 24 | struct bintree* bintree_new(int (*cmp)(void*, void*)); 25 | 26 | void bintree_put_copy(struct bintree* bin, void* key, size_t ksz, void* value, size_t value_sz); 27 | 28 | void bintree_traversal(struct bintree* tree, void (*printer)(void*)); 29 | void bintree_destroy(struct bintree* tree); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /sem/sem7/tree_program.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "tree.h" 6 | 7 | int icompare(void* a, void* b) { 8 | int* x = (int*) a; 9 | int* y = (int*) b; 10 | 11 | return a - b; 12 | } 13 | 14 | void test_init(void** state) { 15 | 16 | struct bintree* t = bintree_new(icompare); 17 | assert_non_null(t); 18 | 19 | free(t); 20 | 21 | } 22 | 23 | 24 | void print_obj(void* obj) { 25 | char* i = (char*) obj; 26 | fprintf(stderr, "%s\n", i); 27 | } 28 | 29 | void test_tree_place_afew(void** state) { 30 | struct bintree* t = bintree_new(icompare); 31 | 32 | int numbers[] = { 10, 5, 15, 2, 7, 14, 19, 8 }; 33 | char strs[8][8] = { 34 | "A", "B", "C", "D", "E", "F", "G", "Jeff" 35 | }; 36 | 37 | for(int i = 0; i < 8; i++) { 38 | bintree_put_copy(t, numbers+i, sizeof(int), strs+i, 8); 39 | } 40 | bintree_traversal(t, print_obj); 41 | bintree_destroy(t); 42 | } 43 | 44 | 45 | int main() { 46 | 47 | struct CMUnitTest tests[] = { 48 | cmocka_unit_test(test_init), 49 | cmocka_unit_test(test_tree_place_afew) 50 | }; 51 | 52 | 53 | 54 | cmocka_run_group_tests(tests, NULL, NULL); 55 | 56 | test_tree_place_afew(NULL); 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /sem/sem8/myprocess.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | int main() { 8 | 9 | //fork() -> check if parent, then fork() again 10 | // 1 -> Parent 11 | // 1 -> 2 12 | // 1 -> 3 13 | 14 | //fork() -> not check 15 | // 16 | // pid_t p = fork(); 17 | // p = fork(); 18 | // 19 | // 1 -> 2 20 | // 1 -> 3 21 | // 2 -> 4 22 | // 23 | 24 | puts("Before forking!"); 25 | fflush(stdout); 26 | pid_t pid = fork(); 27 | pid_t current_pid = getpid(); 28 | if(pid < 0) { 29 | fprintf(stderr, "Unable to fork!"); 30 | return 0; 31 | } else if (pid == 0) { 32 | //This is the child 33 | sleep(7); 34 | puts("I am the child!"); 35 | printf("%d %d\n", pid, current_pid); 36 | } else { 37 | sleep(5); 38 | puts("I am the parent!"); 39 | printf("%d %d\n", pid, current_pid); 40 | } 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /sem/sem8/mystdout.txt: -------------------------------------------------------------------------------- 1 | Hello World! 2 | -------------------------------------------------------------------------------- /sem/sem8/redirect.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | int main() { 9 | 10 | int fd = open("mystdout.txt", O_CREAT | O_RDWR | O_TRUNC); 11 | 12 | close(STDOUT_FILENO); 13 | dup(fd); 14 | char* args[] = { 15 | "echo", 16 | "Hello World!", 17 | NULL 18 | }; 19 | 20 | pid_t pid = fork(); 21 | 22 | 23 | if(pid == 0) { 24 | if(execv("/usr/bin/echo", args) == -1) { 25 | fprintf(stderr, "exec failed!"); 26 | } 27 | } else if(pid > 0) { 28 | wait(NULL); 29 | char buf[100]; 30 | FILE* f = fdopen(fd, "rw"); 31 | 32 | fseek(fd, 0, SEEK_SET); 33 | ssize_t bytes = read(fd, buf, 100); 34 | fprintf(stderr, "%ld\n", bytes); 35 | 36 | fprintf(stderr, "%s\n", buf); 37 | 38 | fclose(f); 39 | } 40 | 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /sem/sem8/stdout.txt: -------------------------------------------------------------------------------- 1 | Before forking! 2 | I am the parent! 3 | 4533 4532 4 | I am the child! 5 | 0 4533 6 | -------------------------------------------------------------------------------- /sem/sem9/mypipe.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int main() { 11 | 12 | int channel[2]; 13 | pipe(channel); //channel[0] = read, channel[1] = write 14 | 15 | pid_t pid = getpid(); 16 | 17 | for(int i = 0; i < 8; i++) { 18 | 19 | pid = fork(); 20 | if(pid == 0) { 21 | break; 22 | } 23 | } 24 | 25 | if(pid == 0) { 26 | char buf[64]; 27 | snprintf(buf, 64, "Hello From %d\n", getpid()); 28 | write(channel[1], buf, 64); 29 | close(channel[1]); 30 | close(channel[0]); 31 | } else if(pid > 0) { 32 | close(channel[1]); 33 | char buf[64]; 34 | while(1) { 35 | if(read(channel[0], buf, 64) == -1) { 36 | break; 37 | } 38 | if(errno > 0) { 39 | break; 40 | } 41 | printf("%s", buf); 42 | wait(NULL); 43 | } 44 | 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /sem/sem9/shared.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define PG_SIZE (4096) 11 | 12 | int main() { 13 | int fd = shm_open("/myshare", O_RDWR | O_CREAT, 0777); 14 | ftruncate(fd, 4096); 15 | char buf[64] = "Hello from child!"; 16 | char* shared = mmap(NULL, PG_SIZE, PROT_READ | PROT_WRITE, 17 | MAP_SHARED, fd, 0); 18 | pid_t pid = fork(); 19 | 20 | if(pid == 0) { 21 | strcpy(shared, buf); 22 | munmap(shared, PG_SIZE); 23 | 24 | shared = mmap(NULL, PG_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, 25 | fd, 0); 26 | sleep(4); 27 | fputs(shared, stdout); 28 | munmap(shared, PG_SIZE); 29 | 30 | } else if(pid > 0) { 31 | sleep(2); 32 | fputs(shared, stdout); 33 | strcat(shared+strlen(shared), "Another line!\n"); 34 | munmap(shared, PG_SIZE); 35 | shm_unlink("/myshare"); 36 | } 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /tut/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/.DS_Store -------------------------------------------------------------------------------- /tut/Week 10 - Parallelism with POSIX threads and Optimisations.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/Week 10 - Parallelism with POSIX threads and Optimisations.pdf -------------------------------------------------------------------------------- /tut/Week 11 - Synchronisation and Atomics.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/Week 11 - Synchronisation and Atomics.pdf -------------------------------------------------------------------------------- /tut/Week 12 - Recursion and Aliasing.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/Week 12 - Recursion and Aliasing.pdf -------------------------------------------------------------------------------- /tut/Week 13 - Revision.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/Week 13 - Revision.pdf -------------------------------------------------------------------------------- /tut/Week 2 - Introduction To C.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/Week 2 - Introduction To C.pdf -------------------------------------------------------------------------------- /tut/Week 3 - Addressable Memory and Standard Library Functions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/Week 3 - Addressable Memory and Standard Library Functions.pdf -------------------------------------------------------------------------------- /tut/Week 4 - Structs, Unions, Bitfields and Files.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/Week 4 - Structs, Unions, Bitfields and Files.pdf -------------------------------------------------------------------------------- /tut/Week 5 - Dynamic Memory.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/Week 5 - Dynamic Memory.pdf -------------------------------------------------------------------------------- /tut/Week 6 - File IO, Function Pointers and Signals.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/Week 6 - File IO, Function Pointers and Signals.pdf -------------------------------------------------------------------------------- /tut/Week 7 - Compiler pipeline, Signals, Makefile and Shared library.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/Week 7 - Compiler pipeline, Signals, Makefile and Shared library.pdf -------------------------------------------------------------------------------- /tut/Week 8 - Introduction To Processes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/Week 8 - Introduction To Processes.pdf -------------------------------------------------------------------------------- /tut/Week 9 - IPC, Shared Memory and Pipes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/Week 9 - IPC, Shared Memory and Pipes.pdf -------------------------------------------------------------------------------- /tut/tut10/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/tut10/.DS_Store -------------------------------------------------------------------------------- /tut/tut10/false-sharing-correct.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define MAX_SIZE 100000000 5 | 6 | typedef struct { 7 | int first; 8 | int last; 9 | int result; 10 | } MY_ARGS; 11 | 12 | int* arr; 13 | int results[2]; 14 | 15 | void* myfunc(void* args) { 16 | int i; 17 | MY_ARGS* my_args = (MY_ARGS*) args; 18 | int first = my_args->first; 19 | int last = my_args->last; 20 | int s = 0; 21 | for (i = first; i < last; i++) { 22 | s += arr[i]; 23 | } 24 | my_args->result = s; 25 | return NULL; 26 | } 27 | 28 | int main() { 29 | int i = 0; 30 | arr = malloc(sizeof(int) * MAX_SIZE); 31 | for (int i = 0; i < MAX_SIZE; i++) { 32 | arr[i] = rand() % 5; 33 | } 34 | results[0] = 0; 35 | results[1] = 0; 36 | 37 | pthread_t th1; 38 | pthread_t th2; 39 | 40 | int mid = MAX_SIZE / 2; 41 | MY_ARGS args1 = {0, mid, 0}; 42 | MY_ARGS args2 = {mid, MAX_SIZE, 0}; 43 | 44 | pthread_create(&th1, NULL, myfunc, &args1); 45 | pthread_create(&th2, NULL, myfunc, &args2); 46 | 47 | pthread_join(th1, NULL); 48 | pthread_join(th2, NULL); 49 | 50 | int s1 = args1.result; 51 | int s2 = args2.result; 52 | 53 | printf("s1 = %d\n", s1); 54 | printf("s2 = %d\n", s2); 55 | printf("s1 + s2 = %d\n", s1 + s2); 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /tut/tut10/false-sharing-false.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define MAX_SIZE 100000000 5 | 6 | typedef struct { 7 | int first; 8 | int last; 9 | int id; 10 | } MY_ARGS; 11 | 12 | int* arr; 13 | int results[2]; 14 | 15 | void* myfunc(void* args) { 16 | int i; 17 | MY_ARGS* my_args = (MY_ARGS*) args; 18 | int first = my_args->first; 19 | int last = my_args->last; 20 | int id = my_args->id;; 21 | 22 | for (i = first; i < last; i++) { 23 | results[id] = results[id] + arr[i]; 24 | } 25 | 26 | return NULL; 27 | } 28 | 29 | int main() { 30 | int i = 0; 31 | arr = malloc(sizeof(int) * MAX_SIZE); 32 | for (int i = 0; i < MAX_SIZE; i++) { 33 | arr[i] = rand() % 5; 34 | } 35 | results[0] = 0; 36 | results[1] = 0; 37 | 38 | pthread_t th1; 39 | pthread_t th2; 40 | 41 | int mid = MAX_SIZE / 2; 42 | MY_ARGS args1 = {0, mid, 0}; 43 | MY_ARGS args2 = {mid, MAX_SIZE, 1}; 44 | 45 | pthread_create(&th1, NULL, myfunc, &args1); 46 | pthread_create(&th2, NULL, myfunc, &args2); 47 | 48 | pthread_join(th1, NULL); 49 | pthread_join(th2, NULL); 50 | 51 | printf("s1 = %d\n", results[0]); 52 | printf("s2 = %d\n", results[1]); 53 | printf("s1 + s2 = %d\n", results[0] + results[1]); 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /tut/tut10/q1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define NTHREADS 4 5 | 6 | void* worker(void * arg) { 7 | const int argument = *((int * ) arg); 8 | printf("Hello from thread %d\n", argument); 9 | return NULL; 10 | } 11 | 12 | int main(void) { 13 | int args[NTHREADS] = { 1, 2, 3, 4 }; 14 | pthread_t thread_ids[NTHREADS]; 15 | 16 | // Create threads with given worker function and argument 17 | for (size_t i = 0; i < NTHREADS; i++) { 18 | if (pthread_create(thread_ids + i, NULL, worker, args + i) != 0) { 19 | perror("unable to create thread"); 20 | return 1; 21 | } 22 | } 23 | 24 | // Wait for all threads to finish 25 | for (size_t i = 0; i < NTHREADS; i++) { 26 | if (pthread_join(thread_ids[i], NULL) != 0) { 27 | perror("unable to join thread"); 28 | return 1; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /tut/tut10/q2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define LENGTH 100000000 6 | #define NTHREADS 4 7 | #define NREPEATS 10 8 | #define CHUNK (LENGTH / NTHREADS) 9 | 10 | typedef struct { 11 | size_t id; 12 | long* array; 13 | long result; 14 | } worker_args; 15 | 16 | void* worker(void* args) { 17 | 18 | worker_args* wargs = (worker_args*) args; 19 | 20 | const size_t start = wargs->id * CHUNK; 21 | const size_t end = wargs->id == NTHREADS - 1 ? LENGTH : (wargs->id + 1) * CHUNK; 22 | 23 | // Use local stack variable to prevent false sharing 24 | long sum = 0; 25 | 26 | // Sum values from start to end 27 | for (size_t i = start; i < end; i++) { 28 | sum += wargs->array[i]; 29 | } 30 | 31 | wargs->result = sum; 32 | return NULL; 33 | } 34 | 35 | int main(void) { 36 | 37 | long* numbers = malloc(sizeof(long) * LENGTH); 38 | for (size_t i = 0; i < LENGTH; i++) { 39 | numbers[i] = i + 1; 40 | } 41 | 42 | worker_args* args = malloc(sizeof(worker_args) * NTHREADS); 43 | for (size_t n = 1; n <= NREPEATS; n++) { 44 | for (size_t i = 0; i < NTHREADS; i++) { 45 | args[i] = (worker_args) { 46 | .id = i, 47 | .array = numbers, 48 | .result = 0, 49 | }; 50 | } 51 | 52 | pthread_t thread_ids[NTHREADS]; 53 | 54 | // Launch threads 55 | for (size_t i = 0; i < NTHREADS; i++) { 56 | pthread_create(thread_ids + i, NULL, worker, args + i); 57 | } 58 | 59 | // Wait for threads to finish 60 | for (size_t i = 0; i < NTHREADS; i++) { 61 | pthread_join(thread_ids[i], NULL); 62 | } 63 | 64 | long sum = 0; 65 | 66 | // Calculate total sum 67 | for (size_t i = 0; i < NTHREADS; i++) { 68 | sum += args[i].result; 69 | } 70 | 71 | printf("Run %2zu: total sum is %ld\n", n, sum); 72 | } 73 | 74 | free(args); 75 | free(numbers); 76 | } 77 | -------------------------------------------------------------------------------- /tut/tut10/q3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) { 5 | const clock_t tick = clock(); 6 | 7 | int ops = 0; 8 | for (int i = 0; i < 100000000; i++) { 9 | ops += i; 10 | } 11 | 12 | const clock_t tock = clock(); 13 | printf("Time elapsed: %fs\n", (double) (tock - tick) / CLOCKS_PER_SEC); 14 | return 0; 15 | } -------------------------------------------------------------------------------- /tut/tut10/q5.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define THREADS 4 5 | #define LOOPS 10000000 6 | 7 | static unsigned counter = 0; 8 | static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 9 | 10 | static void* worker(void* arg) { 11 | for (unsigned i = 0; i < LOOPS; i++) { 12 | // attemp to lock the mutex 13 | // thread will wait when mutex is already locked 14 | pthread_mutex_lock(&mutex); 15 | // only one thread will be able execute this code 16 | counter++; 17 | // unlock the mutex after the critical section 18 | // pthread_mutex_unlock(&mutex); 19 | } 20 | return NULL; 21 | } 22 | 23 | int main(void) { 24 | pthread_t thread_ids[THREADS]; 25 | 26 | for (size_t i = 0; i < THREADS; i++) { 27 | pthread_create(&thread_ids[i], NULL, worker, NULL); 28 | } 29 | 30 | for (size_t i = 0; i < THREADS; i++) { 31 | pthread_join(thread_ids[i], NULL); 32 | } 33 | 34 | printf("%d\n", counter); 35 | } -------------------------------------------------------------------------------- /tut/tut11/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/tut11/.DS_Store -------------------------------------------------------------------------------- /tut/tut11/q3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define THINKERS 5 8 | 9 | static pthread_mutex_t chopsticks[THINKERS]; 10 | 11 | void* dine(void* arg) { 12 | const unsigned id = *((unsigned * ) arg); 13 | while (true) { 14 | // the ith philosopher can only reach the ith and (i + 1)th chopstick 15 | if (id < ((id+1) % THINKERS)) { 16 | pthread_mutex_lock(&chopsticks[id]); 17 | pthread_mutex_lock(&chopsticks[(id + 1) % THINKERS]); 18 | } else { 19 | pthread_mutex_lock(&chopsticks[(id + 1) % THINKERS]); 20 | pthread_mutex_lock(&chopsticks[id]); 21 | } 22 | 23 | printf("Philosopher %u is eating\n", id); 24 | usleep(500000); 25 | pthread_mutex_unlock(&chopsticks[id]); 26 | pthread_mutex_unlock(&chopsticks[(id + 1) % THINKERS]); 27 | } 28 | return NULL; 29 | } 30 | 31 | int main(void) { 32 | unsigned args[THINKERS]; pthread_t thinkers[THINKERS]; 33 | 34 | // create the chopsticks 35 | for (size_t i = 0; i < THINKERS; i++) { 36 | if (pthread_mutex_init(chopsticks + i, NULL) != 0) { 37 | perror("unable to initialize mutex"); 38 | return 1; 39 | } 40 | } 41 | 42 | // launch threads 43 | for (size_t i = 0; i < THINKERS; i++) { 44 | args[i] = i; 45 | if (pthread_create(thinkers + i, NULL, dine, args + i) != 0) { 46 | perror("unable to create thread"); return 1; 47 | } 48 | } 49 | 50 | // wait for threads to finish 51 | for (size_t i = 0; i < THINKERS; i++) { 52 | if (pthread_join(thinkers[i], NULL) != 0) { 53 | perror("unable to join thread"); 54 | return 1; 55 | } 56 | } 57 | 58 | // remove the chopsticks 59 | for (size_t i = 0; i < THINKERS; i++) { 60 | if (pthread_mutex_destroy(chopsticks + i) != 0) { 61 | perror("unable to destroy mutex"); 62 | return 1; 63 | } 64 | } 65 | 66 | return 0; 67 | } -------------------------------------------------------------------------------- /tut/tut11/q4.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define NTHREADS 5 8 | 9 | sem_t table; 10 | 11 | void* dine(void* arg) { 12 | 13 | const unsigned id = *(unsigned *) arg; 14 | 15 | for (size_t i = 0; i < 100; i++) { 16 | sem_wait(&table); 17 | printf("Philosopher %u is eating\n", id); 18 | sem_post(&table); 19 | } 20 | 21 | return NULL; 22 | } 23 | 24 | int main(void) { 25 | 26 | unsigned args[NTHREADS]; 27 | pthread_t thinkers[NTHREADS]; 28 | 29 | sem_init(&table, 0, NTHREADS / 2); 30 | 31 | for (size_t i = 0; i < NTHREADS; ++i) { 32 | args[i] = i; 33 | pthread_create(thinkers + i, NULL, dine, args + i); 34 | } 35 | 36 | for (size_t i = 0; i < NTHREADS; ++i) { 37 | pthread_join(thinkers[i], NULL); 38 | } 39 | 40 | sem_destroy(&table); 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /tut/tut11/q5_sem.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define EXCHANGES 10 7 | 8 | static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 9 | static sem_t alice_box; 10 | static sem_t bob_box; 11 | 12 | // uses semaphores so we don't lose signals 13 | 14 | void* alice(void* arg) { 15 | 16 | for (size_t i = 0; i < EXCHANGES; ++i) { 17 | puts("Alice: Waiting for Bob to signal"); 18 | 19 | // Wait for mail 20 | sem_wait(&alice_box); 21 | pthread_mutex_lock(&mutex); 22 | 23 | puts("Alice: Got Bob's signal"); 24 | printf("Alice: Got mail (%zu) from Bob\n", i); 25 | 26 | // Send mail to Bob 27 | sem_post(&bob_box); 28 | pthread_mutex_unlock(&mutex); 29 | } 30 | 31 | return NULL; 32 | } 33 | 34 | void* bob(void* arg) { 35 | 36 | for (size_t i = 0; i < EXCHANGES; ++i) { 37 | puts("Bob: Waiting for Alice to signal"); 38 | 39 | // Wait for mail 40 | sem_wait(&bob_box); 41 | pthread_mutex_lock(&mutex); 42 | 43 | puts("Bob: Got Alice's signal"); 44 | printf("Bob: Got mail (%zu) from Alice\n", i); 45 | 46 | // Send mail to Alice 47 | sem_post(&alice_box); 48 | pthread_mutex_unlock(&mutex); 49 | } 50 | 51 | return NULL; 52 | } 53 | 54 | int main(void) { 55 | 56 | sem_init(&alice_box, 0, 1); 57 | sem_init(&bob_box, 0, 1); 58 | 59 | pthread_t alice_tid; 60 | pthread_t bob_tid; 61 | 62 | pthread_create(&alice_tid, NULL, alice, NULL); 63 | pthread_create(&bob_tid, NULL, bob, NULL); 64 | 65 | pthread_join(alice_tid, NULL); 66 | pthread_join(bob_tid, NULL); 67 | 68 | sem_destroy(&alice_box); 69 | sem_destroy(&bob_box); 70 | 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /tut/tut11/q5_unsolved.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define EXCHANGES 10 6 | 7 | bool alice_has_mail = false; 8 | bool bob_has_mail = false; 9 | 10 | pthread_mutex_t alice_mutex = PTHREAD_MUTEX_INITIALIZER; 11 | pthread_cond_t alice_signal = PTHREAD_COND_INITIALIZER; 12 | 13 | pthread_mutex_t bob_mutex = PTHREAD_MUTEX_INITIALIZER; 14 | pthread_cond_t bob_signal = PTHREAD_COND_INITIALIZER; 15 | 16 | void* alice(void* arg) { 17 | for(unsigned i = 0; i < EXCHANGES; ++i) { 18 | pthread_mutex_lock(&alice_mutex); 19 | while (!alice_has_mail) { 20 | puts("Alice: Waiting for Bob to signal"); 21 | pthread_cond_wait(&alice_signal, &alice_mutex); 22 | puts("Alice: Got Bob's signal"); 23 | } 24 | pthread_mutex_unlock(&alice_mutex); 25 | 26 | alice_has_mail = false; 27 | bob_has_mail = true; 28 | 29 | pthread_cond_signal(&bob_signal); 30 | printf("Alice: Got mail (%d) from Bob\n", i); 31 | } 32 | return NULL; 33 | } 34 | 35 | void* bob(void* arg) { 36 | for(unsigned i = 0; i < EXCHANGES; ++i) { 37 | pthread_mutex_lock(&bob_mutex); 38 | while (!bob_has_mail) { 39 | puts("Bob: Waiting for Alice to signal"); 40 | pthread_cond_wait(&bob_signal, &bob_mutex); 41 | puts("Bob: Got Alice's signal"); 42 | } 43 | pthread_mutex_unlock(&bob_mutex); 44 | 45 | alice_has_mail = true; 46 | bob_has_mail = false; 47 | 48 | pthread_cond_signal(&alice_signal); 49 | printf("Bob: Got mail (%d) from Alice\n", i); 50 | } 51 | 52 | return NULL; 53 | } 54 | 55 | int main(void) { 56 | 57 | pthread_t alice_tid; 58 | pthread_t bob_tid; 59 | 60 | pthread_create(&alice_tid, NULL, alice, NULL); 61 | pthread_create(&bob_tid, NULL, bob, NULL); 62 | 63 | // start the chain 64 | bob_has_mail = true; 65 | pthread_cond_signal(&bob_signal); 66 | 67 | pthread_join(alice_tid, NULL); 68 | pthread_join(bob_tid, NULL); 69 | 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /tut/tut11/q6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define NWHITE (1000) 6 | #define NRED (NWHITE * 2) 7 | 8 | sem_t red_pairs; 9 | sem_t white_mutex; 10 | pthread_barrier_t stage; 11 | 12 | void* red(void *arg) { 13 | 14 | // Using a semaphore that allows only two red threads to enter 15 | // Using a barrier to wait for the white thread to enter 16 | 17 | sem_wait(&red_pairs); 18 | pthread_barrier_wait(&stage); 19 | sem_post(&red_pairs); 20 | 21 | return NULL; 22 | } 23 | 24 | void* white(void *arg) { 25 | 26 | // Using a mutex that allows only one white thread to enter 27 | // Using a barrier to wait for the other two red threads 28 | 29 | sem_wait(&white_mutex); 30 | pthread_barrier_wait(&stage); 31 | sem_post(&white_mutex); 32 | 33 | return NULL; 34 | } 35 | 36 | int main(void) { 37 | 38 | sem_init(&red_pairs, 0, 2); 39 | sem_init(&white_mutex, 0, 1); 40 | pthread_barrier_init(&stage, NULL, 3); 41 | 42 | pthread_t thread_ids[NRED + NWHITE]; 43 | 44 | for (size_t i = 0; i < NWHITE; ++i) { 45 | pthread_create(thread_ids + i * 3 + 0, NULL, red, NULL); 46 | pthread_create(thread_ids + i * 3 + 1, NULL, red, NULL); 47 | pthread_create(thread_ids + i * 3 + 2, NULL, white, NULL); 48 | } 49 | 50 | for (size_t i = 0; i < NRED + NWHITE; ++i) { 51 | pthread_join(thread_ids[i], NULL); 52 | } 53 | 54 | pthread_barrier_destroy(&stage); 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /tut/tut11/semaphore.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. The rights granted to you under the License 10 | * may not be used to create, or enable the creation or redistribution of, 11 | * unlawful or unlicensed copies of an Apple operating system, or to 12 | * circumvent, violate, or enable the circumvention or violation of, any 13 | * terms of an Apple operating system software license agreement. 14 | * 15 | * Please obtain a copy of the License at 16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 | * 18 | * The Original Code and all software distributed under the License are 19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 | * Please see the License for the specific language governing rights and 24 | * limitations under the License. 25 | * 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 | */ 28 | /* @(#)semaphore.h 1.0 2/29/00 */ 29 | 30 | 31 | 32 | /* 33 | * semaphore.h - POSIX semaphores 34 | * 35 | * HISTORY 36 | * 29-Feb-00 A.Ramesh at Apple 37 | * Created for Mac OS X 38 | */ 39 | 40 | #ifndef _SYS_SEMAPHORE_H_ 41 | #define _SYS_SEMAPHORE_H_ 42 | 43 | typedef int sem_t; 44 | 45 | /* this should go in limits.h> */ 46 | #define SEM_VALUE_MAX 32767 47 | #define SEM_FAILED ((sem_t *)-1) 48 | 49 | #include 50 | 51 | __BEGIN_DECLS 52 | int sem_close(sem_t *); 53 | int sem_destroy(sem_t *); 54 | int sem_getvalue(sem_t * __restrict, int * __restrict); 55 | int sem_init(sem_t *, int, unsigned int); 56 | sem_t * sem_open(const char *, int, ...); 57 | int sem_post(sem_t *); 58 | int sem_trywait(sem_t *); 59 | int sem_unlink(const char *); 60 | int sem_wait(sem_t *) __DARWIN_ALIAS_C(sem_wait); 61 | __END_DECLS 62 | 63 | 64 | #endif /* _SYS_SEMAPHORE_H_ */ 65 | 66 | -------------------------------------------------------------------------------- /tut/tut12/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/tut12/.DS_Store -------------------------------------------------------------------------------- /tut/tut12/a.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/tut12/a.out -------------------------------------------------------------------------------- /tut/tut12/q1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | static inline bool is_palindrome(char * s, size_t len) { 8 | if (len <= 1) { 9 | return true; 10 | } else if (s[0] != s[len - 1]) { 11 | return false; 12 | } 13 | return is_palindrome(s + 1, len - 2); 14 | } 15 | 16 | bool is_palindrome_iter(char* s, size_t len) { 17 | while (true) { 18 | if (len <= 1) { 19 | return true; 20 | } else if (s[0] != s[len - 1]) { 21 | return false; 22 | } 23 | s++; 24 | len -= 2; 25 | } 26 | } 27 | 28 | int main() { 29 | const clock_t tick = clock(); 30 | 31 | int result = is_palindrome("noon", sizeof("noon")); 32 | printf("noon is palindrome: True or False %d\n", result); 33 | 34 | result = is_palindrome("madam", sizeof("madam")); 35 | printf("madam is palindrome: True or False %d\n", result); 36 | 37 | result = is_palindrome("rececar", strlen("racecar")); 38 | printf("racecar is palindrome: True or False %d\n", result); 39 | 40 | result = is_palindrome("phoebe", strlen("phoebe")); 41 | printf("phoebe is palindrome: True or False %d\n", result); 42 | 43 | for (int i = 0; i < 100; i++) { 44 | char long_palindrome_recur[20001] = {0}; 45 | 46 | for (int j = 0; j < 20000; j++) { 47 | long_palindrome_recur[j] = 'a'; 48 | } 49 | 50 | result = is_palindrome(long_palindrome_recur, strlen(long_palindrome_recur)); 51 | } 52 | 53 | const clock_t tock = clock(); 54 | printf("Time elapsed: %fs\n", (double) (tock - tick) / CLOCKS_PER_SEC); 55 | } -------------------------------------------------------------------------------- /tut/tut12/q3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void cpy1 (char* restrict dest, char* restrict src, size_t n) { 5 | for (size_t i = 0; i < n; ++i) { 6 | dest[i] = src[i]; 7 | } 8 | } 9 | 10 | void cpy2 (char* dest, char* src, size_t n) { 11 | for (size_t i = 0; i < n; ++i) { 12 | dest[i] = src[i]; 13 | } 14 | } 15 | 16 | // this will result in a segmentation fault because "123456" is a const char* 17 | void example1() { 18 | char* s = "123456"; 19 | cpy2(s + 1, s, 4); 20 | printf("%s\n", s); 21 | } 22 | 23 | // the content of s will e 111116 24 | void example2() { 25 | char s[] = "123456"; 26 | cpy2(s + 1, s, 4); 27 | printf("%s\n", s); 28 | } 29 | 30 | int main() { 31 | // example1(); 32 | example2(); 33 | } -------------------------------------------------------------------------------- /tut/tut2/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/tut2/.DS_Store -------------------------------------------------------------------------------- /tut/tut2/q1.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | puts("Hello World!"); 5 | return 0; 6 | } 7 | -------------------------------------------------------------------------------- /tut/tut2/q10.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int string_compare(const char* w1, const char* w2, unsigned int len) { 4 | if (w1 == NULL || w2 == NULL) 5 | return -1; 6 | 7 | for (int i = 0; i < len; i++) { 8 | if(*w1 < *w2) { 9 | return -1; 10 | } 11 | if(*w1 > *w2) { 12 | return 1; 13 | } 14 | 15 | w1++; 16 | w2++; 17 | } 18 | 19 | return 0; 20 | } 21 | 22 | int main() 23 | { 24 | printf("%d\n", string_compare("comp2017", "comp2017", 8)); //0 25 | printf("%d\n", string_compare("pointers", "points", 6)); // -1 26 | printf("%d\n", string_compare("arreys", "arrays", 5)); // 1 27 | printf("%d\n", string_compare("arreys", "arrays", 3)); // 0 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /tut/tut2/q11.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define MAX_LEN 100 4 | 5 | int string_compare(const char* w1, const char* w2, unsigned int len) { 6 | if (w1 == NULL || w2 == NULL) 7 | return -1; 8 | 9 | for (int i = 0; i < len; i++) { 10 | if(*w1 < *w2) { return -1; } 11 | if(*w1 > *w2) { return 1; } 12 | w1++; 13 | w2++; 14 | } 15 | return 0; 16 | } 17 | 18 | int main(int argc, char** argv) { 19 | if(argc != 2) { 20 | printf("Need more arguments\n"); 21 | return 0; 22 | } 23 | 24 | // argv[0] is the name of file 25 | char* search_term = argv[1]; 26 | int len = strlen(search_term); 27 | 28 | char buffer[MAX_LEN]; 29 | 30 | while(fgets(buffer, sizeof(buffer), stdin) != NULL) { 31 | 32 | char* current_term = buffer; 33 | // stop util current term is null byte 34 | while(*current_term) { 35 | // two thing are exactly same before len 36 | if(string_compare(current_term, search_term, len) == 0) { 37 | printf("Found: %s", buffer); 38 | break; 39 | } 40 | current_term++; 41 | } 42 | } 43 | return 0; 44 | } 45 | x 46 | -------------------------------------------------------------------------------- /tut/tut2/q2.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char **argv) { 4 | char *greeting = argv[1]; 5 | char name[20]; 6 | printf("What is your name? "); 7 | // scanf("%s", name); 8 | fgets(name, 100, stdin); 9 | printf("%s! %s", greeting, name); 10 | return 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /tut/tut2/q3.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(){ 4 | int c; 5 | 6 | while ((c=getchar()) != EOF) { 7 | putchar(c); 8 | } 9 | 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /tut/tut2/q4.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char **argv) { 4 | for (int i = 1; i < argc; i++) { 5 | printf("%s ", argv[i]); 6 | } 7 | printf("\n"); 8 | return 0; 9 | 10 | } 11 | -------------------------------------------------------------------------------- /tut/tut2/q5a.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char** argv) { 4 | const char * ptr = "hello"; 5 | printf("ptr: %s\n", ptr); 6 | 7 | const char array[] = "hello"; 8 | printf("array: %s\n", array); 9 | 10 | const char array2[] = { 'h', 'e', 'l', 'l', 'o' }; 11 | printf("array2: %s\n", array2); 12 | 13 | const char array3[] = { 'h', 'e', 'l', 'l', 'o', '\0' }; 14 | printf("array3: %s\n", array3); 15 | 16 | const char array4[5] = { 'h', 'e', 'l', 'l', 'o' }; 17 | printf("array4: %s\n", array4); 18 | 19 | const char array5[6] = { 'h', 'e', 'l', 'l', 'o', 0 }; 20 | printf("array5: %s\n", array5); 21 | 22 | const char array6[20] = { 'h', 'e', 'l', 'l', 'o' }; 23 | printf("array6: %s\n", array6); 24 | 25 | const char array7[20] = { 0 }; 26 | printf("array7: %s\n", array7); 27 | 28 | const char array8[20] = "hello"; 29 | printf("array8: %s\n", array8); 30 | 31 | printf("\nsizes\n"); 32 | printf("ptr: %zu array: %zu\n", sizeof(ptr), sizeof(array)); 33 | printf("array2: %zu array3: %zu\n", sizeof(array2), sizeof(array3)); 34 | printf("*ptr: %zu &array: %zu\n", sizeof(*ptr), sizeof(&array)); 35 | printf("&array2: %zu &array3: %zu\n", sizeof(&array2), sizeof(&array3)); 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /tut/tut2/q5b.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char** argv) { 4 | int x[] = { 1, 2, 3 }; 5 | int * p1 = x; 6 | int * p2 = x + 1; 7 | printf("%zu %zu\n", sizeof(x[0]), sizeof(x)); 8 | printf("p1 value, p2 value: %d %d\n", *p1, *p2); 9 | printf("p1 value with offset: %d\n", *(p1 + 1)); 10 | printf("p2 value with offset: %d\n", *(p2 - 1)); 11 | printf("p1 value plus scalar: %d\n", (*p1) + 2); 12 | printf("p1 plus offset followed: %d\n", *(p1 + 2)); 13 | printf("p1 plus offset followed: %d\n", p1[2]); 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /tut/tut2/q7.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void swap(int a[], int b[]) { 4 | int temp = *a; 5 | *a = *b; // swap the value on the address 6 | *b = temp; 7 | } 8 | 9 | int main(void) { 10 | int a = 2; 11 | int b = 3; 12 | swap(&a, &b); // swap the value on the address 13 | printf("%d %d\n", a, b); 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /tut/tut2/q8.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include // allow you to use sizeof 3 | 4 | int atoi (const char s[]) { 5 | int result = 0; 6 | int multiplier = 1; 7 | 8 | // check the first sign 9 | if (s[0] == '-') { 10 | multiplier = -1; 11 | s++; 12 | } 13 | // get the size of array in function, you can find the null byte 14 | while (*s) { // only null byte is false 15 | result = result * 10 + (*s - '0'); 16 | s++; 17 | } 18 | 19 | return result * multiplier; 20 | } 21 | 22 | int main(void) { 23 | printf("%d\n", atoi("")); 24 | printf("%d\n", atoi("0")); 25 | printf("%d\n", atoi("0123")); 26 | printf("%d\n", atoi("1234")); 27 | printf("%d\n", atoi("-1234")); 28 | } 29 | -------------------------------------------------------------------------------- /tut/tut2/q9.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define MAX_LEN 100 4 | 5 | int main(void) { 6 | // one extra byte needed for the null character 7 | char buffer[MAX_LEN]; 8 | 9 | while (fgets(buffer, sizeof(buffer), stdin) != NULL) { 10 | // strlen do not include the null byte 11 | int len = strlen(buffer)-1; 12 | printf("%d\n",strlen(buffer)); 13 | printf("%zu\n",sizeof(buffer)); 14 | 15 | // Check for newline character 16 | // index of last character is len-1, as it starts from 0 17 | if (buffer[len - 1] == '\n') { 18 | buffer[len - 1] = '\0'; 19 | } 20 | 21 | for (int i = 0; i < len / 2; i++) { 22 | char tmp = buffer[i]; 23 | buffer[i] = buffer[len - i - 1]; 24 | buffer[len - i - 1] = tmp; 25 | } 26 | 27 | printf("%s\n", buffer); 28 | 29 | } 30 | 31 | return 0; 32 | } 33 | 34 | -------------------------------------------------------------------------------- /tut/tut3/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/tut3/.DS_Store -------------------------------------------------------------------------------- /tut/tut3/myfile.txt: -------------------------------------------------------------------------------- 1 | 1234 2 | -------------------------------------------------------------------------------- /tut/tut3/printf.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | printf("%-3s %-15s %-5s\n", "ID", "Name", "Score"); 5 | const char* format = "%03d %-15s %.2f\n"; 6 | 7 | printf(format, 1, "Bryan Cantrill", 99.449); 8 | printf(format, 2, "Scott Forstall", 99.999); 9 | 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /tut/tut3/q1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define BUF_SIZE (100) 5 | 6 | int main(void) { 7 | int c; 8 | int e; 9 | 10 | while ((c=getchar()) != EOF) { 11 | if (c >= 'a' && c <= 'z') { 12 | e = c - 32; 13 | putchar(e); 14 | } else { 15 | putchar(c); 16 | } 17 | } 18 | 19 | // method two 20 | // char buf[BUF_SIZE]; 21 | // while (fgets(buf, BUF_SIZE, stdin) != NULL) { 22 | // for (char *p = buf; *p; ++p) 23 | // if (*p >= 'a' && *p <= 'z') 24 | // *p = toupper(*p); // or *p -= ('a' - 'A') 25 | 26 | // printf("%s\n", buf); 27 | // } 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /tut/tut3/q11.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define LOWER (33) 4 | #define UPPER (126) 5 | 6 | 7 | int main(int argc, char **argv) { 8 | int len = atoi(argv[1]); 9 | char result[len]; 10 | srand(2); 11 | for (int i = 0; i < len; i++) { 12 | result[i] = (rand() % (UPPER - LOWER + 1)) + LOWER; 13 | } 14 | result[len] = '\0'; 15 | puts(result); 16 | } 17 | -------------------------------------------------------------------------------- /tut/tut3/q12.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // if no command line arguments, then read from standard input, output to standard output 5 | // for other arguments, open the filename, read from the file, output to standard output 6 | // for argument '-', read from standard input instead 7 | 8 | int main(int agvc, char **argv) { 9 | int num; 10 | 11 | // use appropriate location if you are using MacOS or Linux 12 | FILE *fptr = fopen(argv[1],"w"); 13 | 14 | if(fptr == NULL) { 15 | printf("Error!\n"); 16 | exit(1); 17 | } 18 | 19 | printf("Enter num: \n"); 20 | scanf("%d",&num); 21 | 22 | fprintf(fptr,"%d\n",num); 23 | fclose(fptr); 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /tut/tut3/q2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define LENGTH 100 3 | 4 | int main(void) { 5 | int velocity; 6 | double time; 7 | printf("What is your current km/h: "); 8 | scanf("%d", &velocity); 9 | 10 | printf("How many hours are you travelling for: "); 11 | scanf("%lf", &time); 12 | 13 | double distance = velocity * time; 14 | double convert_d = distance / 1.60934; 15 | double convert_v = velocity * 0.621371; 16 | 17 | 18 | printf("You will cover: %.2f km (%.2f mi)\nWhile travelling at %d km/h (%.2f mph)\n", distance, convert_d, velocity, convert_v); 19 | } 20 | -------------------------------------------------------------------------------- /tut/tut3/q4.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define NAME_LENGTH (100) 4 | #define MAN_NUM (10) 5 | 6 | int main() { 7 | int i = 0; 8 | char first_names[MAN_NUM][NAME_LENGTH]; 9 | char last_names[MAN_NUM][NAME_LENGTH]; 10 | int runs[MAN_NUM]; 11 | int count = 1; 12 | while (i < MAN_NUM) { 13 | printf("Enter Name and Score for batter %d: ", i + 1); 14 | count = (scanf("%s %s %d", first_names[i], last_names[i], &runs[i]) == 3); 15 | i = i + count ; 16 | } 17 | for (int i = 0; i < MAN_NUM; i++) { 18 | if (runs[i] == 0) { 19 | printf("%c. %s: Duck\n", first_names[i][0], last_names[i]); 20 | } else { 21 | printf("%c. %s: %d\n", first_names[i][0], last_names[i], runs[i]); 22 | } 23 | } 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /tut/tut3/q6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | int r; 6 | // const float PI = 3.1415; 7 | printf("Specify the radius of the sphere: "); 8 | scanf("%d", &r); 9 | double v = 4/3 * M_PI * pow(r,3); 10 | printf("Volume is: %f\n", v); 11 | } 12 | -------------------------------------------------------------------------------- /tut/tut3/q7.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int my_strlen(const char* s) { 4 | int count = 0; 5 | // while (*s) { 6 | // count++; 7 | // s++; 8 | // } 9 | if(s != NULL) { 10 | for(int i = 0; s[i] != '\0'; i++) { 11 | count++; 12 | } 13 | } 14 | return count; 15 | } 16 | 17 | int main(void) { 18 | printf("%d\n", my_strlen("")); // should output 0 19 | printf("%d\n", my_strlen("123")); // should output 3 20 | printf("%d\n", my_strlen("abc\n")); // should output 4 21 | printf("%d\n", my_strlen("lorem\0ipsum\n")); // should output 5 22 | printf("%d\n", my_strlen("lorem ipsum\n")); // should output 12 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /tut/tut3/q8.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int substring(const char* haystack, const char* needle) { 5 | int haystack_len = strlen(haystack); 6 | int needle_len = strlen(needle); 7 | 8 | int result = 0; 9 | int index; 10 | for(int i = 0; i <= (haystack_len - needle_len); i++){ 11 | int match = 1; 12 | for(int j = 0; j < needle_len; j++){ 13 | if(haystack[i + j] != needle[j]){ 14 | match = 0; // 0 i ndicate false 15 | } else { 16 | index = i; 17 | } 18 | } 19 | if(match == 1){ // 1 indicate true 20 | return index; 21 | } 22 | } 23 | return -1; 24 | } 25 | 26 | int main() { 27 | printf("%d\n", substring("racecar", "car")); //4 28 | printf("%d\n", substring("telephone", "one")); //6 29 | printf("%d\n", substring("monkey", "cat")); //-1 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /tut/tut3/q9.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int encode_run(const char* line_run, unsigned line_len, char* buf, unsigned int buf_len) { 4 | 5 | char c = line_run[0]; 6 | int count = 0; 7 | int buf_index = 0; 8 | 9 | // Iterate through the line run 10 | for (int i = 0; i < line_len - 1; i++) { // Why (line_len - 1)? 11 | // Test if current character is different to prev 12 | if (c != line_run[i]) { 13 | // convert the count to a string (only works up to 9) 14 | buf[buf_index++] = (char)(count + '0'); 15 | // update pre char to current 16 | c = line_run[i]; 17 | // restore count to 0, start new counting 18 | count = 0; 19 | } 20 | count++; 21 | } 22 | 23 | // account for the last sequence 24 | buf[buf_index] = (char)(count + '0'); 25 | // null terminate the output buffer 26 | buf_index = buf_index + 1; 27 | buf[buf_index] = '\0'; 28 | return 0; 29 | } 30 | 31 | int main(int argc, char **argv) { 32 | char encoded_run[128]; 33 | 34 | encode_run("1122333334423", 14, encoded_run, 128); 35 | printf("%s\n", encoded_run); // 225211 36 | 37 | encode_run("1", 2, encoded_run, 128); 38 | printf("%s\n", encoded_run); // 1 39 | 40 | encode_run("123456", 7, encoded_run, 128); 41 | printf("%s\n", encoded_run); // 111111 42 | } 43 | -------------------------------------------------------------------------------- /tut/tut3/scanf.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | int x; 5 | double y; 6 | // buffer is an array and has type char[20] 7 | char buffer[20]; 8 | 9 | // scanf function returns the number of input items successfully matched and assigned 10 | if (scanf("%d %lf %19s", &x, &y, buffer) != 3) { 11 | // when reading strings with scanf, you should provide a width specifier 12 | fprintf(stderr, "Invalid input\n"); 13 | return 1; 14 | } 15 | printf("%d %f %s\n", x, y, buffer); 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /tut/tut4/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/tut4/.DS_Store -------------------------------------------------------------------------------- /tut/tut4/astley.tct: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/tut4/astley.tct -------------------------------------------------------------------------------- /tut/tut4/astley.txt: -------------------------------------------------------------------------------- 1 | Nevergonnagiveyouup 2 | Nevergonnaletyoudown 3 | Nevergonnarunaroundanddesertyou 4 | Nevergonnamakeyoucry 5 | desertNevergonnasaygoodbye 6 | cry 7 | Nevergonnatellalieandhurtyou 8 | onna tell a lie and hurt you 9 | 10 | -------------------------------------------------------------------------------- /tut/tut4/batters.csv: -------------------------------------------------------------------------------- 1 | Phoebe, Zuo, 20 2 | -------------------------------------------------------------------------------- /tut/tut4/gamepad.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | 3 | 4 | gcc gamepad.c -o gamepad -std=c99 5 | 6 | # Creates a unidirectional pipe, write from ./device and read from ./controller 7 | socat pty,raw,echo=0,link=./controller0 pty,raw,echo=0,link=./device0 & 8 | 9 | #Saves the pid out 10 | echo $! > socat_pid 11 | 12 | #Sleeps and allows for it be set up (Ed only issue) 13 | sleep 1 14 | 15 | #Runs the gamepad 16 | ./gamepad ./device0 $1 17 | kill -HUP $(cat socat_pid) 18 | rm socat_pid 19 | 20 | -------------------------------------------------------------------------------- /tut/tut4/myfile.txt: -------------------------------------------------------------------------------- 1 | Hello 2 | -------------------------------------------------------------------------------- /tut/tut4/pokemon.dex: -------------------------------------------------------------------------------- 1 | PikachuSquirtle 2 | Charizard2Eevee -------------------------------------------------------------------------------- /tut/tut4/q1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef int uint8_t; 5 | typedef int uint32_t; 6 | 7 | struct quoll { 8 | char name[20]; 9 | uint8_t age; 10 | }; 11 | 12 | struct quokka { 13 | char * name; 14 | struct quokka * quokka_father; 15 | struct quokka * quokka_mother; 16 | }; 17 | 18 | union mammal { 19 | struct quoll l; 20 | struct quokka a; 21 | }; 22 | 23 | int main() { 24 | int a; 25 | int * b = &a; 26 | int * c = NULL; 27 | 28 | unsigned d; 29 | short e; 30 | long f; 31 | size_t g; 32 | long long h; 33 | 34 | uint8_t i; 35 | uint32_t j; 36 | 37 | printf("sizeof(int): %lu\n", sizeof(int)); // 4 38 | printf("sizeof(short): %lu\n", sizeof(short)); // 2 39 | printf("sizeof(long): %lu\n", sizeof(long)); // 8 40 | 41 | printf("sizeof(union mammal): %lu\n", sizeof(union mammal)); // 24 42 | printf("sizeof(struct quokka): %lu\n", sizeof(struct quokka)); // 24 43 | printf("sizeof(struct quoll): %lu\n", sizeof(struct quoll)); // 21 44 | 45 | printf("sizeof(struct quoll*): %lu\n", sizeof(struct quoll*)); // 8 46 | printf("sizeof(struct quokka*): %lu\n", sizeof(struct quokka*)); // 8 47 | } 48 | -------------------------------------------------------------------------------- /tut/tut4/q10.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | typedef struct { 7 | unsigned int id:8; 8 | unsigned int locked:8; 9 | unsigned int x:1; 10 | unsigned int y:1; 11 | unsigned int z:1; 12 | unsigned int w:1; 13 | unsigned int a:1; 14 | unsigned int b:1; 15 | unsigned int c:1; 16 | unsigned int d:1; 17 | unsigned int l:1; 18 | unsigned int r:1; 19 | unsigned int st:1; 20 | unsigned int sel:1; 21 | unsigned int pad_1:1; 22 | unsigned int pad_2:1; 23 | unsigned int pad_3:1; 24 | unsigned int pad_4:1; 25 | float left; 26 | float right; 27 | } gamepad_data; 28 | 29 | typedef union { 30 | gamepad_data d; 31 | unsigned int raw[2]; 32 | } gdata; 33 | 34 | //Start reading data is faking input to demonstrate what is happening 35 | void read_gamepad(gdata* d) { 36 | d->raw[0] = rand(); 37 | d->raw[1] = rand(); 38 | } 39 | 40 | /* 41 | * 42 | */ 43 | int main(int argc, char** argv) { 44 | srand(time(NULL)); 45 | int n = strtol(argv[2], NULL, 10); 46 | FILE* f = fopen(argv[1], "wb"); 47 | gdata u_data; 48 | if(f != NULL) { 49 | while(n >= 0) { 50 | n--; 51 | read_gamepad(&u_data); 52 | fwrite(&(u_data.d), sizeof(gamepad_data), 1, f); 53 | //fflush(f); 54 | sleep(1); //Updates every second 55 | } 56 | } 57 | fclose(f); 58 | return 0; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /tut/tut4/q2.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | enum TYPE { FIRE, WATER, FLYING, ROCK, ELECTRIC }; 4 | struct pokemon { 5 | const char * name; 6 | enum TYPE type; 7 | }; 8 | 9 | int main () { 10 | printf("sizeof(struct pokemon): %lu\n", sizeof(struct pokemon)); 11 | struct pokemon pikachu = { "Pikachu", ELECTRIC }; 12 | struct pokemon *ptr = &pikachu; 13 | ptr -> name = "Raichu"; 14 | ptr -> type = ELECTRIC; 15 | printf("%s %d\n", ptr -> name, ptr -> type); 16 | } 17 | -------------------------------------------------------------------------------- /tut/tut4/q3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define ARR_LEN (100) 6 | 7 | struct customer { 8 | char name[ARR_LEN]; 9 | int age; 10 | char thing[ARR_LEN]; 11 | }; 12 | 13 | int main() { 14 | puts("Welcome to ShopaMocha,"); 15 | puts("Could you please tell me your name, age and what you looking for?"); 16 | 17 | struct customer customer_list[ARR_LEN]; 18 | int count = 0; 19 | char buffer[ARR_LEN]; 20 | 21 | while (scanf("%s", buffer) != EOF) { 22 | strcpy(customer_list[count].name, buffer); 23 | scanf("%d", &customer_list[count].age); 24 | scanf("%s", customer_list[count].thing); 25 | printf("Hrmm, I think you should talk to a ShopaMocha assistant to find \"%s\" Have a good day!\n", customer_list[count].thing); 26 | 27 | count++; 28 | 29 | puts("Welcome to ShopaMocha,"); 30 | puts("Could you please tell me your name, age and what you looking for?"); 31 | } 32 | 33 | for (int i = 0; i < count; i++) { 34 | printf("Customer: %d, Name: %s, Age: %d, Looking for: %s\n", i, customer_list[i].name, customer_list[i].age, customer_list[i].thing); 35 | } 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /tut/tut4/q4.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // read by char 6 | int main(int agrc, char* argv[]) { 7 | FILE* file = fopen("output1.txt", "r"); 8 | if (file == NULL) { 9 | perror("unable to open file"); 10 | fclose(file); 11 | return 1; 12 | } 13 | while (!feof(myfile)) { 14 | char ch = fgetc(myfile); 15 | printf("%c", ch-2 ); 16 | } 17 | fclose(file); 18 | return 0; 19 | } 20 | 21 | // read by word 22 | int main (int argc, char* argv[]) { 23 | FILE* file = fopen("output2.txt", "r+"); 24 | if (file == NULL) { 25 | perror("unable to open file"); 26 | fclose(file); 27 | return 1; 28 | } 29 | char str[100]; 30 | while (fscanf(myfile, "%s", str) != EOF) { 31 | printf("%s\n", str); 32 | } 33 | fclose(file); 34 | return 0; 35 | } 36 | 37 | // read by line 38 | int main (int argc, char* argv[]) { 39 | FILE* file = fopen("output3.txt", "r+"); 40 | if (file == NULL) { 41 | perror("unable to open file"); 42 | fclose(file); 43 | return 1; 44 | } 45 | char str[100]; 46 | while (fgets(buffer, sizeof(buffer), nyfile) != NULL) { 47 | printf("%s", buffer); 48 | } 49 | fclose(file); 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /tut/tut4/q6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | void do_wc(FILE* f, const char* name) { 7 | 8 | int words = 0; 9 | int lines = 0; 10 | int bytes = 0; 11 | char c = 0; 12 | 13 | 14 | if(f != NULL) { 15 | 16 | int word_ev = 0; 17 | while((c = fgetc(f)) != EOF) { 18 | if(c == '\n') { 19 | lines++; 20 | if(word_ev > 0) { 21 | words++; 22 | word_ev = 0; 23 | } 24 | } else if(c == ' ') { 25 | if(word_ev > 0) { 26 | words++; 27 | word_ev = 0; 28 | } 29 | } else { 30 | word_ev++; 31 | } 32 | bytes++; 33 | } 34 | 35 | if(word_ev > 0) { 36 | words++; 37 | } 38 | printf("%d\t%d\t%d\t%s\n", lines, words, bytes, name); 39 | } 40 | } 41 | 42 | int main(int argc, char** argv) { 43 | if (argc > 1) { 44 | for(int i = 1; i < argc; i++) { 45 | FILE* f = fopen(argv[i], "r"); 46 | if(f != NULL) { 47 | do_wc(f, argv[i]); 48 | } 49 | fclose(f); 50 | } 51 | } else { 52 | if(stdin != NULL) { 53 | do_wc(stdin, "stdin"); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /tut/tut4/q7.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int argc, char* argv[]) { 6 | FILE* file1 = fopen(argv[1],"r"); 7 | if (file1 == NULL) { 8 | perror("file1 not exist"); 9 | return 1; 10 | } 11 | FILE* file2 = fopen(argv[2],"r+"); 12 | if (file2 == NULL) { 13 | perror("file2 not exist"); 14 | return 1; 15 | } 16 | 17 | char buffer[1000]; 18 | char words[20][50]; 19 | while (fgets(buffer, 1000, file1) != NULL) { 20 | int word_idx = 0; 21 | int letter_idx = 0; 22 | for (int i = 0; i <= strlen(buffer); i++) { 23 | if (buffer[i] == ' ' || buffer[i] == '\0') { 24 | words[word_idx][letter_idx] = '\0'; 25 | word_idx++; // for next word 26 | letter_idx = 0; // for next word, init index to 0 27 | } else { 28 | words[word_idx][letter_idx] = buffer[i]; 29 | letter_idx ++; 30 | } 31 | } 32 | for (int i = 0; i <= word_idx; i++) { 33 | printf("%s\n", words[i]); 34 | if (strcmp(words[i], "Always") == 0) { 35 | fprintf(file2, "%s", "Never"); 36 | } else { 37 | fprintf(file2, "%s", words[i]); 38 | } 39 | puts(""); 40 | } 41 | } 42 | fclose(file1); 43 | fclose(file2); 44 | } 45 | -------------------------------------------------------------------------------- /tut/tut4/q8.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct batsman { 6 | char first_name[20]; 7 | char last_name[20]; 8 | int score; 9 | }; 10 | 11 | int output_scores(struct batsman* batters, const char* filename) { 12 | FILE* f = fopen(filename, "a"); 13 | if (f != NULL) { 14 | fprintf(f, "%s, %s, %d\n", batters -> first_name, batters -> last_name, batters -> score); 15 | } 16 | return 0; 17 | } 18 | 19 | int main() { 20 | struct batsman b; 21 | strcpy(b.first_name, "Phoebe"); 22 | strcpy(b.last_name, "Zuo"); 23 | b.score = 20; 24 | 25 | // struct batsman* p = malloc(sizeof(struct batsman)); 26 | 27 | output_scores(&b, "batters.csv"); 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /tut/tut4/q9.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define SIZE 4 6 | 7 | typedef struct pokemon { 8 | char name[100]; 9 | unsigned level; 10 | } pokemon; 11 | 12 | int main(void) { 13 | pokemon pokemons[SIZE] = { 14 | { .name = "Pikachu", .level = 5 }, 15 | { .name = "Squirtle", .level = 10 }, 16 | { .name = "Charizard", .level = 50 }, 17 | { .name = "Eevee", .level = 25 } 18 | }; 19 | 20 | printf("sizeof(size_t) = %zu\n", sizeof(size_t)); // 8 21 | printf("sizeof(unsigned) = %zu\n", sizeof(unsigned)); // 4 22 | printf("sizeof(char[100]) = %zu\n", sizeof(char[100])); // 100 23 | 24 | printf("sizeof(pokemon) = %zu\n", sizeof(pokemon)); // 104 25 | printf("sizeof(pokemons) = %zu\n", sizeof(pokemons)); // 416 26 | 27 | // attempt to save to file 28 | FILE* file = fopen("pokemon.dex", "w"); 29 | if (file == NULL) { 30 | perror("unable to open file for writing"); 31 | return 1; 32 | } 33 | fwrite(pokemons, sizeof(pokemon), SIZE, file); 34 | fclose(file); 35 | 36 | // read from file 37 | FILE* f = fopen("pokemon.dex", "r"); 38 | fread(pokemons, sizeof(pokemon), SIZE, f); 39 | 40 | for (size_t i = 0; i < SIZE; i++) { 41 | printf("Name: %s Level: %d\n", pokemons[i].name, pokemons[i].level); 42 | } 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /tut/tut4/rick.txt: -------------------------------------------------------------------------------- 1 | Always gonna give you up 2 | Always gonna let you down 3 | Always gonna run around and desert you 4 | Always gonna make you cry 5 | Always gonna say goodbye 6 | Always gonna tell a lie and hurt you 7 | -------------------------------------------------------------------------------- /tut/tut5/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/tut5/.DS_Store -------------------------------------------------------------------------------- /tut/tut5/circular-linked-list.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef struct Node 5 | 6 | { 7 | int info; 8 | struct Node *next; 9 | }node; 10 | 11 | node *front=NULL,*rear=NULL,*temp; 12 | 13 | void create(); 14 | void del(); 15 | void display(); 16 | 17 | int main() 18 | { 19 | int chc; 20 | do 21 | { 22 | printf("\nMenu\n\t 1 to create the element : "); 23 | printf("\n\t 2 to delete the element : "); 24 | printf("\n\t 3 to display the queue : "); 25 | printf("\n\t 4 to exit from main : "); 26 | printf("\nEnter your choice : "); 27 | scanf("%d",&chc); 28 | 29 | switch(chc) 30 | { 31 | case 1: 32 | create(); 33 | break; 34 | 35 | case 2: 36 | del(); 37 | break; 38 | 39 | case 3: 40 | display(); 41 | break; 42 | 43 | case 4: 44 | return 1; 45 | 46 | default: 47 | printf("\nInvalid choice :"); 48 | } 49 | }while(1); 50 | 51 | return 0; 52 | } 53 | 54 | void create() 55 | { 56 | node *newnode; 57 | newnode=(node*)malloc(sizeof(node)); 58 | printf("\nEnter the node value : "); 59 | scanf("%d",&newnode->info); 60 | newnode->next=NULL; 61 | if(rear==NULL) 62 | front=rear=newnode; 63 | else 64 | { 65 | rear->next=newnode; 66 | rear=newnode; 67 | } 68 | 69 | rear->next=front; 70 | } 71 | 72 | void del() 73 | { 74 | temp=front; 75 | if(front==NULL) 76 | printf("\nUnderflow :"); 77 | else 78 | { 79 | if(front==rear) 80 | { 81 | printf("\n%d",front->info); 82 | front=rear=NULL; 83 | } 84 | else 85 | { 86 | printf("\n%d",front->info); 87 | front=front->next; 88 | rear->next=front; 89 | } 90 | 91 | temp->next=NULL; 92 | free(temp); 93 | } 94 | } 95 | 96 | void display() 97 | { 98 | temp=front; 99 | if(front==NULL) 100 | printf("\nEmpty"); 101 | else 102 | { 103 | printf("\n"); 104 | for(;temp!=rear;temp=temp->next) 105 | printf("\n%d address=%p next=%u\t",temp->info,temp,temp->next->info); 106 | printf("\n%d address=%p next=%u\t",temp->info,temp,temp->next->info); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /tut/tut5/q1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int var_a; 5 | 6 | int sum (const int* var_b) { 7 | static int var_c; 8 | var_c += *var_b; 9 | return var_c; 10 | } 11 | 12 | int main(int argc, char** argv) { 13 | int var_d = 0; 14 | 15 | int* var_e = malloc(sizeof(int)); 16 | if (NULL == var_e) { 17 | perror("Malloc Failed!"); 18 | return 1; 19 | } 20 | *var_e = 2; 21 | sum(&var_d); 22 | sum(&var_a); 23 | sum(var_e); 24 | char* var_f = calloc(sizeof(char), 100); 25 | if (NULL == var_f) { 26 | perror("Calloc Failed"); 27 | return 1; 28 | } 29 | 30 | free(var_e); 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /tut/tut5/q2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct node { 5 | int value; 6 | struct node * next; 7 | }; 8 | 9 | struct node * list_init(int value) { 10 | struct node * temp = (struct node *)malloc(sizeof(struct node)); 11 | temp->value = value; 12 | temp->next = NULL; 13 | return temp; 14 | } 15 | 16 | void list_add(struct node* head, int value) { 17 | struct node *new_node = list_init(value); 18 | struct node *cur = head; 19 | while (cur->next != NULL) { 20 | cur = cur->next; 21 | } 22 | cur->next = new_node; 23 | } 24 | 25 | void list_delete(struct node **head, struct node* n) { 26 | struct node *cur = *head; 27 | if (cur == n) { // the list starts with n 28 | *head = n->next; 29 | free(cur); 30 | return; 31 | } 32 | 33 | while (cur->next != n) { 34 | cur = cur->next; 35 | } 36 | 37 | if (cur->next == n) { 38 | cur->next = n->next; 39 | free(n); 40 | } else { 41 | printf("n is not in this list!\n"); 42 | } 43 | } 44 | 45 | struct node* list_next(const struct node *n) { 46 | return n->next; 47 | } 48 | 49 | void list_free(struct node* head) { 50 | struct node *cur = head; 51 | while (cur != NULL) { 52 | struct node *next = list_next(cur); 53 | free(cur); 54 | cur = next; 55 | } 56 | } 57 | 58 | int main(){ 59 | struct node *head = list_init(5); 60 | list_add(head, 10); 61 | list_add(head, 15); 62 | list_add(head, 12); 63 | list_add(head, 20); 64 | 65 | list_delete(&head, head); // 10 15 12 20 66 | struct node *to_delete = list_next(list_next(head)); // 12 67 | list_delete(&head, to_delete); // 10 15 20 68 | 69 | struct node *cur = head; 70 | while (cur != NULL) { 71 | printf("%d\n", cur->value); 72 | cur = cur->next; 73 | } 74 | 75 | list_free(head); 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /tut/tut5/q4.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() { 6 | char buff[16]; 7 | char* string = malloc(32); 8 | size_t len = 0; 9 | size_t capacity = 32; 10 | while (fgets(buff, 16, stdin)) { 11 | // if the length is exceed with the length 12 | if (len + 16 >= capacity) { 13 | // resize 14 | char* temp = realloc(string, capacity * 2); // return true or false 15 | if (temp) { 16 | string = temp; 17 | capacity *= 2; 18 | } 19 | } 20 | size_t l = strlen(buff); 21 | // copy 16 bytes from buff to "string + len" 22 | memcpy(string + len, buff, 16); 23 | len += l; 24 | } 25 | puts(string); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /tut/tut5/q5.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define DYN_ARRAY_DEF_CAPACITY (8) 5 | 6 | struct dyn_array { 7 | int capacity; 8 | int size; 9 | int *data; 10 | }; 11 | 12 | static void dyn_array_resize(struct dyn_array* array) { 13 | array->capacity *= 2; 14 | array->data = realloc(array, sizeof(*(array->data) * array->capacity)); 15 | } 16 | 17 | struct dyn_array* dyn_array_init(){ 18 | struct dyn_array *array = malloc(sizeof(struct dyn_array)); 19 | array->capacity = DYN_ARRAY_DEF_CAPACITY; 20 | array->size = 0; 21 | array->data = malloc(sizeof(*(array->data) * array->capacity)); // size of data type times capacity 22 | return array; 23 | } 24 | 25 | void dyn_array_add(struct dyn_array* array, int value) { 26 | if (array != NULL) { 27 | if (array->size >= array->capacity) { 28 | int* temp = realloc(array->data, array->capacity*2); 29 | if (temp != NULL) { 30 | array->data = temp; 31 | array->capacity = array->capacity * 2; 32 | } else { 33 | fprintf(stderr, "Cannot resize array"); 34 | return; 35 | } 36 | } 37 | array->data[array->size++] = value; 38 | } 39 | } 40 | 41 | void dyn_array_delete(struct dyn_array* array, int index) { 42 | if (array != NULL) { 43 | if (index >= 0 && index < array->size) { 44 | // move 4*(size-index) bytes from data+index+1 to index 45 | memmove(array->data + index, 46 | array->data + index + 1, 47 | sizeof(int) * (array->size -index)); 48 | } 49 | } 50 | } 51 | 52 | int* dyn_array_get(struct dyn_array* array, int index) { 53 | if (array != NULL) { 54 | if (index >= 0 && index < array->size) { 55 | return array->data + index; // aka array[index] 56 | } 57 | } 58 | return NULL; 59 | } 60 | 61 | void dyn_array_free(struct dyn_array* array) { 62 | free(array->data); 63 | free(array); 64 | } 65 | 66 | int main() { 67 | struct dyn_array* array = dyn_array_init(); 68 | 69 | for (int i = 1; i < 100; i++) { 70 | dyn_array_add(array, i); 71 | } 72 | 73 | dyn_array_delete(array, 97); // 98 disappear 74 | 75 | for (int i = 0; i < array->size; i++) { 76 | printf("%d\n", *dyn_array_get(array, i)); 77 | } 78 | 79 | dyn_array_free(array); 80 | 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /tut/tut5/q6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/tut5/q6 -------------------------------------------------------------------------------- /tut/tut5/q6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | 6 | void *a = malloc(sizeof(int*) * (1 << 3)); 7 | void *b = malloc(sizeof(int*) * 9); 8 | 9 | for (size_t i = 0; i <= 6; i++) { 10 | ((int*)a)[5] += i >> 1; 11 | ((size_t*)b)[i] = i + ~i; 12 | 13 | // if (i == 8) { 14 | // free(a); 15 | // } 16 | } 17 | free(a); 18 | free(b); 19 | return 0; 20 | // return ((int*)a)[0]; 21 | } 22 | -------------------------------------------------------------------------------- /tut/tut6/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/tut6/.DS_Store -------------------------------------------------------------------------------- /tut/tut6/a.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/tut6/a.out -------------------------------------------------------------------------------- /tut/tut6/q1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main() { 7 | write(STDERR_FILENO, "hello world\n", strlen("hello world\n")); 8 | } 9 | -------------------------------------------------------------------------------- /tut/tut6/q5.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define N_ELEMENTS (5) 6 | 7 | struct scorecard { 8 | char name[20]; 9 | int score; 10 | }; 11 | 12 | int int_cmp(const void* a, const void* b) { 13 | return (*(int*)a - *(int*)b); 14 | } 15 | 16 | int str_cmp(const void* a, const void* b) { 17 | // allow compare between different length 18 | while (*(*(char**)a) || *(*(char**)b)) { 19 | if (*(*(char**)a) < *(*(char**)b)) { 20 | return 1; 21 | } else { 22 | return -1; 23 | } 24 | } 25 | return 0; 26 | } 27 | 28 | int struct_cmp(const void* a, const void* b) { 29 | return (((struct scorecard*)a)->score - ((struct scorecard*)b)->score); 30 | } 31 | 32 | int main() { 33 | int int_list[N_ELEMENTS] = {3, 4, 2, 6, 5}; 34 | qsort(int_list, N_ELEMENTS, sizeof(int), int_cmp); 35 | for (int i = 0; i < N_ELEMENTS; i++) { 36 | printf("%d ", int_list[i]); 37 | } 38 | puts(""); 39 | 40 | 41 | char* str_list[N_ELEMENTS] = {"hello", "world", "2017", "pretty", "hard"}; 42 | qsort(str_list, N_ELEMENTS, sizeof(char*), str_cmp); 43 | for (int i = 0; i < N_ELEMENTS; i++) { 44 | printf("%s\n", str_list[i]); 45 | } 46 | 47 | struct scorecard a = {"phoebe", 300}; 48 | struct scorecard b = {"edward", 200}; 49 | struct scorecard c = {"lesi", 350}; 50 | struct scorecard struct_list[3] = {a, b, c}; 51 | qsort(struct_list, 3, sizeof(struct scorecard), struct_cmp); 52 | for (int i = 0; i < 3; i++) { 53 | printf("%s %d\n", struct_list[i].name, struct_list[i].score); 54 | } 55 | 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /tut/tut6/q6.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define ADD (0) 4 | #define SUB (1) 5 | #define MUL (2) 6 | #define DIV (3) 7 | 8 | int add(int a, int b) { return a + b; } 9 | int sub(int a, int b) { return a - b; } 10 | int mul(int a, int b) { return a * b; } 11 | int div(int a, int b) { return a / b; } 12 | 13 | int main() { 14 | int (*operation[])(int, int) = {add, sub, mul, div}; 15 | int result = (*operation[ADD])(9, 10); // 19 16 | result = (*operation[SUB])(result, 10); // 9 17 | result = (*operation[MUL])(3, result); // 27 18 | result = (*operation[DIV])(result, 1); // 27 19 | printf("%d\n", result); // 27 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /tut/tut6/q7.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(void) { 7 | signal(SIGINT, SIG_IGN); 8 | 9 | while (true) { 10 | sleep(1); 11 | } 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /tut/tut6/q8.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | void sigusr_handler(int signo, siginfo_t* sinfo, void* context) { 9 | time_t rawtime; 10 | time(&rawtime); 11 | 12 | struct tm *timeinfo = localtime(&rawtime); 13 | printf("%s", asctime(timeinfo)); 14 | } 15 | 16 | void sigint_handler(int sig) { 17 | printf("\nShutting down\n"); 18 | exit(0); 19 | } 20 | 21 | int main() { 22 | // better approach 23 | struct sigaction sig; 24 | memset(&sig, 0, sizeof(struct sigaction)); 25 | sig.sa_sigaction = sigusr_handler; 26 | sig.sa_flags = SA_SIGINFO; 27 | sigaction(SIGUSR1, &sig, NULL); 28 | 29 | // original method, but cannot use in the future 30 | signal(SIGINT, sigint_handler); 31 | 32 | while (1) { 33 | sleep(1); 34 | } 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /tut/tut6/q9.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | double uptime() { 12 | struct timeval boottime; 13 | size_t len = sizeof(boottime); 14 | int mib[2] = { CTL_KERN, KERN_BOOTTIME }; 15 | if(sysctl(mib, 2, &boottime, &len, NULL, 0) < 0) { 16 | return -1.0; 17 | } 18 | time_t bsec = boottime.tv_sec, csec = time(NULL); 19 | 20 | return difftime(csec, bsec); 21 | } 22 | 23 | void minutes_on(int sig) { 24 | printf("%f\n", uptime()); 25 | } 26 | 27 | void random_num(int sig) { 28 | FILE* in_file = fopen("/dev/urandom", "r"); 29 | if (!in_file) { 30 | printf("Error reading file 1\n"); 31 | return; 32 | } 33 | 34 | char num[1]; 35 | size_t result = fread(num, 1, 1, in_file); 36 | if (result >= 0) { 37 | printf("%d\n", num[0]); 38 | } else { 39 | printf("Error reading file 2\n"); 40 | } 41 | fclose(in_file); 42 | } 43 | 44 | void tell_joke(int sig) { 45 | printf("How do you know if your code is delicious?\n"); 46 | printf("Try a byte.\n"); 47 | } 48 | 49 | void hangup_handler(int sig) { 50 | printf("I'm going into self-isolation\n"); 51 | printf("I can't respond anymore\n"); 52 | } 53 | 54 | int main(void) { 55 | signal(SIGINT, minutes_on); 56 | signal(SIGUSR1, random_num); 57 | signal(SIGUSR2, tell_joke); 58 | signal(SIGHUP, hangup_handler); 59 | 60 | while (true) { 61 | sleep(1); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tut/tut6/time: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/tut6/time -------------------------------------------------------------------------------- /tut/tut7/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/tut7/.DS_Store -------------------------------------------------------------------------------- /tut/tut7/list-example/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/tut7/list-example/.DS_Store -------------------------------------------------------------------------------- /tut/tut7/list-example/Makefile: -------------------------------------------------------------------------------- 1 | CC=clang 2 | CFLAGS=-g -std=c11 -Wall -Werror 3 | 4 | TARGET=tasks 5 | 6 | .PHONY: clean 7 | 8 | all: $(TARGET) 9 | 10 | clean: 11 | rm -f $(TARGET) 12 | rm -f *.o 13 | 14 | list.o: list.c 15 | $(CC) -c $(CFLAGS) $^ -o $@ 16 | 17 | tasks.o: tasks.c 18 | $(CC) -c $(CFLAGS) $^ -o $@ 19 | 20 | tasks: tasks.o list.o 21 | $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ 22 | -------------------------------------------------------------------------------- /tut/tut7/list-example/list.c: -------------------------------------------------------------------------------- 1 | #include "list.h" 2 | 3 | // Initializes an empty circular linked list. 4 | void list_init(node* head) { 5 | head->next = head; 6 | head->prev = head; 7 | } 8 | 9 | // Inserts given node before the head. 10 | void list_push(node* head, node* n) { 11 | n->prev = head; 12 | n->next = head->next; 13 | 14 | n->next->prev = n; 15 | n->prev->next = n; 16 | } 17 | 18 | // Inserts given node after the head. 19 | void list_append(node* head, node* n) { 20 | n->prev = head->prev; 21 | n->next = head; 22 | 23 | n->prev->next = n; 24 | n->next->prev = n; 25 | } 26 | 27 | // Removes the given node from the list. 28 | void list_delete(node* n) { 29 | n->prev->next = n->next; 30 | n->next->prev = n->prev; 31 | } 32 | 33 | // Returns whether the list is empty. 34 | int list_empty(node* head) { 35 | return head->prev == head; 36 | } 37 | -------------------------------------------------------------------------------- /tut/tut7/list-example/list.h: -------------------------------------------------------------------------------- 1 | #ifndef LIST_H 2 | #define LIST_H 3 | 4 | typedef struct node node; 5 | struct node { 6 | void* data; 7 | node* next; 8 | node* prev; 9 | }; 10 | 11 | // Initializes an empty circular linked list. 12 | void list_init(node* head); 13 | 14 | // Inserts given node before the head. 15 | void list_push(node* head, node* n); 16 | 17 | // Inserts given node after the head. 18 | void list_append(node* head, node* n); 19 | 20 | // Removes the given node from the list. 21 | void list_delete(node* n); 22 | 23 | // Returns whether the list is empty. 24 | int list_empty(node* head); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /tut/tut7/list-example/list.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/tut7/list-example/list.o -------------------------------------------------------------------------------- /tut/tut7/list-example/tasks.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "list.h" 6 | 7 | int main(void) { 8 | 9 | struct node *head = malloc(sizeof(struct node)); 10 | head->data = (int*)1; 11 | 12 | struct node *a = malloc(sizeof(struct node)); 13 | a->data = (int*)2; 14 | 15 | struct node *b = malloc(sizeof(struct node)); 16 | b->data = (int*)3; 17 | 18 | struct node *c = malloc(sizeof(struct node)); 19 | c->data = (int*)4; 20 | 21 | struct node *d = malloc(sizeof(struct node)); 22 | d->data = (int*)5; 23 | 24 | list_init(head); 25 | list_append(head, a); 26 | list_append(head, b); 27 | list_append(head, c); 28 | list_append(head, d); 29 | // list: 1 2 3 4 5 30 | 31 | list_delete(head); // 2 3 4 5 32 | 33 | struct node *e = malloc(sizeof(struct node)); 34 | e->data = (int*)10; 35 | list_push(head, e); // 10 2 3 4 5 36 | 37 | // traverse the list 38 | node* tail = head->prev; 39 | node* cur = head; 40 | while (cur != tail) { 41 | printf("%d\n", (int)cur->data); 42 | cur = cur->next; 43 | } 44 | printf("%d\n", (int)cur->data); 45 | 46 | printf("the list is empty? %d\n", list_empty(head)); 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /tut/tut7/list-example/tasks.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/tut7/list-example/tasks.o -------------------------------------------------------------------------------- /tut/tut7/q2.c: -------------------------------------------------------------------------------- 1 | // 2 | // Question 3 - Declarations, definitions and linkages 3 | // 4 | 5 | // 6 | // Part 1 7 | // 8 | 9 | // definition 10 | int x; 11 | 12 | // declaration 13 | extern int y; 14 | 15 | // definition 16 | static int z; 17 | 18 | // declaration 19 | int add(int a, int b); 20 | 21 | // declaration 22 | extern int multiply(int a, int b); 23 | 24 | // definition 25 | int add(int a, int b) { 26 | return a + b; 27 | } 28 | 29 | // declaration 30 | static int subtract(int a, int b); 31 | 32 | // definition 33 | static int subtract(int a, int b) { 34 | return a - b; 35 | } 36 | 37 | // definition 38 | int main(void) { 39 | return 0; 40 | } 41 | 42 | // 43 | // Part 2 44 | // 45 | 46 | // external linkage 47 | extern int y; 48 | 49 | // internal linkage 50 | int add(int a, int b); 51 | 52 | // since add is defined later in the current translation unit 53 | // although linkage is internal it is also accessible externally 54 | 55 | // external linkage 56 | extern int multiply(int a, int b); 57 | 58 | // internal linkage 59 | static int subtract(int a, int b); 60 | 61 | // the static keyword means the function must 62 | // be defined in the current translation unit 63 | 64 | // 65 | // Part 3 66 | // 67 | 68 | // global variables are accessible by default 69 | int x; 70 | 71 | int add(int a, int b); 72 | int main(void); 73 | 74 | // 75 | // Part 4 76 | // 77 | 78 | // If the linker cannot find a function that has external linkage then 79 | // your code will compile successfully to object files, however you will 80 | // get a link error when you attempt to merge the object files together. 81 | 82 | // 83 | // Part 5 84 | // 85 | 86 | // Advantages of definitions in headers: 87 | // - Useful when the code is small 88 | // - Code is inlined into where it is used 89 | // - Avoids the need to link to an object file 90 | 91 | // Advantages of definitions in source files: 92 | // - Neater code base 93 | -------------------------------------------------------------------------------- /tut/tut7/q3/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/tut7/q3/.DS_Store -------------------------------------------------------------------------------- /tut/tut7/q3/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | FLAGS=-Wall -Werror -g 3 | DEBUG=-fsanitize=address 4 | 5 | TARGET=tasks 6 | 7 | .PHONY: clean 8 | 9 | clean: 10 | rm -f *.o 11 | rm -f $(TARGET) 12 | rm -f debug 13 | rm -f test 14 | 15 | all: $(TARGET) 16 | 17 | main.o: main.c 18 | $(CC) -c $(FLAGS) $^ -o $@ 19 | 20 | stack.o: stack.c 21 | $(CC) -c $(FLAGS) $^ -o $@ 22 | 23 | tasks: main.o stack.o 24 | $(CC) $(FLAGS) $(LDFLAGS) $^ -o $@ 25 | 26 | debug: main.c stack.c 27 | $(CC) $(FLAGS) $(DEBUG) $^ -o $@ 28 | 29 | test: stack.c test.c 30 | $(CC) $(FLAGS) $(LDFLAGS) $^ -o $@ 31 | ./$@ all 32 | -------------------------------------------------------------------------------- /tut/tut7/q3/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define DEFAULT_TEST (10) 6 | 7 | #include "stack.h" 8 | 9 | int main(int argc, char** argv) { 10 | int n = DEFAULT_TEST; 11 | if(argc > 1) { 12 | // strtol(const char* restrict str, char** restrict endptr, int base) 13 | n = strtol(argv[1], NULL, 10); 14 | } 15 | 16 | stack* s = stack_alloc(); 17 | 18 | for(int i = 0; i < n; i++) { 19 | #if DEBUG 20 | printf("Pushing %d\n", i); 21 | #endif 22 | push(s, i); 23 | } 24 | 25 | for(int i = 0; i < n; i++) { 26 | s_result res = pop(s); 27 | if(!res.failed) { 28 | #if DEBUG 29 | printf("Value: %d\n", res.val); 30 | #endif 31 | } else { 32 | fprintf(stderr, "No element returned\n"); 33 | } 34 | } 35 | 36 | printf("runnning\n"); 37 | 38 | stack_free(s); 39 | } 40 | -------------------------------------------------------------------------------- /tut/tut7/q3/stack.c: -------------------------------------------------------------------------------- 1 | #include "stack.h" 2 | #include 3 | 4 | stack* stack_alloc() { 5 | return (stack*) calloc(sizeof(stack), STACK_INIT_SIZE); 6 | } 7 | 8 | void stack_free(stack* s) { 9 | if(s != NULL) { 10 | s_node* t = s->top; 11 | s_node* n = NULL; 12 | while(t != NULL) { 13 | n = t->next; 14 | free(t); 15 | t = n; 16 | } 17 | free(s); 18 | } 19 | } 20 | 21 | s_node* stack_s_node_alloc() { 22 | return (s_node*) calloc(sizeof(s_node), STACK_NODE_INIT_SIZE); 23 | } 24 | 25 | void stack_s_node_free(s_node* n) { 26 | free(n); 27 | } 28 | 29 | void push(stack* s, int v) { 30 | s_node* n = NULL; 31 | if(s != NULL) { 32 | if(s->top == NULL) { 33 | n = stack_s_node_alloc(); 34 | n->val = v; 35 | s->top = n; 36 | } else { 37 | s_node* s_tmp = s->top; 38 | n = stack_s_node_alloc(); 39 | n->next = s_tmp; 40 | n->val = v; 41 | s->top = n; 42 | } 43 | } 44 | } 45 | 46 | s_result pop(stack* s) { 47 | s_result ret = { 0, 0 }; 48 | s_node* t = s->top; 49 | if(t != NULL) { 50 | ret.val = t->val; 51 | s->top = s->top->next; 52 | stack_s_node_free(t); 53 | } else { 54 | ret.failed = 1; 55 | } 56 | return ret; 57 | } 58 | 59 | s_result peek(stack* s) { 60 | s_result ret = { 0, 0 }; 61 | s_node* t = s->top; 62 | if(t != NULL) { 63 | ret.val = t->val; 64 | } else { 65 | ret.failed = 1; 66 | } 67 | return ret; 68 | } 69 | -------------------------------------------------------------------------------- /tut/tut7/q3/stack.h: -------------------------------------------------------------------------------- 1 | #ifndef STACK_H 2 | #define STACK_H 3 | 4 | #include 5 | 6 | #define STACK_INIT_SIZE (1) 7 | #define STACK_NODE_INIT_SIZE (1) 8 | 9 | typedef struct s_node s_node; 10 | typedef struct stack stack; 11 | typedef struct s_result s_result; 12 | 13 | struct s_node { 14 | int val; 15 | s_node* next; 16 | }; 17 | 18 | struct stack { 19 | s_node* top; 20 | size_t size; 21 | }; 22 | 23 | struct s_result { 24 | int val; 25 | int failed; 26 | }; 27 | 28 | stack* stack_alloc(); 29 | s_node* stack_s_node_alloc(); 30 | 31 | void push(stack* s, int v); 32 | s_result pop(stack* s); 33 | s_result peek(stack* s); 34 | 35 | void stack_free(stack* s); 36 | void stack_s_node_free(s_node* n); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /tut/tut7/q3/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "stack.h" 8 | 9 | stack* s; 10 | s_result res; 11 | size_t size; 12 | 13 | struct testcase { 14 | char* name; 15 | int (*fn)(); 16 | }; 17 | 18 | int test_initialised() { 19 | s = stack_alloc(); 20 | return true; 21 | } 22 | 23 | int test_add() { 24 | push(s, 5); 25 | return true; 26 | } 27 | 28 | int test_pop() { 29 | res = pop(s); 30 | if (!res.failed) { 31 | return true; 32 | } else { 33 | return false; 34 | } 35 | } 36 | 37 | int test_retrieve() { 38 | size = s->size; 39 | return true; 40 | } 41 | 42 | int test_deallocated() { 43 | stack_free(s); 44 | return true; 45 | } 46 | 47 | int test_null() { 48 | s = stack_alloc(); 49 | push(s, (int) NULL); 50 | return true; 51 | } 52 | 53 | struct testcase tests[] = { 54 | {.name = "test_initialised", .fn = test_initialised}, 55 | {.name = "test_add", .fn = test_add}, 56 | {.name = "test_pop", .fn = test_pop}, 57 | {.name = "test_deallocated", .fn = test_deallocated}, 58 | {.name = "test_retrieve", .fn = test_retrieve}, 59 | {.name = "test_null", .fn = test_null}, 60 | }; 61 | 62 | int main(int argc, char** argv) { 63 | if (argc >= 2) { 64 | size_t n_tests = sizeof(tests)/sizeof(struct testcase); 65 | 66 | // if the input is all 67 | if (strcmp("all", argv[1]) == 0) { 68 | for (int i = 0; i < n_tests; i++) { 69 | 70 | // if fn is exited in struct testcase 71 | if (tests[i].fn() != false) { 72 | fprintf(stdout, "%s Passed\n", tests[i].name); 73 | } else { 74 | fprintf(stdout, "%s Failed\n", tests[i].name); 75 | } 76 | } 77 | } else { 78 | for (int i = 0; i < n_tests; i++) { 79 | 80 | if (strcmp(tests[i].name, argv[1]) == 0) { 81 | 82 | // if fn is exited in struct testcase 83 | if (tests[i].fn() != false) { 84 | fprintf(stdout, "%s Passed\n", tests[i].name); 85 | } else { 86 | fprintf(stdout, "%s Failed\n", tests[i].name); 87 | } 88 | break; 89 | } 90 | } 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /tut/tut7/q5/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/tut7/q5/.DS_Store -------------------------------------------------------------------------------- /tut/tut7/q5/rbuf.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "rbuf.h" 4 | 5 | rbuf_queue* rbuf_new(size_t cap) { 6 | rbuf_queue* q = malloc(sizeof(rbuf_queue)); 7 | q->cursor = 0; 8 | q->capacity = cap; 9 | q->size = 0; 10 | q->elements = malloc(sizeof(void*)*cap); 11 | return q; 12 | } 13 | 14 | void rbuf_enqueue(rbuf_queue* q, void* element) { 15 | if(q->size >= q->capacity) { 16 | //Resize 17 | q->elements = realloc(q->elements, sizeof(void*)*q->capacity*2); 18 | q->capacity = q->capacity * 2; 19 | } 20 | q->elements[(q->cursor+q->size)%q->capacity] = element; 21 | q->size++; 22 | } 23 | 24 | void* rbuf_deque(rbuf_queue* q) { 25 | void* element = q->elements[q->cursor]; 26 | q->cursor = (q->cursor+1) % q->capacity; 27 | return element; 28 | } 29 | 30 | void rbuf_delete(rbuf_queue* q, void(*cleanup(rbuf_queue*))) { 31 | if (cleanup != NULL) { 32 | cleanup(q); 33 | } 34 | free(q->elements); 35 | free(q); 36 | } 37 | 38 | int main() { 39 | rbuf_queue* q = rbuf_new(10); 40 | 41 | rbuf_enqueue(q, "1"); 42 | rbuf_enqueue(q, "2"); 43 | rbuf_enqueue(q, "3"); 44 | rbuf_enqueue(q, "4"); 45 | 46 | char* e = rbuf_deque(q); // 1 47 | printf("%s\n", e); 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /tut/tut7/q5/rbuf.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef struct rbuf_queue rbuf_queue; 4 | 5 | struct rbuf_queue { 6 | size_t capacity; 7 | size_t size; 8 | size_t cursor; 9 | void** elements; 10 | }; 11 | 12 | rbuf_queue* rbuf_new(size_t cap); 13 | 14 | void rbuf_enqueue(rbuf_queue* q, void* element); 15 | 16 | void* rbuf_deque(rbuf_queue* q); 17 | 18 | void rbuf_delete(rbuf_queue* q, void(*cleanup(rbuf_queue*))); 19 | -------------------------------------------------------------------------------- /tut/tut7/q6/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/tut7/q6/.DS_Store -------------------------------------------------------------------------------- /tut/tut7/q6/key_value.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "key_value.h" 6 | 7 | static KeyValue *key_values = NULL; 8 | static unsigned int number_of_key_values = 0; 9 | 10 | void set_key_values(KeyValue * const new_key_values, 11 | const unsigned int new_number_of_key_values) { 12 | key_values = new_key_values; 13 | number_of_key_values = new_number_of_key_values; 14 | } 15 | 16 | /* Compare two key members of KeyValue structures. */ 17 | static int key_value_compare_keys(const void *a, const void *b) { 18 | return (int)((KeyValue*)a)->key - (int)((KeyValue*)b)->key; 19 | } 20 | 21 | /* Search an array of key value pairs for the item with the specified value. */ 22 | KeyValue* find_item_by_value(const char * const value) { 23 | unsigned int i; 24 | for (i = 0; i < number_of_key_values; i++) { 25 | if (strcmp(key_values[i].value, value) == 0) { 26 | return &key_values[i]; 27 | } 28 | } 29 | return NULL; 30 | } 31 | 32 | /* Sort an array of key value pairs by key. */ 33 | void sort_items_by_key(void) { 34 | qsort(key_values, number_of_key_values, sizeof(*key_values), 35 | key_value_compare_keys); 36 | } 37 | -------------------------------------------------------------------------------- /tut/tut7/q6/key_value.h: -------------------------------------------------------------------------------- 1 | typedef struct KeyValue { 2 | unsigned int key; 3 | const char* value; 4 | } KeyValue; 5 | 6 | void set_key_values(KeyValue * const new_key_values, 7 | const unsigned int new_number_of_key_values); 8 | 9 | KeyValue* find_item_by_value(const char * const value); 10 | 11 | void sort_items_by_key(void); 12 | -------------------------------------------------------------------------------- /tut/tut7/q6/key_value_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "cmocka.h" 6 | 7 | #include "key_value.h" 8 | 9 | static KeyValue key_values[] = { 10 | { 10, "this" }, 11 | { 52, "test" }, 12 | { 20, "a" }, 13 | { 13, "is" }, 14 | }; 15 | 16 | static int create_key_values(void **state) { 17 | KeyValue * const items = (KeyValue*)test_malloc(sizeof(key_values)); 18 | memcpy(items, key_values, sizeof(key_values)); 19 | *state = (void*)items; 20 | set_key_values(items, sizeof(key_values) / sizeof(key_values[0])); 21 | 22 | return 0; 23 | } 24 | 25 | static int destroy_key_values(void **state) { 26 | test_free(*state); 27 | set_key_values(NULL, 0); 28 | 29 | return 0; 30 | } 31 | 32 | static void test_find_item_by_value(void **state) { 33 | unsigned int i; 34 | 35 | (void) state; /* unused */ 36 | 37 | for (i = 0; i < sizeof(key_values) / sizeof(key_values[0]); i++) { 38 | KeyValue * const found = find_item_by_value(key_values[i].value); 39 | assert_true(found != NULL); 40 | assert_int_equal(found->key, key_values[i].key); 41 | assert_string_equal(found->value, key_values[i].value); 42 | } 43 | } 44 | 45 | static void test_sort_items_by_key(void **state) { 46 | unsigned int i; 47 | KeyValue * const kv = *state; 48 | sort_items_by_key(); 49 | for (i = 1; i < sizeof(key_values) / sizeof(key_values[0]); i++) { 50 | assert_true(kv[i - 1].key < kv[i].key); 51 | } 52 | } 53 | 54 | int main(void) { 55 | const struct CMUnitTest tests[] = { 56 | cmocka_unit_test_setup_teardown(test_find_item_by_value, 57 | create_key_values, destroy_key_values), 58 | cmocka_unit_test_setup_teardown(test_sort_items_by_key, 59 | create_key_values, destroy_key_values), 60 | }; 61 | return cmocka_run_group_tests(tests, NULL, NULL); 62 | } 63 | -------------------------------------------------------------------------------- /tut/tut7/q6/libcmocka-static.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/tut7/q6/libcmocka-static.a -------------------------------------------------------------------------------- /tut/tut7/q7/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/tut7/q7/.DS_Store -------------------------------------------------------------------------------- /tut/tut7/q7/librbuf.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/tut7/q7/librbuf.a -------------------------------------------------------------------------------- /tut/tut7/q7/rbuf.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "rbuf.h" 4 | 5 | rbuf_queue* rbuf_new(size_t cap) { 6 | rbuf_queue* q = malloc(sizeof(rbuf_queue)); 7 | q->cursor = 0; 8 | q->capacity = cap; 9 | q->size = 0; 10 | q->elements = malloc(sizeof(void*)*cap); 11 | return q; 12 | } 13 | 14 | void rbuf_enqueue(rbuf_queue* q, void* element) { 15 | if(q->size >= q->capacity) { 16 | //Resize 17 | q->elements = realloc(q->elements, sizeof(void*)*q->capacity*2); 18 | q->capacity = q->capacity * 2; 19 | } 20 | q->elements[(q->cursor+q->size)%q->capacity] = element; 21 | q->size++; 22 | } 23 | 24 | void* rbuf_deque(rbuf_queue* q) { 25 | void* element = q->elements[q->cursor]; 26 | q->cursor = (q->cursor+1) % q->capacity; 27 | return element; 28 | } 29 | 30 | void rbuf_delete(rbuf_queue* q, void(*cleanup(rbuf_queue*))) { 31 | if (cleanup != NULL) { 32 | cleanup(q); 33 | } 34 | free(q->elements); 35 | free(q); 36 | } 37 | -------------------------------------------------------------------------------- /tut/tut7/q7/rbuf.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef struct rbuf_queue rbuf_queue; 4 | 5 | struct rbuf_queue { 6 | size_t capacity; 7 | size_t size; 8 | size_t cursor; 9 | void** elements; 10 | }; 11 | 12 | rbuf_queue* rbuf_new(size_t cap); 13 | 14 | void rbuf_enqueue(rbuf_queue* q, void* element); 15 | 16 | void* rbuf_deque(rbuf_queue* q); 17 | 18 | void rbuf_delete(rbuf_queue* q, void(*cleanup(rbuf_queue*))); 19 | -------------------------------------------------------------------------------- /tut/tut7/q7/rbuf.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/tut7/q7/rbuf.o -------------------------------------------------------------------------------- /tut/tut7/q7/shared_library.sh: -------------------------------------------------------------------------------- 1 | gcc -c rbuf.c -o rbuf.o 2 | ar rcs librbuf.a rbuf.o 3 | gcc test.c -L./ -lrbuf -o rbuf_test 4 | 5 | #-L allows for specification of library directory, -l is the linker command, 6 | #Once constructed we can cutout the -lib- component and specify the component afterwards 7 | -------------------------------------------------------------------------------- /tut/tut7/q7/test.c: -------------------------------------------------------------------------------- 1 | #include "rbuf.h" 2 | 3 | int main() { 4 | int* n = malloc(sizeof(int)); 5 | *n = 5; 6 | rbuf_queue* q = rbuf_new(10); 7 | rbuf_enqueue(q, n); 8 | int* p = rbuf_deque(q); 9 | rbuf_delete(q, NULL); 10 | free(n); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /tut/tut8/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phoebezuo/COMP2017-Study-Notes/cb08c09cc397ea5f67a674ccb33275121ebbd079/tut/tut8/.DS_Store -------------------------------------------------------------------------------- /tut/tut8/q1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(void) { 7 | int n = 4; 8 | puts("about to fork"); 9 | pid_t pid = fork(); 10 | if (pid < 0) { 11 | perror("unable to fork"); 12 | return 1; 13 | } 14 | if (pid == 0) { 15 | puts("child"); 16 | n++; 17 | sleep(1); 18 | } else { 19 | puts("parent"); 20 | n *= 2; 21 | wait(NULL); 22 | } 23 | printf("fork returned %d, n is %d\n", pid, n); 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /tut/tut8/q2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | volatile sig_atomic_t amazing = 0; 7 | volatile sig_atomic_t outside = 0; 8 | 9 | void parent_int(int signo) {} 10 | 11 | void child_int(int signo) { amazing = 1; } 12 | 13 | void child_hup(int signo) { outside = 1; } 14 | 15 | int main() { 16 | pid_t parent = getpid(); 17 | pid_t pid = fork(); 18 | 19 | if(pid > 0) { //Parent 20 | pause(); 21 | kill(pid, SIGINT); 22 | sleep(1); //Just to delay the next signal 23 | kill(pid, SIGHUP); 24 | } else if(pid == 0) { 25 | kill(parent, SIGINT); 26 | while(1) { 27 | pause(); 28 | if(amazing) { 29 | amazing = 0; //reset 30 | printf("I'm Amazing!\n"); 31 | } else if(outside) { 32 | printf("I'm going to go play outside!\n"); 33 | break; 34 | } 35 | } 36 | } else { 37 | printf("It failed!\n"); 38 | } 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /tut/tut8/q3.c: -------------------------------------------------------------------------------- 1 | f#include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define BUF_SIZE (1024) 8 | #define ARG_SIZE (512) 9 | #define BIN_PATH "/bin/" 10 | 11 | int main() { 12 | char arg0[ARG_SIZE]; 13 | char arg1[ARG_SIZE]; 14 | char buf[BUF_SIZE]; 15 | char* n_check = NULL; 16 | while(1) { 17 | printf("> "); 18 | n_check = fgets(buf, BUF_SIZE, stdin); 19 | sscanf(buf, "%s %s", arg0, arg1); 20 | // int sscanf(const char *restrict s, const char *restrict format, ...); 21 | 22 | if(strcmp(arg0, "exit") == 0) { break; } 23 | 24 | if(n_check != NULL) { 25 | pid_t pid = fork(); 26 | if(pid == 0) { 27 | snprintf(buf, BUF_SIZE, BIN_PATH"%s", arg0); 28 | // int sprintf(char *restrict str, const char *restrict format, ...); 29 | execl(buf, arg0, arg1, NULL); 30 | return 0; 31 | } 32 | } 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /tut/tut8/q4.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define BUF_SIZE (1024) 10 | #define ARG_SIZE (512) 11 | #define BIN_PATH "/bin/" 12 | 13 | #define PID_LIST_SIZE (1024) 14 | 15 | void shift_down(pid_t* pids, size_t sz, size_t idx) { 16 | for(size_t i = idx; i < sz-1; i++) { 17 | pids[i] = pids[i+1]; 18 | } 19 | } 20 | 21 | int main() { 22 | char arg0[ARG_SIZE]; 23 | char arg1[ARG_SIZE]; 24 | char buf[BUF_SIZE]; 25 | char* n_check = NULL; 26 | pid_t pids[PID_LIST_SIZE]; 27 | size_t n_procs = 0; 28 | 29 | while (1) { 30 | printf("> "); 31 | n_check = fgets(buf, BUF_SIZE, stdin); 32 | sscanf(buf, "%s %s", arg0, arg1); 33 | 34 | for (size_t i = 0; i < PID_LIST_SIZE; i++) { 35 | int status = 0; 36 | if (waitpid(pids[i], &status, WNOHANG) == -1) { 37 | shift_down(pids, PID_LIST_SIZE, i); 38 | } 39 | 40 | if (WIFEXITED(status)) { 41 | shift_down(pids, PID_LIST_SIZE, i); 42 | } 43 | } 44 | 45 | if(strcmp(arg0, "exit") == 0) { break; } 46 | 47 | if (n_check != NULL) { 48 | pid_t pid = fork(); 49 | if (pid == 0) { 50 | snprintf(buf, BUF_SIZE, BIN_PATH"%s", arg0); 51 | execl(buf, arg0, arg1, NULL); 52 | return 0; 53 | } 54 | } 55 | } 56 | } 57 | 58 | -------------------------------------------------------------------------------- /tut/tut8/q5.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(int argc, char** argv) { 7 | 8 | if(argc > 1) { 9 | //quick and dirty method of parsing the arguments 10 | char* cmd_ptr = (strstr(argv[1], "=")+1); 11 | 12 | char buf[1024]; 13 | FILE* output_file = stdout; 14 | FILE* f = popen(cmd_ptr, "r"); 15 | if (argc > 2){ 16 | char* out_ptr = (strstr(argv[2], "=")+1); 17 | output_file = fopen(out_ptr, "w"); 18 | } 19 | printf(":::Process Logger Started:::"); 20 | //Reading the output of the process running 21 | size_t bytes = 0; 22 | while ((bytes = fread(buf, sizeof(char), 1024, f)) > 0) { 23 | fwrite(buf, sizeof(char), bytes, output_file); 24 | } 25 | if (argc > 2){ 26 | fclose(output_file); 27 | } 28 | printf(":::Process Logger Ended:::\n"); 29 | pclose(f); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /tut/tut8/say_hello_100.py: -------------------------------------------------------------------------------- 1 | print("hello\n" * 100) -------------------------------------------------------------------------------- /tut/tut8/test.out: -------------------------------------------------------------------------------- 1 | hello 2 | hello 3 | hello 4 | hello 5 | hello 6 | hello 7 | hello 8 | hello 9 | hello 10 | hello 11 | hello 12 | hello 13 | hello 14 | hello 15 | hello 16 | hello 17 | hello 18 | hello 19 | hello 20 | hello 21 | hello 22 | hello 23 | hello 24 | hello 25 | hello 26 | hello 27 | hello 28 | hello 29 | hello 30 | hello 31 | hello 32 | hello 33 | hello 34 | hello 35 | hello 36 | hello 37 | hello 38 | hello 39 | hello 40 | hello 41 | hello 42 | hello 43 | hello 44 | hello 45 | hello 46 | hello 47 | hello 48 | hello 49 | hello 50 | hello 51 | hello 52 | hello 53 | hello 54 | hello 55 | hello 56 | hello 57 | hello 58 | hello 59 | hello 60 | hello 61 | hello 62 | hello 63 | hello 64 | hello 65 | hello 66 | hello 67 | hello 68 | hello 69 | hello 70 | hello 71 | hello 72 | hello 73 | hello 74 | hello 75 | hello 76 | hello 77 | hello 78 | hello 79 | hello 80 | hello 81 | hello 82 | hello 83 | hello 84 | hello 85 | hello 86 | hello 87 | hello 88 | hello 89 | hello 90 | hello 91 | hello 92 | hello 93 | hello 94 | hello 95 | hello 96 | hello 97 | hello 98 | hello 99 | hello 100 | hello 101 | 102 | -------------------------------------------------------------------------------- /tut/tut9/fseek-with-files.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define SOME_DATA (24) 10 | 11 | int main(int argc, char ** argv) { 12 | if(argc != 2) { 13 | //Need two arguments 14 | return 1; 15 | } 16 | 17 | FILE* fp = fopen(argv[1], "r"); 18 | struct stat stat_b; 19 | 20 | if(stat(argv[1], &stat_b) == -1) { 21 | perror("connot get file size\n"); 22 | fclose(fp); 23 | return 1; 24 | } 25 | 26 | //Read some bytes 27 | for(size_t i = 0; i < SOME_DATA; i++) { 28 | fseek(fp, i, SEEK_SET); 29 | printf("%c", fgetc(fp)); 30 | } 31 | printf("\njob finish\n"); 32 | 33 | fclose(fp); 34 | } -------------------------------------------------------------------------------- /tut/tut9/mkfifo.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define BUF_SZ (256) 8 | #define CHANNEL_NAME ("comm"); 9 | 10 | int main() { 11 | if((mkfifo(CHANNEL_NAME, S_IRWXU | S_IRWXG)) >= 0) { 12 | int fd = open(CHANNEL_NAME, O_RDONLY); // read only 13 | if(fd > 0) { 14 | FILE* read_channel = fdopen(fd, "r"); 15 | char buf[BUF_SZ]; 16 | while(fgets(buf, BUF_SZ, read_channel) != NULL) { 17 | puts(buf); 18 | } 19 | fclose(read_channel); 20 | } 21 | 22 | } else { 23 | fprintf(stderr, "Unable to open pipe"); 24 | } 25 | return 0; 26 | } -------------------------------------------------------------------------------- /tut/tut9/mmap-with-files.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define SOME_DATA (24) 10 | 11 | int main(int argc, char ** argv) { 12 | if(argc != 2) { 13 | //Need two arguments 14 | return 1; 15 | } 16 | 17 | char * block = NULL; 18 | int fd = open(argv[1], O_RDONLY); 19 | struct stat stat_b; 20 | 21 | // int fstat(int fildes, struct stat *buf); 22 | fstat(fd, &stat_b); 23 | 24 | // void* mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset); 25 | block = mmap(NULL, stat_b.st_size, PROT_WRITE|PROT_READ, MAP_PRIVATE, fd, 0); 26 | 27 | if(block == MAP_FAILED) { 28 | perror("MMAP Failed"); 29 | close(fd); 30 | return 1; 31 | } 32 | 33 | //Read some bytes 34 | for(size_t i = 0; i < SOME_DATA; i++) { 35 | printf("%c", block[i]); 36 | } 37 | printf("\njob finish\n"); 38 | 39 | // int munmap(void *addr, size_t len); 40 | munmap(block, stat_b.st_size); 41 | close(fd); 42 | } -------------------------------------------------------------------------------- /tut/tut9/q1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int main() { 8 | int pipefd[2]; 9 | pipe(pipefd); 10 | 11 | pid_t pid = fork(); 12 | 13 | if (pid == 0) { 14 | // child read message from parent 15 | char buffer[50]; 16 | close(pipefd[1]); // write end of pipe 17 | int num_read = read(pipefd[0], buffer, 50); 18 | if (num_read < 0) { 19 | perror("error happened"); 20 | } 21 | close(pipefd[0]); // read end of pipe 22 | printf("Child: I will use the password %s\n", buffer); 23 | } else if (pid > 0) { 24 | // parent write to child 25 | close (pipefd[0]); // read end of pipe 26 | char* password = "\"grilledcheese\""; 27 | printf("Parent: The password is %s\n", password); 28 | write(pipefd[1], password, strlen(password)); 29 | close(pipefd[1]); 30 | wait(0); 31 | } else { 32 | perror("some error"); 33 | exit(1); 34 | } 35 | } -------------------------------------------------------------------------------- /tut/tut9/q2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int main() { 8 | int p2c_pipefd[2]; 9 | int c2p_pipefd[2]; 10 | 11 | if (pipe(p2c_pipefd) < 0 || pipe(c2p_pipefd)) { 12 | perror("Unable to create pipes"); 13 | } 14 | 15 | pid_t pid = fork(); 16 | 17 | if (pid < 0) { 18 | perror("Failed to fork"); 19 | } else if (pid == 0) { 20 | // child read message from parent 21 | close(p2c_pipefd[1]); // parent to child write 22 | close(c2p_pipefd[0]); // child to parent read 23 | 24 | char buf[10]; 25 | read(p2c_pipefd[0], buf, 9); 26 | 27 | printf(".....Message from parent: %s\n", buf); 28 | 29 | // retrive current tie set on computer 30 | sleep(1); 31 | time_t t; 32 | struct tm* tm_info = localtime(&t); // statically allocted memory 33 | char time_buf[256]; 34 | strftime(time_buf, 256, " %H:%M%p", tm_info); 35 | printf("Child: The time is %s!\n", time_buf); 36 | 37 | char* request = "DONE"; 38 | write(c2p_pipefd[1], request, strlen(request) + 1); 39 | 40 | close(p2c_pipefd[0]); // parent read 41 | close(c2p_pipefd[1]); // child write 42 | } else { 43 | // parent write to child 44 | close(p2c_pipefd[0]); // parent to child read 45 | close(c2p_pipefd[1]); // child to parent write 46 | 47 | printf("Parent: Hi! Do you know what time it is?\n"); 48 | 49 | char* request = "TIME"; 50 | write(p2c_pipefd[1], request, strlen(request) + 1); 51 | 52 | char buf[10]; 53 | read(c2p_pipefd[0], buf, 9); 54 | printf(".....Message from child: %s\n", buf); 55 | 56 | sleep(1); 57 | printf("Parent: Thank you!\n"); 58 | 59 | close(p2c_pipefd[1]); // parent to child write 60 | close(c2p_pipefd[0]); // child to parent read 61 | } 62 | } -------------------------------------------------------------------------------- /tut/tut9/q2_time.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define PARENT_MSG_1 ("Hi! Do you know what time it is?") 8 | #define CHILD_MSG_1 ("The time is 8:30 !") 9 | #define PARENT_MSG_2 ("Thank you!") 10 | 11 | #define PROMPT ("PROMPT!") 12 | 13 | int main() { 14 | 15 | 16 | int parent_to_child[2]; 17 | int child_to_parent[2]; 18 | pipe(parent_to_child); 19 | pipe(child_to_parent); 20 | pid_t pid = fork(); 21 | 22 | if(pid > 0) { 23 | printf("Parent: %s\n",PARENT_MSG_1); 24 | write(parent_to_child[1], PROMPT, strlen(PROMPT)+1); //Write first after 25 | 26 | } else if (pid == 0) { 27 | char buf[8];// WAIT AND READ 28 | read(parent_to_child[0], buf, 8); 29 | 30 | printf("Child: %s\n", CHILD_MSG_1); //Print and then write back 31 | write(child_to_parent[1], PROMPT, strlen(PROMPT)+1); 32 | 33 | } else { 34 | fprintf(stderr, "Something broke with fork!\n"); 35 | } 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /tut/tut9/q3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int main() { 8 | 9 | int fd[2]; 10 | pipe(fd); 11 | pid_t pid = fork(); 12 | 13 | if(pid == 0) { 14 | // child 15 | close(1); 16 | close(fd[0]); 17 | dup(fd[1]); //Gets set to stdout 18 | 19 | // int execlp(const char *file, const char *arg0, ... /*, (char *)0 */); 20 | execlp("/bin/ls", "ls", "-l", "./", NULL); // file descriptors are maintained 21 | } else if(pid > 0) { 22 | // parent 23 | FILE* f = fdopen(fd[0], "r"); 24 | char buf[1024]; 25 | int i = 1; 26 | while((fgets(buf, 1024, f)) != NULL) { 27 | printf("Line %d: %s", i, buf); 28 | i += 1; 29 | } 30 | } 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /tut/tut9/q4.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | #define MSG_LENGTH (1024) 12 | #define PARENT_MSG_1 ("Hi! Do you know what time it is?") 13 | #define CHILD_MSG_1 ("The time is 8:30 !") 14 | #define PARENT_MSG_2 ("Thank you!") 15 | 16 | void tell_me(int signo) { 17 | //NOOP Just helps move the pause() 18 | } 19 | 20 | int main() { 21 | signal(SIGINT, tell_me); 22 | char* shared = mmap(NULL, MSG_LENGTH*sizeof(char), PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0); 23 | strcpy(shared, PARENT_MSG_1); 24 | 25 | pid_t parent = getpid(); 26 | pid_t p = fork(); 27 | 28 | if(p == 0) { 29 | pause(); 30 | printf("Child: %s\n", shared); 31 | strcpy(shared, PARENT_MSG_2); 32 | kill(parent, SIGINT); 33 | munmap(shared, MSG_LENGTH * sizeof(int)); 34 | 35 | } else if(p > 0) { 36 | printf("Parent: %s\n", shared); 37 | strcpy(shared, CHILD_MSG_1); 38 | kill(p, SIGINT); // kill child process 39 | pause(); 40 | printf("Parent: %s\n", shared); 41 | munmap(shared, MSG_LENGTH * sizeof(int)); 42 | } 43 | 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /tut/tut9/share-between.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #define DATA_SIZE (6) 9 | 10 | int * give_data() { 11 | int* data = malloc(sizeof(int) * DATA_SIZE); 12 | for(int i = 0; i < DATA_SIZE; i++) { 13 | data[i] = i; 14 | } 15 | return data; 16 | } 17 | 18 | void read_share(int* d) { 19 | for(int i = 0; i < DATA_SIZE; i++) { 20 | printf("%d\n", d[i]); 21 | } 22 | } 23 | 24 | int main() { 25 | int* d = give_data(); 26 | int* shared = mmap(NULL, DATA_SIZE * sizeof(int), PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0); 27 | memcpy(shared, d, DATA_SIZE * sizeof(int)); 28 | free(d); 29 | pid_t p = fork(); 30 | 31 | if(p == 0) { 32 | printf("Child\n"); 33 | read_share(shared); 34 | for(int i = 0; i < DATA_SIZE; i++) { 35 | shared[i] = i + 10; 36 | } 37 | munmap(shared, DATA_SIZE * sizeof(int)); 38 | } else if(p > 0) { 39 | sleep(2); 40 | printf("Parent\n"); 41 | read_share(shared); 42 | munmap(shared, DATA_SIZE * sizeof(int)); 43 | } 44 | return 0; 45 | } --------------------------------------------------------------------------------