150 likes | 299 Views
Lecture 25. Today exec() in Unix CreateProcess in Windows Announcements. Creating new processes. How do you “replace” a running process with a new process (new set of instructions) Use the exec function First, create a second version of your process via fork( )
E N D
Lecture 25 • Today • exec() in Unix • CreateProcess in Windows • Announcements
Creating new processes • How do you “replace” a running process with a new process (new set of instructions) • Use the exec function • First, create a second version of your process • via fork( ) • Next, “replace” the contents of this new process with another program • via exec( …)
Exec comes in many flavors (see man exec) We will use execl Specify location of new process (1st arg) Specify name of new process (2nd arg) Specify any arguments passed to new process Specify NULL to end parameter list (3rd arg here) #include <iostream.h> #include <stdlib.h> #include <unistd.h> int main( ) { cout << "hello world" << endl; int pid = fork(); cout<<"PID is "<<pid<<endl; if (pid == 0) execl("/usr/bin/ls","ls",NULL); else cout<<"original proc"<<endl; } Exec function
Before “fork( )” After “fork( )” After “exec( )” One process still contains the original code we started with Other process now has completely different code What happens with “exec” ? int main() { … int pid = fork( ); if (pid == 0) exec( … ) int main() { … int pid = fork( ); if (pid == 0) exec( … ) int main() { … int pid = fork( ); if (pid == 0) exec( … ) int main() { // another program // starts at beginning } int main() { … int pid = fork( ); if (pid == 0) exec( … )
Consider the “print” routine shown below Prints a number N times #include <iostream> #include <stdlib.h> int main(int argc, char *argv[ ]) { // argv[0] is the program name int num = atoi(argv[1]); int loops = atoi(argv[2]); for (int a=0; a<loops; a++) cout << num << " "; } Use “print” in this code #include <iostream.h> #include <stdlib.h> #include <unistd.h> int main() {cout << "hello world" << endl;int pid = fork();cout << “PID is " << pid << endl;if (pid == 0) execl("./print", "print", "1", "100", NULL);else execl("./print", "print", "2", "100", NULL); } Another example with “exec”
Class Exercises • Run the example shown on the previous page • Compile print.C (from previous slide) into an executable “print” • Compile the main program and run it • Try it printing each number • 100 times • 1000 times • 10,000 times • 100,000 times
Creating new processes • Lots of applications where the ability to generate a new process comes in handy • Simple example: command shell in Unix • The “shell” is a C++ program • Basic algorithm • Get a command from user • Interpret the command • Invoke a process to execute this command
Overview Prompt user Get command If not time-to-exit Fork new process Replace new process with either who, ls or uptime Read next command int main() {int cmd, num;cout << "Enter 1=who, 2=ls, 3=uptime -> ";cin >> cmd;while (cmd != 0) { int pid = fork(); if (pid == 0) { if (cmd==1) execl("/usr/bin/who", "who", NULL); if (cmd==2) execl("/usr/bin/ls", "ls", NULL); if (cmd==3) execl("/usr/bin/uptime", "uptime",NULL); exit(1); } cin >> cmd;} } Implementing a simple shell
Class Exercises • Implement the program shown on the previous slide. Run it, and watch its execution. • What happens when you give an invalid number? • Modify the program (add two more commands to the “shell” we are writing), consider: • date • hostname
Programs & Processes • We have seen how to write a program that • When executed, could invoke additional instances of itself (fork) • When executed, could then replace these additional instances with other programs – replace the code in the executing process (exec) • Unix and Windows handle these basic tasks differently
Creating processes in Windows • No exact Windows equivalent of fork and exec • Windows has CreateProcess method • Creates a new process and loads the specified program into that process (one step) • Requires #include <windows.h> • More parameters than fork & exec • Most can be NULL • Just need to specify program to run and a few flags
Need two variables to handle basic info – must initialize correctly Specify the location of the new process (our “print” process from last time) Wait for it to finish #include <windows.h> #include <iostream.h> void main( ) {STARTUPINFO si;PROCESS_INFORMATION pi;ZeroMemory( &si, sizeof(si) );si.cb = sizeof(si);if ( ! CreateProcess( NULL, “..\\print\\debug\\print.exe 5 10", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi) ) cerr << "CreateProcess failed." << endl;WaitForSingleObject( pi.hProcess, INFINITE );CloseHandle( pi.hProcess );CloseHandle( pi.hThread ); } Example using CreateProcess
CreateProcess syntax BOOL CreateProcess ( LPCTSTR lpApplicationName, // pointer to executable module LPTSTR lpCommandLine, // pointer to command line string LPSECURITY_ATTRIBUTES lpProcessAttrib, // process security LPSECURITY_ATTRIBUTES lpThreadAttrib, // thread security BOOL bInheritHandles, // handle inheritance flag DWORD dwCreationFlags, // creation flags LPVOID lpEnvironment, // pointer to new environment block LPCTSTR lpCurrentDirectory, // pointer to current dir name LPSTARTUPINFO lpStartupInfo, // pointer to STARTUPINFO LPPROCESS_INFORMATION lpProcessInformation // pointer to PROCESS_INFORMATION );
Comments on CreateProcess • Can specify program in either 1st or 2nd args • If in first, give location of program to run • If in second, give the command line to execute • Creation flags • If 0, runs in existing window • Also have other flags (combine with | ) • CREATE_NEW_CONSOLE probably most useful • Specify priority, linkage to parent, etc. • Structures pi and si used for process communication (how to start, basic info)
Class Exercises • Write a program (in the Windows VC++ environment) that starts up a copy of notepad as part of its execution • Notepad is located in c:\winnt\ directory • Don’t forget to double the “\” in string literal