From fe89f0b79ec52d27534e0ce1b99b62546706cf35 Mon Sep 17 00:00:00 2001
From: Andrew To <andrewto.307@gmail.com>
Date: Tue, 4 Mar 2025 15:29:55 -0500
Subject: [PATCH] resubmitting question due to git commit problems in the last
 submission

---
 hw4/question.md                               |  46 ++++++++++++++++++
 hw4/questions.md                              |  41 ----------------
 hw4/starter/bats/student_tests.sh             |   4 +-
 hw4/starter/ok.dSYM/Contents/Info.plist       |  20 --------
 .../ok.dSYM/Contents/Resources/DWARF/ok       | Bin 9046 -> 0 bytes
 5 files changed, 48 insertions(+), 63 deletions(-)
 create mode 100644 hw4/question.md
 delete mode 100644 hw4/questions.md
 delete mode 100644 hw4/starter/ok.dSYM/Contents/Info.plist
 delete mode 100644 hw4/starter/ok.dSYM/Contents/Resources/DWARF/ok

diff --git a/hw4/question.md b/hw4/question.md
new file mode 100644
index 0000000..9846f3b
--- /dev/null
+++ b/hw4/question.md
@@ -0,0 +1,46 @@
+1. Can you think of why we use `fork/execvp` instead of just calling `execvp` directly? What value do you think the `fork` provides?
+
+    > **Answer**: If the execvp runs successfully, the process ends. Therefore, we need to use the fork create a child process so that when we have done with the current exe within the child process, we can move back to the "checkpoint" status so that the program will continue until "exit" command is read.
+
+2. What happens if the fork() system call fails? How does your implementation handle this scenario?
+
+    > **Answer**:  If it fails, no child is created, so we shouldn't run the execvp. To handle this, I use a condition to check the return of fork(), and stops if fork fail. If it's 0, it will be successful and we can safely run the execvp().
+
+3. How does execvp() find the command to execute? What system environment variable plays a role in this process?
+
+    > **Answer**: The execvp() find searches the PATH to the binaries to the new program and replace the current process by this program.
+
+4. What is the purpose of calling wait() in the parent process after forking? What would happen if we didn’t call it?
+
+    > **Answer**: The wait() is used for telling the parent process waits for the child to complete its current process. If we didn't call it, the parent may not know the exit status of the child process, which may cause potential issues.
+
+5. In the referenced demo code we used WEXITSTATUS(). What information does this provide, and why is it important?
+
+    > **Answer**:  The WEXITSTATUS() is used for extracting the status code from the child process. It's important to pass the exit code of child process to its parent, so that we can control the exit code of the program.
+
+6. Describe how your implementation of build_cmd_buff() handles quoted arguments. Why is this necessary?
+
+    > **Answer**:  For quoted arguments, since there is always at least 1 space before a new argument, so I use strchr to get the first space. Then, if the pointer points to a double quotation mark, it will save the current position, then implement one by one until reach another double quotation mark, then use the new position and old position to extract the argument. After that, the loop continues with a new strchr() command and the same process. It's necessary if we don't care about the quoted arguments, we will inaccurately parse arguments, which may lead to many potential issues in many commands which have limited number of arguments (for example: cd)
+
+7. What changes did you make to your parsing logic compared to the previous assignment? Were there any unexpected challenges in refactoring your old code?
+
+    > **Answer**: Comparing to the previous assignment, I don't use a list of command in this assignment and just use a buffer instead. Therefore, I can only store 1 command at a time. Moreover, I saved both command and arguments in an array. It was quite challenging when I have to deal with the quoted string since I have to combine the strchr() and the normal pointer implementation, which was so complex and made many unexpected bugs.
+
+8. For this quesiton, you need to do some research on Linux signals. You can use [this google search](https://www.google.com/search?q=Linux+signals+overview+site%3Aman7.org+OR+site%3Alinux.die.net+OR+site%3Atldp.org&oq=Linux+signals+overview+site%3Aman7.org+OR+site%3Alinux.die.net+OR+site%3Atldp.org&gs_lcrp=EgZjaHJvbWUyBggAEEUYOdIBBzc2MGowajeoAgCwAgA&sourceid=chrome&ie=UTF-8) to get started.
+
+- What is the purpose of signals in a Linux system, and how do they differ from other forms of interprocess communication (IPC)?
+
+    > **Answer**: In general, signals notify the process that an event has occurred. Each signal has a current disposition, which determines how the process behaves when it is delivered the signal. Other forms of IPC are used to allow processes to communicate in different forms like sharing data, or message passing.
+
+- Find and describe three commonly used signals (e.g., SIGKILL, SIGTERM, SIGINT). What are their typical use cases?
+
+    > **Answer**:  
+    - SIGKILL: Kill the process
+    - SIGTERM: Terminate the process
+    - SIGINT: Interrupt the process
+
+    They are usually used for terminating the process, but they have some difference. SIGKILL will kill the process immediately without saving any memory, while SIGTERM may be blocked or ignored. SIGINT is requested by user (like Cirl+C in Mac).
+
+- What happens when a process receives SIGSTOP? Can it be caught or ignored like SIGINT? Why or why not?
+
+    > **Answer**: It will stop/pause the process, and it can't be caught or ignored. The SIGINT is designed to forcefully terminate the process when it's unresponsive. 
\ No newline at end of file
diff --git a/hw4/questions.md b/hw4/questions.md
deleted file mode 100644
index f3e6ead..0000000
--- a/hw4/questions.md
+++ /dev/null
@@ -1,41 +0,0 @@
-1. Can you think of why we use `fork/execvp` instead of just calling `execvp` directly? What value do you think the `fork` provides?
-
-    > **Answer**:  _start here_
-
-2. What happens if the fork() system call fails? How does your implementation handle this scenario?
-
-    > **Answer**:  _start here_
-
-3. How does execvp() find the command to execute? What system environment variable plays a role in this process?
-
-    > **Answer**:  _start here_
-
-4. What is the purpose of calling wait() in the parent process after forking? What would happen if we didn’t call it?
-
-    > **Answer**:  _start here_
-
-5. In the referenced demo code we used WEXITSTATUS(). What information does this provide, and why is it important?
-
-    > **Answer**:  _start here_
-
-6. Describe how your implementation of build_cmd_buff() handles quoted arguments. Why is this necessary?
-
-    > **Answer**:  _start here_
-
-7. What changes did you make to your parsing logic compared to the previous assignment? Were there any unexpected challenges in refactoring your old code?
-
-    > **Answer**:  _start here_
-
-8. For this quesiton, you need to do some research on Linux signals. You can use [this google search](https://www.google.com/search?q=Linux+signals+overview+site%3Aman7.org+OR+site%3Alinux.die.net+OR+site%3Atldp.org&oq=Linux+signals+overview+site%3Aman7.org+OR+site%3Alinux.die.net+OR+site%3Atldp.org&gs_lcrp=EgZjaHJvbWUyBggAEEUYOdIBBzc2MGowajeoAgCwAgA&sourceid=chrome&ie=UTF-8) to get started.
-
-- What is the purpose of signals in a Linux system, and how do they differ from other forms of interprocess communication (IPC)?
-
-    > **Answer**:  _start here_
-
-- Find and describe three commonly used signals (e.g., SIGKILL, SIGTERM, SIGINT). What are their typical use cases?
-
-    > **Answer**:  _start here_
-
-- What happens when a process receives SIGSTOP? Can it be caught or ignored like SIGINT? Why or why not?
-
-    > **Answer**:  _start here_
diff --git a/hw4/starter/bats/student_tests.sh b/hw4/starter/bats/student_tests.sh
index f9e0212..60ff8a3 100755
--- a/hw4/starter/bats/student_tests.sh
+++ b/hw4/starter/bats/student_tests.sh
@@ -221,7 +221,7 @@ EOF
     # Strip all whitespace (spaces, tabs, newlines) from the output
     stripped_output=$(echo "$output" | tr -d '[:space:]')
     # Expected output with all whitespace removed for easier matching
-    expected_output="Linuxtux25.15.0-121-generic#131-UbuntuSMPFriAug908:29:53UTC2024x86_64x86_64x86_64GNU/Linuxdsh2>dsh2>cmdloopreturned0"
+    expected_output="Linuxtux45.15.0-133-generic#144-UbuntuSMPFriFeb720:47:38UTC2025x86_64x86_64x86_64GNU/Linuxdsh2>dsh2>cmdloopreturned0"
 
     # These echo commands will help with debugging and will only print
     #if the test fails
@@ -245,7 +245,7 @@ EOF
     stripped_output=$(echo "$output" | tr -d '[:space:]')
 
     # Expected output with all whitespace removed for easier matching
-    expected_output="batsdragon.cdshdsh_cli.cdsh.dSYMdshlib.cdshlib.hinput.txtmakefileshell_roadmap.mdstudent-testtestdsh2>dsh2>cmdloopreturned0"
+    expected_output="batsdragon.cdshdsh_cli.cdsh.dSYMdshlib.cdshlib.hinput.txtmakefileshell_roadmap.mddsh2>dsh2>cmdloopreturned0"
 
     # These echo commands will help with debugging and will only print
     #if the test fails
diff --git a/hw4/starter/ok.dSYM/Contents/Info.plist b/hw4/starter/ok.dSYM/Contents/Info.plist
deleted file mode 100644
index 01a73db..0000000
--- a/hw4/starter/ok.dSYM/Contents/Info.plist
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-	<dict>
-		<key>CFBundleDevelopmentRegion</key>
-		<string>English</string>
-		<key>CFBundleIdentifier</key>
-		<string>com.apple.xcode.dsym.ok</string>
-		<key>CFBundleInfoDictionaryVersion</key>
-		<string>6.0</string>
-		<key>CFBundlePackageType</key>
-		<string>dSYM</string>
-		<key>CFBundleSignature</key>
-		<string>????</string>
-		<key>CFBundleShortVersionString</key>
-		<string>1.0</string>
-		<key>CFBundleVersion</key>
-		<string>1</string>
-	</dict>
-</plist>
diff --git a/hw4/starter/ok.dSYM/Contents/Resources/DWARF/ok b/hw4/starter/ok.dSYM/Contents/Resources/DWARF/ok
deleted file mode 100644
index f5692c73526cca8881535b752238d63bb593d139..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 9046
zcmX^A>+L@t1_nk31_lN$1_lNW1_lNJHV_Yjr5P9)Bp4VNeol2>$`NJqsn=UWUeEEB
zy%AI#tdW72fq|J9tbqwC&LF_R0Aec$Ffhn4Ffd3mFfe#9Ffhc&2RORBM!5$0gO#HY
z5VKH(FgPG{Iv7Fbgt$h8ph|=FJD`fec&rQz3?R$`6^M^7Nv$Y>a=`9FHLt`D5-0}{
zO2Gbsb6FS~;B2t|;*!#&Vz^LzJgRvn_7L+_;3^>D1LJZ)&EtUz#K$KWmlS2@rNjBC
z=0!lwOMuFwQ=qU%7K@KB%`4B$ONr0SOUnnl7uCESQ1d`>1k;CZ22318gW_QZ*c=zf
z5XX3Df4^WzY&byt$$%psm>C!tKo}HP0$}~=`AE^g5Fd}-JWv`0*$cuT{U92IK}i*v
z4{{gC5ApFno_^l0E}jrqF@RzVWG5(Hg7m>?8!!jrX0SYz4>CuB8I;ak!X1O$prQ;6
z3=<$~Vfq;qAW~saN3cWv#|aT;h>uT6O)5=~&&kY71qsE+V>fRWND_ph=7E^lFwDHf
zqQt!P)M8M0p}21r)O`j}&9jI!51K46%sT}&uMukADI(2FOiC(BEyD~y?}?D`3xb;G
ztq5h{pkV$jE-3=5Ko7sUQ1cFhWf>Ue5;QNdpdcqTJ})sh6_i`i%}baBaUU#QBq%`*
z#zDo$Bbir_n2c`T9H@D)d_RXs^GYfUu)6O6)I3ONFfbe-(!BhntYnZE(A{S=8RB1<
z`;3%9sz&i>2#kinXb6mkz-S1JhQMeDjE2B)4FOOekDn3L6N9t^#TXbE_!$`(VEtcE
z3qCg^KD8n>xwIrTJ|i_TCAEklJ~uHlZ@31@sJ})-U^E0qLtr!nMnhmU1V%$(Gz3ON
zU^E0qLtr!nMnhoOg}^ih1_l-eIR*v>Mn=Zpe7qnEG!M!M8V)E)EiTamPa82Xa5BM$
z1jJZ5xj0H$`PjTzIh$A+n5&vtIoUd!SuI;xS=m4WrA@4?%-l_^{A@m~oNP_35>SQ3
zAcf3)O{@%T%tc<ToNUbeO{}cmAZ`JeE7-)!+RDn<%p}0T$f&~rn;{3SNkEK9AkWAn
zM@KE#Cm<0HMvxD97>pSh7_1l=7+@n6l?<q+z<mTVk}-ERC=ggPKohu36Du|#@%ja}
zf_b2ca|V`Oprr&Xte{zIR*;b_`xqD)*ccfY1sPTOgjt#Snriso*YgR8OY;db3b8RT
zFzGRZ7!DH5d{*4n-0G5^!uFC349u(yOi&?DVFm^k6$WNLJ8o`n1_oAs29O8?gCl6J
zQXx4fF)v-AEVZaOGe1wk&_vHb&saeNEUIg0VqmOipl4*HXK12lsL240GJT)Sq@u*4
zN`05qvecaXg47~?=ltB<#Jm)r%)Hc){QR6^{a_dGVtwDlWdGm@z2cN?1|+6_XmM&$
zv3^Qva!P4_UV2HszDsIxc1eDLzH_jVg|U8eF^J44H_<OHNh~T!En)x<2qhM!Co?1#
zrI#^e=9MrcXCxLecmz9ofMNrNVe1<pe9-JY14CB*tQt^kgCl@}fdRC(1Qd_RdO>`2
zz5oCJ{|{3G8pi@**g65wIuAw$HU?$}Rt8oEZU#06h+QCi4H`PQlNF}cxG*p<L^Cij
zfFcwm4vKme28JaXR$!Yz(Fzg<#jy$lL-_UT$skw2Yy?Sx_+Yi5<N?NP3?Nql0FSdI
A5dZ)H

-- 
GitLab