CSE 381 Exam #1 Miami University Page 1 of 13 CSE 381-- Systems 2: OS, Currency, Virtualization, and Security Miami University Exam 1 There are 11 questions for a total of 100 points. Maximum Possible Score: 100 points NAME (PRINT IN ALL CAPS): _______________________________________________ General Instructions • Wait until you are instructed to start. • First, ensure you have all the 13 pages of this exam booklet before starting. • This exam is closed notes and closed books. No discussions are permitted. • Even if your final answers are incorrect, you will get partial credit if intermediate steps are clearly shown to highlight thought process. This applies to program tracing questions as well. • All work must be written on the exam pages in order to be graded. Any scrap paper used, must be the extra sheets provided during the exam period. • For programming questions: Be accurate with your C++ syntax. This includes appropriate use of braces, semicolons, and the proper use of upper/lowercase letters. Points will be deducted for syntax errors in programs and C++ statements that you write in this exam. • You are permitted to use a simple calculator. You calculator cannot be: a graphing calculator, cannot have a QWERTY keyboard, or be integrated with other electronic devices such as: iPods, PDAs, and cellular phones. • You have about two hours (120 minutes) to complete the exam. GOOD LUCK! CSE 381 Exam #1 Miami University Page 2 of 13 Multiple Choice Questions [42 Points] 1. Clearly circle only the best response for each question below. If your choice is not clearly indicated or if multiple choices seem to be selected then you will not earn any points for that question. If you change your answer, ensure that your final answer is clearly highlighted. Each question is worth 2 points. i. A structured thought process is critical for developing good, maintainable programs. A key indicator of lack of structured thinking is A. Methods longer than 25-lines of code B. Many methods in one program. C. Many objects in one method D. A method with many calls to other methods ii. Most modern operating systems use 2-stage boot loading because A. 1st stage cannot store a complex boot loader B. 1st is to too large to store on disk C. It is needed to fork a new process D. Because a 3-stage boot loading is not allowed iii. In the context of computer hardware, what is BIOS A. First program that runs on a computer B. A special user interface C. Hardware on a computer D. The Master Boot Record iv. What is the convention that is used for the 1st command-line argument, in the list of arguments passed to the execvp system call? A. The 1st argument should be the command executed B. The 1st argument should be nullptr C. The first argument should be empty string D. The first argument should be zero CPU D o not w rite letters here. Instead, clearly circle one best response for each question CSE 381 Exam #1 Miami University Page 3 of 13 v. The exit code from the child process is: A. The return value from the main function of the child process B. The PID of the child process C. Zero in child and non-zero in parent D. The PID of the parent process vi. The exit code from the child process is obtained via: A. Argument to the waitpid system call B. Return value of fork system call C. Return value of exitCode system call D. Cannot be determined vii. What is the expansion of the acronym, GNU? A. GNU's Not Unix B. GNU/Linux C. Great Next Unix D. This is not an acronym viii. In order to write data to a file, the correct stream to use is A. std::ofstream B. std::ifstream C. std::istringstream D. std::cin ix. The correct approach/method to check if a given value exists in an unordered_map is to use A. Use find() method B. Use [] and check for zero/null C. Use the insert method D. Use the has() method D o not w rite letters here. Instead, clearly circle one best response for each question CSE 381 Exam #1 Miami University Page 4 of 13 x. Assume the forkNexec method below is a helper method that – runs a given program in a child process while returning PID of the child in the parent process. What would be the estimated runtime of the sleepy method? A. 5 seconds B. 2 seconds C. 3 seconds D. 4 seconds xi. When listing files using the ls command on Linux, the correct combination of permission flags that indicate read-&-execute for group members is: A. rw- r-x r-- B. rwx –wx --- C. r-x rw- r-- D. rwx --x r-w xii. Which one of the following streams can be used for redirection or piping? E. std::cin F. std::ofstream G. std::ostringstream H. All of the above xiii. Given the following bash command, how many child processing are being multitasked? $ ls -lh | tr -s " " A. 2 B. 3 C. 4 D. 1 // Helper method int forkNexec(std::vector
argList); void sleepy() { int pid1 = forkNexec({"sleep", "3"}); waitpid(pid1, nullptr, 0); int pid2 = forkNexec({"sleep", "2"}); waitpid(pid2, nullptr, 0); } D o not w rite letters here. Instead, clearly circle one best response for each question CSE 381 Exam #1 Miami University Page 5 of 13 xiv. Assume the following method is being run by a process. Excluding this parent process (i.e., the process that is initially running the method below), the total number of additional child processes created would be: A. 7 B. 5 C. 3 D. This program is wrong (as return value of fork is not used) xv. The correct bash command to write the output of the ps command to a file named output.txt is: A. ps > output.txt B. ps < output.txt C. ps | output.txt D. ps output.txt xvi. The return value of the fork (system call) is: E. Zero in the child process F. Zero in the parent process G. Fork never returns on success H. The return value depends on the program being run xvii. The following for-loop that iterates over a string. It works just fine. However, the compiler generates a warning – “warning: comparison between signed and unsigned integer expressions”. The correct solution to fix this issue would be: A. Change int to size_t B. Change the string to const C. It is incorrect to modify the string D. Use a suitable type cast for comparison void forkyMon() { fork(); fork(); fork(); } std::string str = "some data"; for (int i = 0; (i < str.size()); i++) { str[i] = '*'; } D o not w rite letters here. Instead, clearly circle one best response for each question CSE 381 Exam #1 Miami University Page 6 of 13 xviii. All of us get only one chance to make a good "first impression". When your prospective employer looks at an example source code (or program) you have developed, the first thing that people see is: A. Style and formatting B. If the program runs correctly C. If the source code is available on the internet D. If the source code compiles. xix. The value stored in variable s shown below is (Note: sub-string in C++ has different parameters than Java) A. “234” B. “23” C. “123” D. This is an invalid method call xx. Given the following declaration, which of the following is a valid method call? A. callMe(); B. callMe(os, str, i); C. callMe(std::cin, “***”, 10); D. callMe(os = std::cout, str = "", i = 5); std::string str = "123456789"; std::string s = str.substr(1, 3); void callMe(std::ostream& os = std::cout, const std::string& str = "", int i = 5); CSE 381 Exam #1 Miami University Page 7 of 13 Short Answer Questions [12 points] 2. Briefly (1 sentence each) the key steps involved in Booting an operating system? [4 points] • First the BIOS runs and initializes the hardware • BIOS loads the 1st stage boot loader from the primary boost device • The 1st stage boot loader runs and loads 2nd stage boot loader • The 2nd stage boot loader loads the OS kernel • The kernel loads device drivers that initialize all the hardware • The kernel then starts up system programs • The user is prompted to login 3. What does the const at the end of members methods in C++ indicate – as in what can/cannot such methods do? [4 points] Constant methods are methods can be called on both constant and non-constant objects. A constant method guarantees that it will never directly or indirectly (by calling other non-const methods) modify instance variables in the object, thereby ensuring the object is not mutated (i.e., changed/modified). No, other languages like Java, Python, C# etc. do not have such a robust const methods – thereby preventing programmers from developing good APIs and robust solutions. 4. What is a system call and how does it operate to permit the execution of privileged operations on behalf of a user (maximum 2-to-3 sentences)? [4 points] The operation through which an user-application interacts with an OS is called a system call. When a process makes a system call (aka syscall) there is switch from user-space (ring 3) to kernel-space (ring 0) and the system call actually runs in kernel space (ring 0). Once the OS has completed the system call it switches back to user- space. CSE 381 Exam #1 Miami University Page 8 of 13 Linux questions [10 points] 5. A GNU/Linux server has three users alice, bob, and eve. Only alice and bob are part of a group named friends. Show the permissions (in the form rwxrwxrwx) for the following 2 files such that: [5 points] a. All three can read and execute file1.txt, but none can write to it b. alice can only read and bob can only write to file2.txt, while eve has no permissions r-x r-x r-x alice friends 280 Mar 3 18:00 file1.txt r-- -w- --- alice friends 1120 Mar 3 18:00 file2.txt 6. Assume you are given a text file named courses.txt in CSV (comma separated values) format. The columns are in the order -- number,name,id,instructor,col lege. Using Linux commands, show 1 software pipeline to print names (2nd column) of all CSE courses (i.e., the 1st column starts with "cse") taught in college “cec” (last column). For example, given adjacent data, the expected output is shown. [5 points] $ cut -d”,” -f1,2,5 | grep “,cec” | grep “cse” | cut -d”,” -f2 $ cut -d”,” -f1,2,5 | grep “,cec$” | grep “^cse” | cut -d”,” -f2 cse278,Systems 1,054,Rao,cec cec101,Intro.course,101,Krumpe,fsb cec140,GCSP,140,cecil,cec cse301,Software,103,Kiper,fsb ece102,Intro. course,102,Jamieson,cec cse381,Systems 2,054,Johnson,cec cse443,HPC,054,Rao,fsb Systems 1 Systems 2 CSE 381 Exam #1 Miami University Page 9 of 13 Programming questions [38 points] 7. Assume the main method below is begin run in the grandparent process labeled ①. Complete the main method below, to create the process hierarchy shown in the adjacent figure. You don't need to show the associated waitpid calls. Note: This is an advanced course. Hence, full points are assigned only for correct and concise solutions. [6 points] // Assume all #include s are here! int main(int argc, char *argv[]) { if (fork() != 0) { // Created 2, and in 1 to create 3 & 4 if (fork() == 0) { // Running on 3 if (fork() != 0) { // Create 4 wait(nullptr); // Wait for 4 in 3 } } else { wait(nullptr); // wait for 3 in 1 } wait(nullptr); // wait for 2 in 1 } return 0; } CSE 381 Exam #1 Miami University Page 10 of 13 8. A standard GNU/Linux groups file is being obtained from a standard HTTP web-server as shown in the starter code below. Complete the main method to process the groups' data and print group-names in which two given users, specified as 2-command line arguments, are both members. For example, given the following response from the web-server, the expected output is shown further below. [10 points] HTTP 200 OK Content-Type: text/plain ... (many HTTP response headers removed for brevity) Content-Length: 282 Server: Apache Expected output: faculty linux labs bin:x:1: faculty:xx:2:raodm,kiperjd,davisk4,femianjc,campbest,crossv,ahmede staff:x123:3:lewisjp3,raodm linux:xab:102:campbest,femianjc,ahmede,raodm admin:xabcdefg:5:campbest,lewisjp3,root theory:x:6:davisk4,inclezd,raychov,femianjc labs:yy:7:raodm,lewisjp3,davisk4,campbest,crossv,ahmede Note: This is an advanced course and hence, full points are reserved for a concise solution. // Assume all #include s are here! int main(int argc, char *argv[]) { const std::string host = "www.users.miamioh.edu"; tcp::iostream is(host, "80"); is << "GET /raodm/groups.txt HTTP/1.1\r\n" << "Host: " << host << "\r\n" << "Connection: Close\r\n\r\n"; const std::string user1 = std::string(argv[1]) + ","; const std::string user2 = std::string(argv[2]) + ","; // Skip over the HTTP-response headers for (std::string hdr; std::getline(is, hdr) && !hdr.empty() && hdr != "\r";) {} // Process each group line for (std::string line; std::getline(is, line);) { line += ','; // Ease correct matching if ((line.find(user1) != std::string::npos) && (line.find(user2) != std::string::npos)) { std::cout << line.substr(0, line.find(':')) << '\n'; } } return 0; } Example output: $ ./ex1 23 5741 18 3347 23: terminated 5741: not terminated 18: not terminated 3347: terminated CSE 381 Exam #1 Miami University Page 11 of 13 9. Assume process hierarchy information has been stored in a simple text file with 3 columns, in the order process id (pid), parent-process id (ppid), and command (cmd) as shown in the adjacent example. Implement the load and printHierarchy methods in the Proc class. a. Concisely implement the load method [6 points]. An example of data loaded in the above two unordered maps by the load method is shown in the figure below. b. Concisely implement the printHierarchy method to print (to std::cout) the complete process hierarchy for a given pid [6 points]. For example, given the above example unordered maps, and pid = 5 (the process hierarchy is 1 → 7 → 5), the method should print (note the parent-to-child order for printing) as shown in the adjacent figure. Note: Thinking recursively makes the printHierarchy method very concise. Do not hard code to given values. They are just examples. Your solution must work with any given valid data — yes, for this method you may assume the 2 unordered maps will always contain valid values. void Proc::load(const std::string& fileName) { std::ifstream is(fileName); int pid, ppid; std::string cmd; while (is >> pid >> ppid >> cmd) { pid2ppid[pid] = ppid; pid2cmd[pid] = cmd; } } void Proc::printHierarchy(int pid) const { // Implement this method to print the full process heirearchy // in a parent-to-child order. if (pid2ppid.find(pid) != pid2ppid.end()) { // First print parent information. printHierarchy(pid2ppid.at(pid)); // Print information about this process std::cout << pid << " " << pid2cmd.at(pid) << std::endl; } } 7 1 /usr/lib/logind 1235 2000 chorme ... (many removed for brevity) 5 7 /bin/bash ... (many removed for brevity) 1 0 /sbin/init ... (many removed brevity) class Proc { public: void load(const std::string& fileName = "process_list.txt"); void printHierarchy(int pid) const; private: /** Maps a process ID (pid) to its parent-process ID (ppid) */ std::unordered_mapint> pid2ppid; /** Maps a pid to the command it is running */ std::unordered_mapstd::string> pid2cmd; }; 1 /sbin/init 7 /usr/lib/logind 5 /bin/bash CSE 381 Exam #1 Miami University Page 12 of 13 10. On GNU/Linux each process is assigned a unique process ID (pid) in the range 1 to 65,535. The ps -er -p command can be used to check if a given process is running – e.g., ps -er -p 123 yields an exit code of 0 (zero) if the process with pid 123 is in running state or a non-zero exit code if the process 123 is not in running state. Using the above information, complete the program below to print the PIDs (one per line) of all running processes, as shown in the adjacent sample output. Note: This is an advanced course. Hence full points are assigned only to concise solutions. int main(int argc, char *argv[]) { for (int i = 1; (i < 65'535); i++) { std::string checkPid = std::to_string(i); int childPid = fork(); if (childPid == 0) { execlp("ps", "ps", "-er", "-p", &checkPid[0], nullptr); } int exitCode = -1; waitpid(childPid, &exitCode, 0); if (exitCode == 0) { std::cout << i << std::endl; } } return 0; } $ ./exam1 0 5 100 123 … CSE 381 Exam #1 Miami University Page 13 of 13 Blank Worksheet 欢迎咨询51作业君