From b0caf2463ec27213b4b66d81252f36ac1a8c3c0a Mon Sep 17 00:00:00 2001 From: Joshua Powers Date: Wed, 14 Sep 2022 10:34:38 -0500 Subject: [PATCH] stuff --- Examples/a.out | Bin 49536 -> 0 bytes Examples/ipc/Makefile | 13 +++++++ Examples/ipc/README.md | 35 +++++++++++++++++ Examples/ipc/ipcfs1.c | 54 ++++++++++++++++++++++++++ Examples/ipc/ipcfs2.c | 59 +++++++++++++++++++++++++++++ Examples/ipc/ipcmsg1.c | 71 +++++++++++++++++++++++++++++++++++ Examples/ipc/ipcmsg2.c | 74 ++++++++++++++++++++++++++++++++++++ Examples/ipc/ipcpipe1.c | 58 ++++++++++++++++++++++++++++ Examples/ipc/ipcpipe2.c | 75 +++++++++++++++++++++++++++++++++++++ Examples/ipc/ipcshm1.c | 74 ++++++++++++++++++++++++++++++++++++ Examples/ipc/ipcshm2.c | 79 +++++++++++++++++++++++++++++++++++++++ Examples/ipc/ipcsignal.c | 46 +++++++++++++++++++++++ Examples/ipc/signal1.c | 29 ++++++++++++++ Examples/ipc/signal2.c | 29 ++++++++++++++ 14 files changed, 696 insertions(+) delete mode 100755 Examples/a.out create mode 100644 Examples/ipc/Makefile create mode 100644 Examples/ipc/README.md create mode 100644 Examples/ipc/ipcfs1.c create mode 100644 Examples/ipc/ipcfs2.c create mode 100644 Examples/ipc/ipcmsg1.c create mode 100644 Examples/ipc/ipcmsg2.c create mode 100644 Examples/ipc/ipcpipe1.c create mode 100644 Examples/ipc/ipcpipe2.c create mode 100644 Examples/ipc/ipcshm1.c create mode 100644 Examples/ipc/ipcshm2.c create mode 100644 Examples/ipc/ipcsignal.c create mode 100644 Examples/ipc/signal1.c create mode 100644 Examples/ipc/signal2.c diff --git a/Examples/a.out b/Examples/a.out deleted file mode 100755 index 42b3d696664da28aef340837a689930be0c29dc4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49536 zcmeI*PiP!f9Ki9HCTX`?YU)7}|8=P*M5T#}g&-sz>fIl%i1O%yR9J6!IN|Eql2=~#>N1zCw-DBw2-j<_?ptxk{uUd} zx?epLE=bn97}gsL&ubo!p4xK4+E(>_zgo0@b*UEQz0c#Tu%1414b77^+!=S&=lY2> zYiDQXXY327PR_Zfn{jT@b4>R7ebc7TO22c~o~gwi>wnfu$=VaX>p(0xq> z-#6V?G%I~Ou`kJk$ha=rS5(W|a^5ypDur6vE;sApzTDd2*mm`XqbbRwYjsL~TRq=D zYm512UeCC2Zc%2;aNE_3?o;!4z3r85WbIbZDq|K3j= zKlw^__IUJL?IheJ*Jy_Yw2Rj|B&VL%1s!AbUQ*I;8A+a&d|djR^i$I7p7i`jlI!~M z?~PfI{$6RPrD;T;p&oia@q5zq@kq(_YM+e#GLe?HPugUwQJ*aPg~{SdxhT2DL(+5~ zPt{-k;>)$^cQ1c^>CjtOu3daq=F-x155d*_`+~81Hn(>@DYN=LjzaFOt#$P8PdxN< zr=;mQz32YoLHYC6x4jqH&)iC*=~X6w5N=GLb_)8YD&pSs=d z6|?z9kWGK=CP!wBk;!A4U25s-4`e7a`u?h9=Yy_wOJ*Jo)?B!`xmO0ybaJad4!!-u zMtAg^j4|EOZ-e7iIT~|f{gLlvFf-R3{Z!J8l1|?ELq5NxuYlh8O-B#v=ocA{Rq}o{ zJ)It1zQ>ID;ozNU;%qq3cTXRdrV;P;JyLzo^f~FZ={xEgI@b47^-a~G@Xb|8-7Bmz zAP_(R0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I|sO2$aJA_g)YC^I^X;cE>IdKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#~Ee+V3S%*^SX9>^3|%0=5~whFf3SBqZVyjnLKrXgqSQr+`( zoRV=RUoO`cH5-y_x$ak+OOlyBYX(ift(2^H&Rc9XJzMhfTITUe-mjW*-yGg0pVMzT z7tDb9yse3ZWI?aE?!RLa B9Q^ // needed for open system call +#include // needed for printf +#include // needed for exit +#include // nneded for strlen +#include // needed for pid_t +#include // needed for wait system call +#include // needed for fork, read, write, close system calls + +int main() +{ + // Open a file for reading and writing + // Create it if it doesn't exist + int myfile = open("MYFILE", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); + + pid_t pid = fork(); // fork into 2 processes + + if (pid < 0) // error + { + printf("ERROR: COULD NOT FORK\n"); + exit(EXIT_FAILURE); + } + else if (pid == 0) // child + { + /* Write to parent */ + char *data = "HELLO"; + write(myfile, data, strlen(data)); + printf("Child wrote %s\n", data); + + /* Close file */ + close(myfile); + + return 0; // Return success + } + else // parent + { + /* Wait for child */ + wait(0); + + /* Read data */ + char data[32]; + read(myfile, data, sizeof(data)); + printf("Parent received %s from child\n", data); + + /* Close file */ + close(myfile); + } + return 0; +} diff --git a/Examples/ipc/ipcfs2.c b/Examples/ipc/ipcfs2.c new file mode 100644 index 0000000..534f9ce --- /dev/null +++ b/Examples/ipc/ipcfs2.c @@ -0,0 +1,59 @@ +/* + * ipcsfs2 - Using the file system for inter-process communication + * Fixes the file position pointer problem in ipcfs1.c + * by using lseek to reset the pointer to the beginning + * Shows the frustration with using the file system for + * IPC by needing to move the file position pointer around + */ + +#include // needed for open system call +#include // needed for printf +#include // needed for exit +#include // nneded for strlen +#include // needed for pid_t +#include // needed for wait system call +#include // needed for fork, read, write, close system calls + +int main() +{ + // Open a file for reading and writing + // Create it if it doesn't exist + int myfile = open("MYFILE", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); + + pid_t pid = fork(); // fork into 2 processes + + if (pid < 0) // error + { + printf("ERROR: COULD NOT FORK\n"); + exit(EXIT_FAILURE); + } + else if (pid == 0) // child + { + /* Write to parent */ + char *data = "HELLO"; + write(myfile, data, strlen(data)); + printf("Child wrote %s\n", data); + + /* Close file */ + close(myfile); + + return 0; // Return success + } + else // parent + { + /* Wait for child */ + wait(0); + + /* Reset file position pointer */ + lseek(myfile, 0, SEEK_SET); + + /* Read data */ + char data[32]; + read(myfile, data, sizeof(data)); + printf("Parent received %s from child\n", data); + + /* Close file */ + close(myfile); + } + return 0; // Return success +} diff --git a/Examples/ipc/ipcmsg1.c b/Examples/ipc/ipcmsg1.c new file mode 100644 index 0000000..b3c918d --- /dev/null +++ b/Examples/ipc/ipcmsg1.c @@ -0,0 +1,71 @@ +/* + * ipcmsg1.c - Using a message queue to send data from + * a parent process to a child process + * NOTE: message queues are persistent + */ + +#include // needed for pid_t +#include // needed for wait system call +#include // needed for fork system call +#include // needed for exit +#include // needed for printf, perror +#include // needed for mq system calls +#include // needed for strcpy + +/* Struct for the queue message */ +typedef struct message { + int message_id; + char string[10]; +} message; + +int main() +{ + // Create attributes for new queue + struct mq_attr queue_attr; + queue_attr.mq_flags = 0; // Ignored by kernel + queue_attr.mq_maxmsg = 10; // Max messages the queue supports + queue_attr.mq_msgsize = sizeof(message); + queue_attr.mq_curmsgs = 0; // Not used + + // Create and open a queue + mqd_t mqdes = mq_open("/CS3841QUEUE", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR, &queue_attr); + if(mqdes == -1) { + printf("COULD NOT OPEN QUEUE\n"); + exit(EXIT_FAILURE); + } + + pid_t pid = fork(); // fork into 2 processes + + if(pid < 0) // error + { + perror("fork"); + exit(EXIT_FAILURE); + } + else if(pid == 0) // child + { + // Child receives message from parent + message from_parent; + mq_receive(mqdes, (char*)&from_parent, sizeof(message), NULL); + printf("Child got %d: %s from parent\n", from_parent.message_id, from_parent.string); + + // Close the queue + mq_close(mqdes); + + return 0; // Return success + } + else // parent + { + // Parent sends message to child + message to_child; + to_child.message_id = 10; + strcpy(to_child.string, "HELLO"); + mq_send(mqdes, (char*)&to_child, sizeof(message), 0); + + // Wait for child + wait(0); + + // Close the queue + mq_close(mqdes); + } + return 0; // Return success +} diff --git a/Examples/ipc/ipcmsg2.c b/Examples/ipc/ipcmsg2.c new file mode 100644 index 0000000..786793c --- /dev/null +++ b/Examples/ipc/ipcmsg2.c @@ -0,0 +1,74 @@ +/* + * ipcmsg2.c - Uses message queues to send multiple messages + * between two processes. Shows what can happen + * with blocking queues when the queue gets full + * NOTE: message queues are persistent + */ + +#include // needed for pid_t +#include // needed for wait system call +#include // needed for fork system call +#include // needed for exit +#include // needed for printf, perror +#include // needed for mq system calls +#include // needed for strcpy + +/* Struct for the queue message */ +typedef struct message { + int message_id; + char string[10]; +} message; + +int main() +{ + // Create attributes for new queue + struct mq_attr queue_attr; + queue_attr.mq_flags = 0; // Ignored by kernel + queue_attr.mq_maxmsg = 10; // Max messages the queue supports + queue_attr.mq_msgsize = sizeof(message); + queue_attr.mq_curmsgs = 0; // Not used + + // Create and open a queue + mqd_t mqdes = mq_open("/CS3841QUEUE", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR, &queue_attr); + if(mqdes == -1) { + printf("COULD NOT OPEN QUEUE\n"); + exit(EXIT_FAILURE); + } + + pid_t pid = fork(); // fork into 2 processes + + if(pid < 0) // error + { + perror("fork"); + exit(EXIT_FAILURE); + } + else if(pid == 0) // child + { + // Child receives message from parent + message from_parent; + mq_receive(mqdes, (char*)&from_parent, sizeof(message), NULL); + printf("Child got %d: %s from parent\n", from_parent.message_id, from_parent.string); + + // Close the queue + mq_close(mqdes); + + return 0; // Return success + } + else // parent + { + // Parent sends messages to child + message to_child; + for(int i = 0; i < 10; i++) { + to_child.message_id = i; + strcpy(to_child.string, "HELLO"); + mq_send(mqdes, (char*)&to_child, sizeof(message), 0); + } + + // Wait for child + wait(0); + + // Close the queue + mq_close(mqdes); + } + return 0; // Return success +} diff --git a/Examples/ipc/ipcpipe1.c b/Examples/ipc/ipcpipe1.c new file mode 100644 index 0000000..ae3c814 --- /dev/null +++ b/Examples/ipc/ipcpipe1.c @@ -0,0 +1,58 @@ +/* + * ipcpipe1.c - Using a pipe to communicate data from + * a child process to a parent process + */ + +#include // needed for pid_t +#include // needed for wait system call +#include // needed for fork, read, write, close system calls +#include // needed for exit +#include // needed for printf, perror + +int main() +{ + /* Create a pipe */ + int pipefd[2]; + if (pipe(pipefd) == -1) { + perror("pipe"); + exit(EXIT_FAILURE); + } + + pid_t pid = fork(); // fork into 2 processes + + if (pid == -1) // error + { + perror("fork"); + exit(EXIT_FAILURE); + } + else if (pid == 0) // child + { + /* Close unused write end */ + close(pipefd[1]); + + /* Read from parent */ + char data[32]; + read(pipefd[0], data, sizeof(data)); + printf("Child received %s from parent\n", data); + + /* Close pipe */ + close(pipefd[0]); + + return 0; // Return success + } + else // parent + { + /* Close unused read end */ + close(pipefd[0]); + + /* Write to child */ + write(pipefd[1], "HELLO", 5); + + /* Close pipe */ + close(pipefd[1]); + + /* Wait or child */ + wait(0); + } + return 0; // Return success +} diff --git a/Examples/ipc/ipcpipe2.c b/Examples/ipc/ipcpipe2.c new file mode 100644 index 0000000..a67c588 --- /dev/null +++ b/Examples/ipc/ipcpipe2.c @@ -0,0 +1,75 @@ +/* + * ipcpipe2.c - Pipes are unidirectional and require + * two pipes to send data in two directions + */ + +#include // needed for pid_t +#include // needed for wait system call +#include // needed for fork, read, write, close system calls +#include // needed for exit +#include // needed for printf, perror + +int main() +{ + /* Create pipes */ + int pipe_to_child[2]; + if (pipe(pipe_to_child) == -1) { + printf("PIPE FAILURE\n"); + exit(EXIT_FAILURE); + } + int pipe_from_child[2]; + if (pipe(pipe_from_child) == -1) { + printf("PIPE FAILURE\n"); + exit(EXIT_FAILURE); + } + + pid_t pid = fork(); // fork into 2 processes + + if (pid == -1) // error + { + perror("fork"); + exit(EXIT_FAILURE); + } + else if (pid == 0) // + { + /* Close unused pipe ends */ + close(pipe_to_child[1]); + close(pipe_from_child[0]); + + /* Write to parent */ + write(pipe_from_child[1], "CHELLO", 6); + close(pipe_from_child[1]); + + /* Read from parent */ + char data[32]; + read(pipe_to_child[0], data, sizeof(data)); + printf("Child received %s from parent\n", data); + + /* Close pipe */ + close(pipe_to_child[0]); + + return 0; // Return success + } + else // parent + { + /* Close unused pipe ends */ + close(pipe_to_child[0]); + close(pipe_from_child[1]); + + /* Write to child */ + write(pipe_to_child[1], "PHELLO", 6); + close(pipe_to_child[1]); + + /* Read from child */ + char data[32]; + read(pipe_from_child[0], data, sizeof(data)); + printf("Parent recieved %s from child\n", data); + + /* Close pipe */ + close(pipe_from_child[0]); + + /* Wait for child */ + wait(0); + } + return 0; // Return success +} diff --git a/Examples/ipc/ipcshm1.c b/Examples/ipc/ipcshm1.c new file mode 100644 index 0000000..53b1ddd --- /dev/null +++ b/Examples/ipc/ipcshm1.c @@ -0,0 +1,74 @@ +/* + * ipcshm1.c - Uses shared memory to send data from + * a child process to a parent process + * NOTE: named shared memory segments are persistent + */ + +#include // needed for pid_t +#include // needed for wait system call +#include // needed for parameter values for shm_open +#include // needed for fork, getpid, getppid, kill system calls +#include // needed for exit +#include // needed for signal system call +#include // needed for printf, perror +#include // needed for mmap, munmap, shm system calls +#include // needed for strcpy + +#define MAPPED_SIZE 128 + +int main() +{ + // Create and open a shared memory segment + int shmfd = shm_open("/CS3841MEMORY", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); + if(shmfd == -1) { + printf("COULD NOT OPEN SHARED MEMORY SEGMENT\n"); + exit(EXIT_FAILURE); + } + + // Set the size of the shared memory segment + ftruncate(shmfd, MAPPED_SIZE); + + // Map the segment into the processes address space + // NOTE: protection is set to allow reading and writing with a shared mapping + void* mapped_space = mmap(NULL, MAPPED_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0); + if(mapped_space == MAP_FAILED) { + printf("COULD NOT MMAP\n"); + exit(EXIT_FAILURE); + } + + pid_t pid = fork(); // fork into 2 processes + + if(pid < 0) // error + { + perror("fork"); + exit(EXIT_FAILURE); + } + else if(pid == 0) // child + { + // Child writes to shared memory segment + strcpy(mapped_space, "HELLO"); + + // Unmap the shared memory + munmap(mapped_space, MAPPED_SIZE); + + // Close the shared memory segment + close(shmfd); + + return 0; // Return success + } + else // parent + { + // Wait for child to finish + wait(0); + + // Parent reads from shared memory segment + printf("Parent reads %s from shared mapped segment\n", (char*)mapped_space); + + // Unmap the shared memory + munmap(mapped_space, MAPPED_SIZE); + + // Close the shared memory segment + close(shmfd); + } + return 0; // Return success +} diff --git a/Examples/ipc/ipcshm2.c b/Examples/ipc/ipcshm2.c new file mode 100644 index 0000000..67ca5c7 --- /dev/null +++ b/Examples/ipc/ipcshm2.c @@ -0,0 +1,79 @@ +/* + * ipcshm2.c - Uses shared memory to send data from + * a child process to a parent process + * Uses shm_unlink to remove the shared memory when done + * NOTE: named shared memory segments are persistent + */ + +#include // needed for pid_t +#include // needed for wait system call +#include // needed for parameter values for shm_open +#include // needed for fork, getpid, getppid, kill system calls +#include // needed for exit +#include // needed for signal system call +#include // needed for printf, perror +#include // needed for mmap, munmap, shm system calls +#include // needed for strcpy + +#define MAPPED_SIZE 128 + +int main() +{ + // Create and open a shared memory segment + int shmfd = shm_open("/CS3841MEMORY", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); + if(shmfd == -1) { + printf("COULD NOT OPEN SHARED MEMORY SEGMENT\n"); + exit(EXIT_FAILURE); + } + + // Set the size of the shared memory segment + ftruncate(shmfd, MAPPED_SIZE); + + // Map the segment into the processes address space + // NOTE: protection is set to allow reading and writing with a shared mapping + void* mapped_space = mmap(NULL, MAPPED_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0); + if(mapped_space == MAP_FAILED) { + printf("COULD NOT MMAP\n"); + exit(EXIT_FAILURE); + } + + pid_t pid = fork(); // fork into 2 processes + + if(pid < 0) // error + { + perror("fork"); + exit(EXIT_FAILURE); + } + else if(pid == 0) // child + { + // Child writes to shared memory segment + strcpy(mapped_space, "HELLO"); + + // Unmap the shared memory + munmap(mapped_space, MAPPED_SIZE); + + // Close the shared memory segment + close(shmfd); + + return 0; // Return success + } + else // parent + { + // Wait for child to finish + wait(0); + + // Parent reads from shared memory segment + printf("Parent reads %s from shared mapped segment\n", (char*)mapped_space); + + // Unmap the shared memory + munmap(mapped_space, MAPPED_SIZE); + + // Close the shared memory segment + close(shmfd); + + // Unlink the shared memory + shm_unlink("/CS3841MEMORY"); + } + return 0; // Return success +} + diff --git a/Examples/ipc/ipcsignal.c b/Examples/ipc/ipcsignal.c new file mode 100644 index 0000000..803834a --- /dev/null +++ b/Examples/ipc/ipcsignal.c @@ -0,0 +1,46 @@ +/* + * ipcsignal.c - Shows how to use the kill system call + * to send a signal from one process to another + */ + +#include // needed for pid_t +#include // needed for wait system call +#include // needed for fork, getpid, getppid, kill system calls +#include // needed for exit +#include // needed for signal system call +#include // needed for printf, perror + +void signal_handler(int sig) +{ + pid_t pid = getpid(); + printf("Process %d received signal %d\n", pid, sig); +} + +int main() +{ + // Set a signal handler for a user defined signal number 1 + signal(SIGUSR1, signal_handler); + + pid_t pid = fork(); // fork into 2 processes + + if(pid < 0) // error + { + perror("fork"); + exit(EXIT_FAILURE); + } + else if(pid == 0) // child + { + // Send a signal to the parent by its PID + pid_t parent_pid = getppid(); + printf("Sending SIGUSR1(%d) to %d\n", SIGUSR1, parent_pid); + kill(parent_pid, SIGUSR1); + + return 0; // Return success + } + else // parent + { + // Wait for child + wait(0); + } + return 0; // Return success +} diff --git a/Examples/ipc/signal1.c b/Examples/ipc/signal1.c new file mode 100644 index 0000000..ed57a5c --- /dev/null +++ b/Examples/ipc/signal1.c @@ -0,0 +1,29 @@ +/* + * signal1.c - Shows how to set up a signal handler + * for the interrupt (CTRL+C) signal + */ + +#include // needed for pid_t +#include // needed for getpid, sleep system calls +#include // needed for signal system call +#include // needed for printf + +// Signal handler +// Prints the PID of the process and the received signal +void signal_handler(int sig) +{ + pid_t pid = getpid(); + printf("Process %d received signal %d\n", pid, sig); +} + +int main() +{ + // Set a signal handler for the interrupt signal + signal(SIGINT, signal_handler); + + // Loop forever and sleep + while(1) { + printf("sleeping...\n"); + sleep(1); + } +} diff --git a/Examples/ipc/signal2.c b/Examples/ipc/signal2.c new file mode 100644 index 0000000..709e7fc --- /dev/null +++ b/Examples/ipc/signal2.c @@ -0,0 +1,29 @@ +/* + * signal2.c - Shows how to set up a signal handler + * for the segmentation fault signal + * Unfortunately does not fix the segmentation + * fault and essentially loops forever + */ + +#include // needed for pid_t +#include // needed for getpid, sleep system calls +#include // needed for signal system call +#include // needed for printf + +// Signal handler +// Prints the PID of the process and the received signal +void signal_handler(int sig) +{ + pid_t pid = getpid(); + printf("Process %d received signal %d\n", pid, sig); +} + +int main() +{ + // Set up a signal handler for the segmentation fault signal + signal(SIGSEGV, signal_handler); + + // Cause a segmentation fault + int* i = NULL; + return *i + 10; +}