From 27e48d6d8eff41686bc6f02d4f719c103a1d579b Mon Sep 17 00:00:00 2001 From: alejandrok93 Date: Wed, 13 Feb 2019 13:37:41 -0800 Subject: [PATCH 1/9] Initial PR --- README.md | 96 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 57 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 4b8dba5fa..937276f97 100644 --- a/README.md +++ b/README.md @@ -3,19 +3,22 @@ Now that we've talked a bit about how processes and system calls work at a high level, it's time to apply these concepts by doing some exercises related to process creation and making system calls. We'll be utilizing the `fork()`, `exec()`, `wait()`, and `pipe()` system calls in order to create processes and even have them pass messages to each other. ## Objective -To introduce and familiarize yourself with some basic system calls pertaining to process + +To introduce and familiarize yourself with some basic system calls pertaining to process creation, to spawn some new processes, and to practice writing more C! ## `fork()` -The `fork()` system call is used by a parent process to create a new child process. Its -actual implementation isn't as intuitive as it could be, though. When a parent process -executes `fork()`, the new child process that is created is an almost exact copy of the -calling process from the operating system's perspective. We say _almost_ an exact copy -to delineate the fact that while the new child process has the same instruction set -(i.e. code) as its parent process, the child process starts executing at the point right -after `fork()` is called in the parent process. + +The `fork()` system call is used by a parent process to create a new child process. Its +actual implementation isn't as intuitive as it could be, though. When a parent process +executes `fork()`, the new child process that is created is an almost exact copy of the +calling process from the operating system's perspective. We say _almost_ an exact copy +to delineate the fact that while the new child process has the same instruction set +(i.e. code) as its parent process, the child process starts executing at the point right +after `fork()` is called in the parent process. Let's look at a program that calls `fork()` to try to give an example of what this means: + ```c // p1.c #include @@ -39,7 +42,9 @@ int main(int argc, char *argv[]) return 0; } ``` + Running this program, one of the possible outputs could be something like this: + ``` prompt> ./p1 hello world (pid: 29146) @@ -48,22 +53,24 @@ hello, child here (pid: 29147) prompt> ``` -So as we can see, the child process doesn't return the exact same output as its parent process, which -is good, because otherwise spawning child processes wouldn't be nearly as useful. Notice that the child -process has its own process identifier (PID); it also has its own address space, program counter, and -execution context that are not the same as its parent's. +So as we can see, the child process doesn't return the exact same output as its parent process, which +is good, because otherwise spawning child processes wouldn't be nearly as useful. Notice that the child +process has its own process identifier (PID); it also has its own address space, program counter, and +execution context that are not the same as its parent's. -More specifically, if we look at the `int rc = fork();` line, which both parent and chlid execute, they -receive different results here. The parent process receives the PID of the child process it just spawned, -while the child process receives 0 if the `fork()` call was successful. +More specifically, if we look at the `int rc = fork();` line, which both parent and chlid execute, they +receive different results here. The parent process receives the PID of the child process it just spawned, +while the child process receives 0 if the `fork()` call was successful. ## `wait()` -So `fork()` allows us to spawn new child processes, but the thing with having multiple processes is that -the order in which they execute is not deterministic, i.e., the parent may execute before the child or -the child may execute before the parent; we can't say for certain. The `wait()` system call (along with -the more complete `waitpid()` system call) allows us to get around this non-determinism if that is something -that needs to be accounted for. Let's add a call to `waitpid()` in our previous example program to ensure that + +So `fork()` allows us to spawn new child processes, but the thing with having multiple processes is that +the order in which they execute is not deterministic, i.e., the parent may execute before the child or +the child may execute before the parent; we can't say for certain. The `wait()` system call (along with +the more complete `waitpid()` system call) allows us to get around this non-determinism if that is something +that needs to be accounted for. Let's add a call to `waitpid()` in our previous example program to ensure that the child always runs before its parent: + ```c // p2.c #include @@ -89,11 +96,14 @@ int main(int argc, char *argv[]) return 0; } ``` -Here, the `waitpid()` function suspends the parent process until the child process pointed at by `rc` terminates. Thus, we ensure that the parent process only runs after the child process has finished its execution. + +Here, the `waitpid()` function suspends the parent process until the child process pointed at by `rc` terminates. Thus, we ensure that the parent process only runs after the child process has finished its execution. ## `exec()` -The `exec()` system call is used in order to run a program that is different from the calling program (since `fork` only executes copies of the program that called it). + +The `exec()` system call is used in order to run a program that is different from the calling program (since `fork` only executes copies of the program that called it). Let's say we wanted to spin up a child process to execute a word count program. Here's how what a program that does that might look like: + ```c // p3.c #include @@ -113,8 +123,8 @@ int main(int argc, char *argv[]) } else if (rc == 0) { // child process satisfies this branch printf("hello, child here (pid: %d) \n", (int) getpid()); char *myargs[3]; // allocate an array of chars to hold 3 bytes - // `strdup` duplicates the given input string - myargs[0] = strdup("wc"); // pass the name of the program we want to run as the first array element + // `strdup` duplicates the given input string + myargs[0] = strdup("wc"); // pass the name of the program we want to run as the first array element myargs[1] = strdup("p3.c"); // argument: the file to count myargs[2] = NULL; // marks the end of the array execvp(myargs[0], myargs); // runs the word count program, passing in the `myargs` array to the word count program as arguments @@ -127,16 +137,19 @@ int main(int argc, char *argv[]) return 0; } ``` -Here, we're doing the same thing as before, forking a new child process from a parent process. Then, inside that -child process, we're calling `execvp()` with the arguments it needs to run the word count program. Note that `exec` -does not spin up _another_ child process from the child process in which we called it. It transforms the process -that called it into the new program that was passed to `exec`, in this case, `wc`, the word count process. That's -why we still had to have the parent process `fork` a new child process. + +Here, we're doing the same thing as before, forking a new child process from a parent process. Then, inside that +child process, we're calling `execvp()` with the arguments it needs to run the word count program. Note that `exec` +does not spin up _another_ child process from the child process in which we called it. It transforms the process +that called it into the new program that was passed to `exec`, in this case, `wc`, the word count process. That's +why we still had to have the parent process `fork` a new child process. ## `pipe()` -Conceptually, a pipe is a uni-directional channel between two processes that would otherwise be isolated from each other. When a pipe is established between two processes, one process has access to the write end of the pipe, while the other has read access to the other end of the pipe. Thus, if you want two-way communication between two processes, two pipes will have to be created between both processes, one in each direction. -Some things to keep in mind when working with pipes is that when a process writes to a pipe, the other process receives the data in FIFO order (which makes sense when you think about the pipe analogy in real life). Additionally, if the process with read access tries to read from the pipe before anything has been written to it, the reading process is suspended until there is some data to read. +Conceptually, a pipe is a uni-directional channel between two processes that would otherwise be isolated from each other. When a pipe is established between two processes, one process has access to the write end of the pipe, while the other has read access to the other end of the pipe. Thus, if you want two-way communication between two processes, two pipes will have to be created between both processes, one in each direction. + +Some things to keep in mind when working with pipes is that when a process writes to a pipe, the other process receives the data in FIFO order (which makes sense when you think about the pipe analogy in real life). Additionally, if the process with read access tries to read from the pipe before anything has been written to it, the reading process is suspended until there is some data to read. + ```c #include #include @@ -151,7 +164,7 @@ char* msg3 = "hello world #3"; int main() { char inbuf[MSGSIZE]; // a buffer that will hold the incoming data that is being written - int p[2]; // a two-element array to hold the read and write file descriptors that are used by the pipe + int p[2]; // a two-element array to hold the read and write file descriptors that are used by the pipe // establish our pipe, passing it the p array so that it gets populated by the read and write file descriptors if (pipe(p) < 0) { @@ -165,7 +178,7 @@ int main() write(p[1], msg3, MSGSIZE); for (int i = 0; i < 3; i++) { - // read 16 bytes of data from the read file descriptor + // read 16 bytes of data from the read file descriptor read(p[0], inbuf, MSGSIZE); printf("% s\n", inbuf); } @@ -173,20 +186,25 @@ int main() return 0; } ``` -This program isn't actually sending data between two different processes. The process that is doing the writing is also doing the reading. This process is essentially just talking to itself. But at least it gives you an idea of how to create pipes and send data between both ends. + +This program isn't actually sending data between two different processes. The process that is doing the writing is also doing the reading. This process is essentially just talking to itself. But at least it gives you an idea of how to create pipes and send data between both ends. ## What You'll be Doing for this Lab + This was your first introduction to making system calls to an operating system kernel. Obviously, there are many more system calls that we'll talk about in a future lesson, but for now we'll just practice with these. Once you've cloned this repo, go into each directory, open up the exercise file, read the prompt, and write some C code! Compile your code with `gcc [NAME OF FILE].c -o [NAME OF EXECUTABLE]`, then run the executable with `./[NAME OF EXECUTABLE]`. ## Further Reading + If you would like to read more on this topic, these chapters from _Operating Systems: Three Easy Pieces_ heavily informed this particular topic and material: [http://pages.cs.wisc.edu/~remzi/OSTEP/cpu-api.pdf](http://pages.cs.wisc.edu/~remzi/OSTEP/cpu-api.pdf) [http://pages.cs.wisc.edu/~remzi/OSTEP/cpu-mechanisms.pdf](http://pages.cs.wisc.edu/~remzi/OSTEP/cpu-mechanisms.pdf) Additionally, it's always a good idea to read the man pages for any system calls you're trying to use: - - The man page for `fork`: [https://linux.die.net/man/2/fork](https://linux.die.net/man/2/fork) - - The man page for `wait` and `waitpid`: [https://linux.die.net/man/3/waitpid](https://linux.die.net/man/3/waitpid) - - The man page for the `exec` family: [https://linux.die.net/man/3/exec](https://linux.die.net/man/3/exec) - - The man page for the `pipe` system call: [https://linux.die.net/man/2/pipe](https://linux.die.net/man/2/pipe) + +- The man page for `fork`: [https://linux.die.net/man/2/fork](https://linux.die.net/man/2/fork) +- The man page for `wait` and `waitpid`: [https://linux.die.net/man/3/waitpid](https://linux.die.net/man/3/waitpid) +- The man page for the `exec` family: [https://linux.die.net/man/3/exec](https://linux.die.net/man/3/exec) +- The man page for the `pipe` system call: [https://linux.die.net/man/2/pipe](https://linux.die.net/man/2/pipe) ## Stretch Goal -Open up the `/stretch` directory. In there, you'll find an involved exercise pertaining to file locking and concurrency. Read the README included in that directory for instructions on what to do. + +Open up the `/stretch` directory. In there, you'll find an involved exercise pertaining to file locking and concurrency. Read the README included in that directory for instructions on what to do. From 4b3945d577f23b9ff0f35704a5ef466f146cea5e Mon Sep 17 00:00:00 2001 From: alejandrok93 Date: Wed, 13 Feb 2019 14:02:55 -0800 Subject: [PATCH 2/9] finished ex 1 --- ex1/ex1 | Bin 0 -> 8668 bytes ex1/ex1.c | 18 +++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100755 ex1/ex1 diff --git a/ex1/ex1 b/ex1/ex1 new file mode 100755 index 0000000000000000000000000000000000000000..13aa1d28ce22f055acd699f6ca43e8033c068d52 GIT binary patch literal 8668 zcmeHMUuYaf7@uns8)HnaDkb6{HpOTv+N9cI5L=Rx!!5=(rU{5B<6Ukqw{&xN?CsG6 z6b?cqM~viAAAIxOKKRh5R#4h1h{Y$7`c~x*D)^9xBI5b`&CVu!d&OrT=7Vp)?>F3-rK?JLtG>TxJ# zHK^sPyG_Y_Js^bnp4Jf&jt2DUd=Kb`FrO?sUd8dzmdy8z&UaeJ6O;E{=~~}XHSpci zvJOb*E9iW4x}P{M9l6mVWvz74E#;+KDwGxO+>a|dANQO>oXipSgir44q}tb+>4oW7 z5B86|Mf;ev+*kbOlrl`pk|(QcE4i{KD}fJu|9rbY6F3|n3Hj&mBoZl?%dwwHSH84f zU!NX8oXp2HMk1w`{jc>6>wIH+0C7AYb47D8WbeD0J#+Sr%*>hSo3IkR0aI=(GKF9s z?W*>}_--fYSz-P@ScTaJnY6<1w+_p8?&UD_3h;xlAB+g`KI}u#IcQuMOO5jo@278L z{KLscV0?C5k{E!F*Q)-w=jO)qYhE6h@&uIYxHk9c$-sW))aM%$A3gfGHFkl!k3>XFs1BQWa1{UqcZ}$3K%icP90Oz(FnZFrx zSv0?dxskc&z%(*{Ha}5zXZ^z+F|@@)mc7|q#{heC(%w4p3mT4nxAFbPt>y)|*LVVK zWbQWSVbzdJ7Cg*x6=t(`5Bbl*L;eCxBhzg0eAzsK2ZFwU*<9RdTt^ts=Z(yr7K}Ld zwY~nW_1-t_(Lqem9!;y~BkK8>dLF`4h}o^DeubGn-yZz|cDu;N*6;0hyU1f^>oz?e zG+RH>dyd{sdYr#?m7e2yW$R+u_wpnCqEPlPScRXFs1BL;^fMLKeU>GnA7zPXj|5FAI z9v)ug(hg2Zmag-T?^ncIetLU~#X40SmpRmnQOvG4ag(7WwJrQ%jBr-nK)|=)^HPKU z82t(=){Bi=nmcTO!Je$D0TS0+Q)u366X3bRB kd#A!z= Date: Wed, 13 Feb 2019 14:14:25 -0800 Subject: [PATCH 3/9] completed ex2 --- ex2/ex2 | Bin 0 -> 8620 bytes ex2/ex2.c | 23 +++++++++++++++++++---- ex2/text.txt | 1 + ex3/ex3.c | 5 +---- 4 files changed, 21 insertions(+), 8 deletions(-) create mode 100755 ex2/ex2 diff --git a/ex2/ex2 b/ex2/ex2 new file mode 100755 index 0000000000000000000000000000000000000000..02ba547b251b3bbbe30fee32334d8e0838916773 GIT binary patch literal 8620 zcmeHM&ud&&6h6~7Hq?+zp~@63yaYz0rAZ?eMnOp0KAdXN)=r^F%O%r!(+r(oym_h3 zq7n#|jv)|57wX21=)y(*0|f=Eo0g*1g&U!^GZ3NZPQ>y1?z=O2^AcQ^F7AQz&iU>= z_q=<*`ySjMH~#+P-<=|f?IMfYL}Ub-91yuG4m^>)&@5D`6EiQnZ@O>1&eDEK^usL? z^ZbH9rE>0>Tz`mepX@IagV8rZceFA>sldA&&zyQK(cS zn9nzQMe%%xK?w7uOhgxV8w{F!kC=impPKW^b&|1`a$fPxX=RvF)v{_VRPwd5ss}#s*7vMwVlT*GCT2S%}u%r0lpzwUFsSOzQumI2FvWxz6E8L$jk1|CiZc8{fU?Ah*V#jERr=lgXz=_gmGd0D3~ z$5kHp#kkB~Y~gG|OJY_06k2$fOM$?5;1_FkuSzhkfq#+yLHc!EUk61%EeVCY{B5c- zht}Tt`M|?n`7G0qR%T08N%J6MyR7XCqk9gEM-sf53lA?I*El@$;PDO5LSX4?c^c0s zJ`lq^7m3!t7{f @@ -8,7 +8,22 @@ int main(void) { - // Your code here - + // Your code here + FILE *file; + file = fopen("text.txt", "r+"); + int fp = fork(); + if (fp < 0) + { // fork failed; exit + fprintf(stderr, "fork failed\n"); + exit(1); + } + else if (fp == 0) + { // child process satisfies this branch + //fprintf(file, "%s"); + } + else + { + fprintf(file, "%s"); + } return 0; } diff --git a/ex2/text.txt b/ex2/text.txt index e69de29bb..d2b3994af 100644 --- a/ex2/text.txt +++ b/ex2/text.txt @@ -0,0 +1 @@ +(null) \ No newline at end of file diff --git a/ex3/ex3.c b/ex3/ex3.c index 3a3698c1f..1e454a550 100644 --- a/ex3/ex3.c +++ b/ex3/ex3.c @@ -9,7 +9,4 @@ int main(void) { - // Your code here - - return 0; -} +} \ No newline at end of file From 47c9d69de683488bb87882d3563498f07806bc42 Mon Sep 17 00:00:00 2001 From: alejandrok93 Date: Wed, 13 Feb 2019 14:15:40 -0800 Subject: [PATCH 4/9] completed ex3 --- ex3/ex3 | Bin 0 -> 8668 bytes ex3/ex3.c | 19 ++++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100755 ex3/ex3 diff --git a/ex3/ex3 b/ex3/ex3 new file mode 100755 index 0000000000000000000000000000000000000000..b876ec2d4b148afca9f0a2cf16f292bf52915c80 GIT binary patch literal 8668 zcmeHMUuYaf7@un!o5t8&UusINY$MSq*fiS05fqY=!>z4aZ3@LA<6Uo)TfE#IdwVp2 z77jwCAqMX?KJ`^l=wqL%plI|(=~F2|6tvvY7W&YKP)e`A-|XyVZ!h>J_%I)Q^L@Yh z^X<%Uc8|IFetUHP$xa~>+l8oY6G99?lRZLQ78X1q_Cal^l&2=&Nq?OF=mXYvN}>~P zi5TY=I!Za6K0DpnMU78()(MRmPXppj6yxpC9yoI)Ir5wrv)_cf*Vb!u{Y zGSY(mBX8k8#x3_1@0?P0ld@Qlm4&%%sUXX~2fTH>_GhL-=K~+q6ZL1<1tqFEOy!au1+3*|3rG~c=%0NG2VbF>xxVv z7)QIRehA;~VR}{&zZX_v)6n9j7Gvp`+D`H(GGBqq&7b4w$kZ%6Z(DBh|kijz9kP?z!hrq~>qDfjSGC zfQsFHO6e;u`&SdM!B4VH3;3=v4!`rL@VO}{+qj0FwZHK*kl36H=5uH0;yvr<^kY7(@db*d z^v2?)4Kc97!#F=im4Bimy)}AA>D_=gQ}RBu zW-@NU$@K~RpDdL6#B8aQ%Pu%L7IS4UKq*nnvo6oVM_{S^ze=IcGju;jCWF&8s~KiX z$?N}tp0*dY{ao9+wp$K1m4*SsfMLKeU>GnA7zPXjh5^HXVZbn87%&X{uNc@fGO07tXZW~-a~ZcNhIyf}U0eFnArA)W%q;5s${ literal 0 HcmV?d00001 diff --git a/ex3/ex3.c b/ex3/ex3.c index 1e454a550..aae513599 100644 --- a/ex3/ex3.c +++ b/ex3/ex3.c @@ -9,4 +9,21 @@ int main(void) { -} \ No newline at end of file + int fp = fork(); + if (fp < 0) + { // fork failed; exit + fprintf(stderr, "fork failed\n"); + exit(1); + } + else if (fp == 0) + { // child process satisfies this branch + printf("hello\n"); + } + else + { + int wc = waitpid(fp, NULL, 0); + printf("goodbye\n"); + } + + return 0; +} From 4828b3d5eae7af0cc1f5694200fbab58f47abe6e Mon Sep 17 00:00:00 2001 From: alejandrok93 Date: Wed, 13 Feb 2019 16:01:44 -0800 Subject: [PATCH 5/9] ex4, WIP --- ex4/ex4.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/ex4/ex4.c b/ex4/ex4.c index 0221ca96e..76cf6883a 100644 --- a/ex4/ex4.c +++ b/ex4/ex4.c @@ -1,6 +1,6 @@ // Write a program that calls `fork()` and then calls some form of `exec()` -// to run the program `/bin/ls`. Try a few variants of `exec()`, such as -// `execl()`, `execle()`, `execv()`, and others. Why do you think there +// to run the program `/bin/ls`. Try a few variants of `exec()`, such as +// `execl()`, `execle()`, `execv()`, and others. Why do you think there // are so many variants of the same basic call? #include @@ -10,7 +10,21 @@ int main(void) { - // Your code here + int fp = fork(); + if (fp < 0) + { // fork failed; exit + fprintf(stderr, "fork failed\n"); + exit(1); + } + else if (fp == 0) + { // child process satisfies this branch + // do nothing? + } + else + { + //call exec on '/bin/ls + exec("/bin/ls"); + } return 0; } From 1c7564053433257aa0b7611c7552f9b0efba08a6 Mon Sep 17 00:00:00 2001 From: alejandrok93 Date: Wed, 13 Feb 2019 16:41:30 -0800 Subject: [PATCH 6/9] completed ex4 --- ex4/ex4 | Bin 0 -> 8848 bytes ex4/ex4.c | 7 +++++-- 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100755 ex4/ex4 diff --git a/ex4/ex4 b/ex4/ex4 new file mode 100755 index 0000000000000000000000000000000000000000..cf4039c2b1a48eb7609f27a05b29bb47a6476a60 GIT binary patch literal 8848 zcmeHNU1(fI6rOFGnzo_Yij=BVZUZT`(ENzXDk!_!i?^C;Y-5#Ho$Sv|_L9x+dhcD^ zh=D+eWC?)Ac?U%sae!GA4xrFo-%Es=YyJ@2s2;jJUUGi+@?q zcb(#doS@o!Q`$Q&$AP2NW}5~$uM{sh#T<8v<0XOH^Kn_)L(W0Ks*PYI=#ke2k=GNc z(NtuF@`t#Ec~m*_N_(!A8_tUb?oCf+N(El_UGj5#d#!Ck0@jCw_`_yMoKKV@+hmKq zxb!cy2dvuL9U3Ffc_Do({|sp_A=dy$?ZLObZT7OIqPOXx`n+S(-a)wrxNRRtY(d<7 zPlr!F^R#*5WcZF5N*)MJ!4g)n}c-9f%2w^VTo`_BruN-FVc2!B3USqfA0zO*RlQ-&{hqWIJAbBgleNgKs=4u%c^%Hyf1<8xuFcJ?v7RLyZD`tOVp_sl zdhiHILtig^v#?tKh{is_xvOff*54s6mdrndB}uj@T6*-V82s@=RzD@Al?E~Ra||ZP?Zs0Y*2613^ElNG zEn9P6Bwzl#j$>fY-deNo4w}{MJ0SXlqQ6V@heUs`=nd+Jm+twV)}+of`#vRJ%Tvc1 zzcri9JdTEq>yU8hYg~hb<7Z<9(qoW5h6Mi_mm!^p^gc=BC3n&oPdf!Ww}%xxc0A3V z$UB9cQFcpN+w%;^GqR4fP;4FKHmV%-j=Te+oA0Uo~->M+Uc+hS-ug0lKY6+oY zJD!xk2cMFBRPt9O&r9w~{)XhCt+yn;r0BzO&2vVk~D2B2ha}C83ZZ)VP=pH4#ebLUoMrN2hD3IerPLPZX5Xec$WvX}k;& literal 0 HcmV?d00001 diff --git a/ex4/ex4.c b/ex4/ex4.c index 76cf6883a..40acbc099 100644 --- a/ex4/ex4.c +++ b/ex4/ex4.c @@ -18,12 +18,15 @@ int main(void) } else if (fp == 0) { // child process satisfies this branch - // do nothing? + char *args[] = {"ls", "-a", NULL}; + // execvp(args[0], args); + execvp(args[0], args); } else { //call exec on '/bin/ls - exec("/bin/ls"); + int wc = waitpid(fp, NULL, 0); + printf("Child process is complete"); } return 0; From d87aecb50eae06633cb7dbf62f7f13bd7710333c Mon Sep 17 00:00:00 2001 From: alejandrok93 Date: Thu, 14 Feb 2019 14:16:24 -0800 Subject: [PATCH 7/9] Completed ex5 --- ex5/ex5 | Bin 0 -> 9112 bytes ex5/ex5.c | 48 ++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 40 insertions(+), 8 deletions(-) create mode 100755 ex5/ex5 diff --git a/ex5/ex5 b/ex5/ex5 new file mode 100755 index 0000000000000000000000000000000000000000..d551e3fe0090e9e02e1600f9a2741c903be293ee GIT binary patch literal 9112 zcmeHNZ)g-p6rVHxi5k5`q138nlM>OEs+TBQK}dp&D{4)vfncfYxK&BI2D8_Jl>M zwq{O#fux~_V}0fL)%Dwf1*7?<#W>+gs)~&PRZYc?g=0ZA9P5p9TpjO{h(~KqMA#X_ z9lvimTot)Mcd#=1Tsv3)^$>Y(UctlMYI`VvYyz(}IK>j77 z`Y$a3a8>P#S8S6x@#;l>rFev$@s?G^i})XvpCsaS3m?Lj@o2u4OQWhmzu}+#0Ox$u zBHrV|gm7iNSx;M+Oms#BqrCV!aV=v__&czfWQnm_uv+la zUI1jBz{B8E;GN*KHz-G?k+GHF;|OpWoYsQIE2;DxW6S>|rQ!d?Lq^F*Lc`pK zrbxJFQ}B2s2u!pZjq><;<$yQ- zs+UV{1>6d_6>uxyR^b0qfiA`TO?iE?fcYx>5`FuX&X(ri#TPeR(U5w@JU@YsDPJ=!kU(+QDh&&C_dulHZ!gS2RLz zV?*?s zHZew0Gf8(y@{u$`(oT}TBxxT>mq6mQ+SwOJsy<;A&l>knya-5zplj$ zTiu+*8!Ug9T?0;3$+3y}d+Qc(YV=!`h-4~z9X#vpH(^rq8j|oR`W`XJ@F&5?1-~!& z1Hoqmuf>lXvR@(i8o}2IzFF|n@76s6cMJZgT--6Y0&WG|3b++;E8teZt$Y_DY>>PiGM$K!+(vQ&*WE@h zK?Sf+GZNt-p-vz=M6Z!aFA5vV>??|M=RT1!=@#iq+}Y=WgB@oG9V&P zuZM2>?DLPuIJVDY=sbkZX}pVZCIb_~O#){G#=RpS&kDQ|7 #include #include #include -#define MSGSIZE 16 +#define MSGsize 16 -char* msg1 = "hello world #1"; -char* msg2 = "hello world #2"; -char* msg3 = "hello world #3"; +char *msg1 = "hello world #1"; +char *msg2 = "hello world #2"; +char *msg3 = "hello world #3"; int main(void) { - // Your code here + + int size = 100; + int p[2]; + char buffer[size]; + if (pipe(p) < 0) { + fprintf(stderr, "pipe failde\n"); + } + int fp = fork(); + if (fp < 0) { + fprintf(stderr, "fork failed\n"); + exit(1); + } + else if (fp == 0) { + //inside child branch + printf("Hello from child: %d\n", (int)getpid()); + close(p[0]); // close the read branch + write(p[1], msg1, size); + write(p[1], msg2, size); + write(p[1], msg3, size); + close(p[1]); // close the write branch + } else { + // inside parent branch + + close(p[1]); + int wc = waitpid(fp, NULL, 0); + printf("Hello from parent: %d\n", (int)getpid()); + for (int i = 0; i < 3; i++) { + read(p[0], buffer, size); + printf("%s\n", buffer); + } + close(p[0]); + } + return 0; } From f55076c3468258d9bc139e2ea4591c59f50e5a3d Mon Sep 17 00:00:00 2001 From: alejandrok93 Date: Thu, 14 Feb 2019 14:18:46 -0800 Subject: [PATCH 8/9] updated ex2 with output to text file --- ex2/ex2 | Bin 8620 -> 8708 bytes ex2/ex2.c | 5 ++++- ex2/text.txt | 3 ++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ex2/ex2 b/ex2/ex2 index 02ba547b251b3bbbe30fee32334d8e0838916773..a642f520202ec7fb4581129f180a8f9d0ad4e453 100755 GIT binary patch delta 954 zcmZ8gUr19?7(aKr7pKIov#6D>?lo64BHV0f{+-t3LP8E9B8ZvZ=|*!Kck3ZxXqez- z3^vX~J@n9X2^sbv1pcW&tsYiADH8S)SMb3H=_y#>ckeZ%1K;=ke!u(s4(A@eGk5*T zjY7#G*a=|>A>Scz3B{k?H3z2HU})sPPJK+5!^s=oep7bR$4s|FHq|~;mFZVd=S)>H z)j29!UeP+Moo-or85?z3o0%pWveq({bllo*VJ-BfwM`rV`>a4n6I2U?6JiB;71ZY< zAyLY)=b+uo)pA3?`C{ley~BE{FZU?z6N~Lrxu-LmV{2m*w7|A90^MM5)ht544f-1) zsv%Z{1uys8M(6DnlL0B;>4*Q9^8OYmYr#KYAlecnNe%96?*OR5z3J>8;q$nGl;hr@ zKi3K^6@a`Ov!7;5+B5jJ3>4g&mWHag%or`%eM!ykXcO3<_y53>%kHS}=O>9a1WXNX z@8Vs9iq4W2LX!7?Hnb8riPoYUzwAQMjoJwS-VHUluC7bd9|QM36w2 z8}xiZ&mPGAc^7WcGgx+Sk`6)&QQUC%SGin{9z(Q^=nSH7h%O>pN7RgH2~jVix3tLD zU6CU3cv2WulHmP`6o}$+1j3`qR3w31Nz4yQ8@hr`3Mgd9=8O2}XQ CQs<@s delta 673 zcmYk3T}TvB6vyw(&SYWChbgS+*1g8a)=O>_ZAN}=8$$#(=!1|EJtRh{%NjmqA6VwL zEbMmdrF!TklJsG~w_Xei$|%?@ji47HY8Hf~UW4hJ^*(gqod5s)?mc&gdvBjuNEOSr zZ!o4X#_nTM_@(vEx*l^2Mzfsx2DbwPpWk#<2xXEjE zoAfyLwIy#C3}|u7@P7WOFD0Xoj-GmWePsPN6t$${!?M;}_e9R`!!s<*Ilkyw(>s70 zH8;3hIKGO^Egb%W@+SQkD+?wF<?uljU+6qQEe;c`{0PHvcqh4UWss@88hgW4 Date: Thu, 14 Feb 2019 14:28:05 -0800 Subject: [PATCH 9/9] completed ex6 --- ex6/ex6 | Bin 0 -> 8636 bytes ex6/ex6.c | 15 ++++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100755 ex6/ex6 diff --git a/ex6/ex6 b/ex6/ex6 new file mode 100755 index 0000000000000000000000000000000000000000..1ffe495496e9f95b23100fc8b233cd7138bfd531 GIT binary patch literal 8636 zcmeHNUuYaf7@up51`WN-gOZ|!ZA&y(NK%O!6y+{tb&H8sdj$#A$-hmqc-cGdc5PB9 zoJ7In33MCIdhEgh)as+J$&u7_fvm1ht@2p31yrj+?K)%Gy>* zw8DK6yqSy3|$D25a!Jv6dxe(vebSEfB zp_C=hpDOKE#p4Zv5XS3P9w81pbf|dE{1{Kp+qr^Wgi}1;sERkF0uYn;UD=c0blxpB z2ON+0fr{6m0uW;^?sIj$Izxz~@i<;;D9!J5 z^yDiqnO)$228meklBc#%%C3gULK%j2*I&*pbRi<%8(&M8s#EN)^jfTZL9&) z|LhSVCQv>AJq3*leW_6%qV2Q?(4T$dg3p*KiB4$0Un=(JoT>hqrQ8fKaV*HH5zZ+5Ed-=_>jbmuv zyoKeFXy$@^PA`=_d!cW*4|zFLaDqGvW&DdqgP+G0CSO`K1DXNNfM!55pc&8%{2v)O zV^w~!mVcYL!cCvG;@39Jzc|j?H+XEA!OygcdHLN7Tj}AXNUm^?WmVgK?9r_1Q0-&D z6W>>^Ta^oIl?|)vuUXYIYqbyQRWUDC&8_A2M8({?{cXKo58rXKHqQ2y=P#kyNv7IA zBdq#2ttb4N<@_Oj`1Coe&EE#RvtuQXU)xD`jcvk_kGG&*W9vZXdd2)=Em7mv8abGs zS2nHXs}pa2SMT`=RrQ|j;Q4d#yoKlJ%Hgk3WKP$6zC^h?kB7MZD>9pZkk*g1j?ub7 z>jbS$SSSN2zt@+^yki$9=WN4s7Hq?D4R_Mbmu&n7oGCqP^yFr-gAMkwkElM;lKWEb zTL)26pTch~3T^IpJJB=M*a@>b*b>v&PtK~}ZL_K@sPeoj_v@qUGy|Fe&46Y=GoTsJ z3}^;41DXNNfM!55pc(jYGSGFjJIlSM=~OqfKmw=NqBH>SUsEW5)xGhXUL<_aLS}%H6Y#$71;D z7=9s!UyR|g80I+&?}fwvNl