1 / 9

Exec function :

Exec function : - replaces the current process (its code, data, stack & heap segments) with a new program - the new program starts executing at its main function - pid of the process isn’t changed Note: exec is usually used after fork(), when we want a child process to execute some program.

yadid
Download Presentation

Exec function :

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Exec function: - replaces the current process (its code, data, stack & heap segments) with a new program - the new program starts executing at its main function- pid of the process isn’t changed Note: exec is usually used after fork(), when we want a child process to execute some program. exec(l/v)(e/p) (path/filename, listOfArgs/ArgvArray, --/(char *) 0, --/environment) There are six different ways to call exec function. Example:we want to create a child process and force it to execute “ls -l” program. char * argv [ ] = { “ls”, “-l”, NULL};char * envp [ ] = { “USER=unknown”, “PATH=/tmp”, NULL};1) execl (“/bin/ls”, “ls”, ”-l”, (char *) 0);2) execlp (“ls”, “ls”, “-l”, (char *) 0);3) execle (“/bin/ls”, “ls”, “-l”, (char *) 0, envp);4) execv (“/bin/ls”, argv);5) execvp (“ls”, argv);6) execve (“/bin/ls”, argv, envp); full path to ls program list of arguments (first argument is a new program name) “end of arguments” delimiter new environment to use

  2. - if the first argument is filename (and not path), o.s. would look for it in all directories that appear in PATH system variable (you can examine this variable using “>echo $PATH” Unix command)- if don’t use exec function with environment option (with “e” at the end of the name), then the environment of the current process is copied to the new process (you can see you shell’s environment using “>set” Unix command) Let’s write a program for this example:#include <unistd.h>int main (void) { pid_t pid; int status; pid = fork (); if (pid == 0) { //childexeclp (“ls”, “ls”, “-l”, (char *) 0); fprintf (stderr, “couldn’t execute: %s”, “ls –l”); exit (-1); // abnormal termination } // there is no need to use “else” because child code was changed ! waitpid (pid, &status, 0) ; exit (0); } If this line is executed, then exec function failed (process code wasn’t changed). So, we print error into stderr and then exit abnormally (exit (-1)). This causes stderr to print the last error it got.

  3. Important: there are some properties that the new process image inherits from the calling process:- pid & ppid- time left until alarm clock- current working directory- process signal mask- pending signals- file descriptors (by default, they are left opened) Notes:1. usually only execve is a system call. The other five are just library functions that eventually invoke this system call2. see shell.c & exec.c programs (from maman13 material) for more examples(we would also learn them in class). Pay attention that shell.c can’t execute commands with parameters because of the way it passes arguments to execlp. FIFO - named pipes:- is a type of file- is used by unrelated processes to exchange data int mkfifo (const char * pathname, mode_t mode)

  4. - pathname is a path to a file name, that would represent a fifo - mode is permissions set (for user, group and others) - return value: 0 if OK, -1 on error. Example: mkfifo (“myFifo”, S_IRUSR | S_IWUSR| S_IRGRP | S_IWGRP); In this example we created fifo that is represented by the file “myFifo” (in the current working directory), with the following permissions set: user can read & write to fifo, and group can also read & write to it. After we created a fifo, we should open it (like we open a regular file):myFifo = open (“myFifo”, O_RDWR) );In this example we opened fifo for reading and writing to it. After this, we can write some message to it: char *message = “Marina”; write (myFifo, message, strlen(message)+1); Now, another process can read from this fifo. How? It should open the same file (with the same name, that is known for all the processes), and just read from it:myFifo = open (“myFifo”, O_RDWR) ); read (myFifo, buf, 100); // assuming that maximal message length is 100

  5. Important: when open fifo file with O_RDONLY permission, the process would be blocked until some other process would open the same fifo file for writing, and write something into it. In order to avoid this, we should use select() function: int select (int maxpdp1, fd_set *readfds, fd_set *readfds, fd_set *readfds, struct timeval *tvptr) Example: mkfifo (“myFifo”, S_IRUSR | S_IWUSR| S_IRGRP | S_IWGRP); myFifo = open (“myFifo”, O_RDWR) ); fd_set r_set; FD_ZERO (&r_set); FD_SET (myFifo, &r_set ); select (myFifo+1, &r_set, NULL, NULL, NULL); In this example we create a set r_set, that would contain fifo file descriptor (the one we want to read from it). Third and fourth parameters are NULLs (file descriptors sets for another purposes).Fifth parameter defines if we would block on select system call or not: - NULL - block till get some message to read in fifo - empty struct timeval (zero values for each member) – returns immediately macro that set zeros to r_set macro that add file descriptor to r_set

  6. - non empty struct timeval – returns after the given time First parameter is the maximal file descriptor in all the sets (since we can wait for messages from several fifo files, just by adding them to r_set, this function need to know the maximal file descriptor from all the fifo files in all the sets).Return value: 0 on success, -1 on failure. struct timeval { long tv_sec; // seconds long tv_usec; // microseconds} Example: struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 20;select (myFifo+1, &r_set, NULL, NULL, &tv); In this example, a process would be blocked by select () system call only for 20 microseconds, and then would return with success (0 return value) or error (-1 return value). Use myDeamon.c & myClient.c files to learn more about this topic.myClient sends message to myDeamon using one fifo, and myDeamon returns this message to myClient using another fifo.

  7. In order to run these programs: - open two consoles - compile both myDeamon.c & myClient.c ( get two executable files ) - on one console run myDeamon > myDeamon - on the second console run myClient > myClient Marina Now you should get the following output: - on myDeamon console: > well known fifo established got the message: Marina, message length is: 6 wrote to pfifo 7 chars - on myClient console: > read 7 chars from pfifo Marina Notes: - for some reasons, fifo can be broken (closed, error when opened, etc). You should catch SIGPIPE signal in order to prevent your program to crash because of a broken fifo (just create signal handler for this signal, that exit the program when catch this signal). - when you write a message to fifo, it can’t be bigger than PIPE_BUF size (constant that is defined in <limits.h> file).

  8. Note: I strongly recommend you to build your maman based on this example (it is pretty similar to what you have to do). Time function: - gets the number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC from the system clocktime_t time (time_t * timer) - save the time in timer - if send NULL argument, the time wouldn’t be saved, but still be returned value Example: #include <stdio.h>#include <time.h> int main () { time_t seconds; seconds = time (NULL); printf (“%ld hours since January 1, 1970\n”, seconds / 3600); }

  9. Dup function: - duplicates an existing file descriptor - a new descriptor that returns is the first free file descriptor - a new descriptor points to the same file (there is no two files) int dup (int fd); - fd is a file descriptor that we want to duplicate Example: myFifo = open (“myFifo”, O_RDWR); close(1); dup (myFifo ); close (myFifo ); In this example we open a fifo. Then we close stdout (with file descriptor = 1), and duplicate myFifo (file descriptor). This causes a duplicate of myFifo to get a file descriptor = 1 (because it is a first free file descriptor) => now, for this process, each printing would be into myFifo file.

More Related