system calls resources

Upload: takeaxe

Post on 04-Apr-2018

217 views

Category:

Documents


0 download

TRANSCRIPT

  • 7/31/2019 System Calls Resources

    1/15

    System Calls

    System calls are special set of functions available in several programming languages. They are used by

    programs to communicate directly with an operating system. The operating system communicates back

    to the user's program through the return value of the function.

    Generally, system calls are slower than normal function calls. The reason is because when you call a

    system call, control is relinquished to the operating system to perform the system call. In addition,

    depending on the nature of the system call, your program may be blocked by the OS until the system

    call has finished, thus making the execution time of your program even longer.

    One rule of thumb should always be followed when calling a system call: Always check the return value.

    The return value is the only method that the operating system has to communicate information to your

    program. Thus, you should always check the return value in the event that the system call failed.

    system() :

    The system() call will execute an OS shell command as described by a character

    command string. This function is implemented using fork(), exec() and waitpid(). The

    command string is executed by calling /bin/sh -c command-string. During execution of

    the command, SIGCHLD will be blocked, and SIGINT and SIGQUIT will be ignored. The

    call "blocks" and waits for the task to be performed before continuing.

    1 #include

    2 #include

    3 main()

    4 {

    5 system("ls -l");

    6 printf("Command done!");

  • 7/31/2019 System Calls Resources

    2/15

    7 }

    The statement "Command done!" will not print untill the "ls -l" command has completed.

    fork():

    The fork() system call will spawn a new child process which is an identical process to

    the parent except that has a new system process ID. The process is copied in memory

    from the parent and a new process structure is assigned by the kernel. The return value

    of the function is which discriminates the two threads of execution. A zero is returned by

    the fork function in the child's process.

    The environment, resource limits, umask, controlling terminal, current working directory,

    root directory, signal masks and other process resources are also duplicated from the

    parent in the forked child process.

    [Potential Pitfall]: Some memory duplicated by a forked process such as file pointers,

    will cause intermixed output from both processes. Use the wait() function so that the

    processes do not access the file at the same time or open unique file descriptors. Some

    like stdout or stderr will be shared unless synchronized using wait() or some other

    mechanism. The file close on exit is another gotcha. A terminating process will close

    files before exiting. File locks set by the parent process are not inherited by the child

    process.

    [Potential Pitfall]: Race conditions can be created due to the unpredictability of when the

    kernel scheduler runs portions or time slices of the process. One can use wait(). the

    use of sleep() does not guarentee reliability of execution on a heavily loaded system as

    the scheduler behavior is not predictable by the application.

    The fork() System Call

  • 7/31/2019 System Calls Resources

    3/15

    System call fork() is used to create processes. It takes no arguments and returns a process ID. The

    purpose offork() is to create a new process, which becomes the childprocess of the caller. After a

    new child process is created, both processes will execute the next instruction following thefork()

    system call. Therefore, we have to distinguish the parent from the child. This can be done by

    testing the returned value offork():

    Iffork() returns a negative value, the creation of a child process wasunsuccessful.

    fork() returns a zero to the newly created child process.

    fork() returns a positive value, theprocess ID of the child process, to the

    parent. The returned process ID is of type pid_t defined in sys/types.h.Normally, the process ID is an integer. Moreover, a process can use functiongetpid() to retrieve the process ID assigned to this process.

    Therefore, after the system call to fork(), a simple test can tell which process is the

    child. Please note that Unix will make an exact copy of the parent's address

    space and give it to the child. Therefore, the parent and child processeshave separate address spaces.

    Let us take an example to make the above points clear. This example does not distinguish parent

    and the child processes. Clickhereto download this file fork-01.c.

    #include #include #include

    #define MAX_COUNT 200

    #define BUF_SIZE 100

    void main(void){

    pid_t pid;int i;char buf[BUF_SIZE];

    fork();pid = getpid();for (i = 1; i

  • 7/31/2019 System Calls Resources

    4/15

    If the call to fork() is executed successfully, Unix will

    make two identical copies of address spaces, one for the parent and the otherfor the child.

    Both processes will start their execution at the next statement following thefork() call. In this case, both processes will start their execution at theassignment statement as shown below:

    Both processes start their execution right after the system call fork(). Since both processes haveidentical but separate address spaces, those variables initialized before the fork() call have the

    same values in both address spaces. Since every process has its own address space, any

    modifications will be independent of the others. In other words, if the parent changes the value of

    its variable, the modification will only affect the variable in the parent process's address space.Other address spaces created by fork() calls will not be affected even though they have identical

    variable names.

  • 7/31/2019 System Calls Resources

    5/15

    What is the reason of using write rather than printf? It is because printf() is "buffered," meaning

    printf()will group the output of a process together. While buffering the output for the parent

    process, the child may also use printf to print out some information, which will also be buffered.As a result, since the output will not be send to screen immediately, you may not get the right order

    of the expected result. Worse, the output from the two processes may be mixed in strange ways. To

    overcome this problem, you may consider to use the "unbuffered" write.

    If you run this program, you might see the following on the screen:

    ................This line is from pid 3456, value 13This line is from pid 3456, value 14

    ................This line is from pid 3456, value 20This line is from pid 4617, value 100This line is from pid 4617, value 101

    ................This line is from pid 3456, value 21

    This line is from pid 3456, value 22................

    Process ID 3456 may be the one assigned to the parent or the child. Due to the fact

    that these processes are run concurrently, their output lines are intermixed in a

    rather unpredictable way. Moreover, the order of these lines are determined by the

    CPU scheduler. Hence, if you run this program again, you may get a totally different

    result.

    Consider one more simple example, which distinguishes the parent from the child. Clickhereto

    download this file fork-02.c.

    #include #include

    #define MAX_COUNT 200

    void ChildProcess(void); /* child process prototype */void ParentProcess(void); /* parent process prototype */

    void main(void){

    pid_t pid;

    pid = fork();

    if (pid == 0)ChildProcess();else

    ParentProcess();}

    void ChildProcess(void){

    int i;

    http://www.csl.mtu.edu/cs4411/www/NOTES/process/fork/fork-02.chttp://www.csl.mtu.edu/cs4411/www/NOTES/process/fork/fork-02.chttp://www.csl.mtu.edu/cs4411/www/NOTES/process/fork/fork-02.c
  • 7/31/2019 System Calls Resources

    6/15

    for (i = 1; i

  • 7/31/2019 System Calls Resources

    7/15

    In the parent, since pid is non-zero, it calls function ParentProcess(). On the other hand, the childhas a zero pid and calls ChildProcess() as shown below:

    Due to the fact that the CPU scheduler will assign a time quantum to each process, the parent orthe child process will run for some time before the control is switched to the other and the running

    process will print some lines before you can see any line printed by the other process. Therefore,

    the value ofMAX_COUNT should be large enough so that both processes will run for at least two

  • 7/31/2019 System Calls Resources

    8/15

    or more time quanta. If the value ofMAX_COUNT is so small that a process can finish in one

    time quantum, you will see two groups of lines, each of which contains all lines printed by the

    same process

    The getpid() system call returns the process ID of the calling process.Though the ID is guaranteed to be unique, it should NOT be used for con-

    structing temporary file names, for security reasons; see mkstemp(3)instead.

    The getppid() system call returns the process ID of the parent of thecalling process.

    Open

    open is a system call that is used to open a new file and obtain its file descriptor.

    Function Definition

    int open(const char *path, int oflags);int open(const char *path, int oflags, mode_t mode);

    Field Description

    const char*path

    The relative or absolute path to the file that is to be opened.

    int oflagsA bitwise 'or' separated list of values that determine the method in which the file is to beopened (whether it should be read only, read/write, whether it should be cleared whenopened, etc). See a list of legal values for this field at the end.

    mode_t modeA bitwise 'or' separated list of values that determine the permissions of the file if it is created.See a list of legal values at the end.

    return value

    Returns the file descriptor for the new file. The file descriptor returned is always the smallest

    integer greater than zero that is still available. If a negative value is returned, then there wasan error opening the file.

    Code Snippet

    Example using the open system call:

    #include #include int main(){

    size_t filedesc = open("testfile.txt", O_WRONLY | O_APPEND);

    http://fuse4bsd.creo.hu/localcgi/?mkstemp+3http://codewiki.wikidot.com/system-callshttp://fuse4bsd.creo.hu/localcgi/?mkstemp+3http://codewiki.wikidot.com/system-calls
  • 7/31/2019 System Calls Resources

    9/15

    if(filedesc < 0) return1;

    if(write(filedesc,"This will be output to testfile.txt\n", 36) != 36){

    write(2,"There was an error writing to testfile.txt\n",43); return1;

    }

    return0;}

    Available Values foroflag

    Value Meaning

    O_RDONLY Open the file so that it is read only.

    O_WRONLY Open the file so that it is write only.

    O_RDWR Open the file so that it can be read from and written to.

    O_APPEND Append new information to the end of the file.

    O_TRUNC Initially clear all data from the file.

    O_CREATIf the file does not exist, create it. If the O_CREAT option is used, then you must include thethird parameter.

    O_EXCLCombined with the O_CREAT option, it ensures that the caller must create the file. If the filealready exists, the call will fail.

    Available Values formode

    Value Meaning

    S_IRUSR Set read rights for the owner to true.

    S_IWUSR Set write rights for the owner to true.

    S_IXUSR Set execution rights for the owner to true.

    S_IRGRP Set read rights for the group to true.

    S_IWGRP Set write rights for the group to true.

    S_IXGRP Set execution rights for the group to true.

    S_IROTH Set read rights for other users to true.

  • 7/31/2019 System Calls Resources

    10/15

    S_IWOTH Set write rights for other users to true.

    S_IXOTH Set execution rights for other users to true.

    Close

    close is asystem call that is used to close an open file descriptor.

    Required Include Files

    #include

    Function Definition

    int close(int fildes);

    Field Description

    int fildes The file descriptor to be closed.

    return valueRetuns a 0 upon success, and a -1 upon failure. It is important to check the return value,

    because some network errors are not returned until the file is closed.

    Code Snippet

    Example closing an open file descriptor:

    #include #include int main(){

    size_t filedesc = open("testfile.txt", O_WRONLY | O_CREAT); if(filedesc < 0) return1;

    if(close(filedesc) < 0) return1;

    return0;

    }

    Write

    write is asystem call that is used to write data out of a buffer.

    http://codewiki.wikidot.com/system-callshttp://codewiki.wikidot.com/system-callshttp://codewiki.wikidot.com/system-callshttp://codewiki.wikidot.com/system-callshttp://codewiki.wikidot.com/system-callshttp://codewiki.wikidot.com/system-calls
  • 7/31/2019 System Calls Resources

    11/15

    Required Include Files

    #include

    Function Definition

    size_t write(int fildes, const void *buf, size_t nbytes);

    Field Description

    int fildesThe file descriptor of where to write the output. You can either use a file descriptor obtainedfrom the open system call, or you can use 0, 1, or 2, to refer to standard input, standardoutput, or standard error, respectively.

    const void*buf

    A null terminated character string of the content to write.

    size_t nbytes The number of bytes to write. If smaller than the provided buffer, the output is truncated.

    return valueReturns the number of bytes that were written. If value is negative, then the system callreturned an error.

    Code Snippet

    Example using standard file descriptors:

    #include int main(void)

    { if (write(1, "This will be output to standard out\n", 36) != 36) {write(2, "There was an error writing to standard out\n", 44);

    return -1;}

    return0;

    }

    Example using a file descriptor:

    #include #include

    int main(void){

    int filedesc = open("testfile.txt", O_WRONLY | O_APPEND);

    if (filedesc < 0) { return -1;

    }

    http://codewiki.wikidot.com/c:system-calls:openhttp://codewiki.wikidot.com/c:system-calls:open
  • 7/31/2019 System Calls Resources

    12/15

    if (write(filedesc, "This will be output to testfile.txt\n", 36) != 36) {write(2, "There was an error writing to testfile.txt\n", 43);

    return -1;}

    return0;

    }

    Read

    read is a system call used to read data into a buffer.

    Required Include Files

    #include

    Function Definition

    size_t read(int fildes, void *buf, size_t nbytes);

    Field Description

    int fildesThe file descriptor of where to write the output. You can either use a file descriptor obtainedfrom the open system call, or you can use 0, 1, or 2, to refer to standard input, standardoutput, or standard error, respectively.

    const void*buf

    A character array where the read content will be stored.

    size_t nbytesThe number of bytes to read before truncating the data. If the data to be read is smaller thannbytes, all data is saved in the buffer.

    return valueReturns the number of bytes that were read. If value is negative, then the system callreturned an error.

    Code Snippet

    #include int main()

    {char data[128];

    if(read(0, data, 128) < 0)

    write(2, "An error occurred in the read.\n", 31);

    exit(0);}

    http://codewiki.wikidot.com/system-callshttp://codewiki.wikidot.com/c:system-calls:openhttp://codewiki.wikidot.com/system-callshttp://codewiki.wikidot.com/c:system-calls:open
  • 7/31/2019 System Calls Resources

    13/15

    Stat

    stat is a system call that is used to determine information about a file based on its file path.

    Required Include Files#include #include #include

    Function Definition

    int stat(const char *path, struct stat *buf);

    Field Description

    const char*path The file descriptor of the file that is being inquired.

    struct stat *bufA structure where data about the file will be stored. A detailed look at all of the fields in thisstructure can be found in the struct stat page.

    return value Returns a negative value on failure.

    Code Snippet

    An example of code that uses the stat() system call is below.

    #include #include #include #include int main(int argc, char **argv){ if(argc != 2)

    return1;

    struct stat fileStat; if(stat(argv[1],&fileStat) < 0)

    return1;

    printf("Information for %s\n",argv[1]);printf("---------------------------\n");printf("File Size: \t\t%d bytes\n",fileStat.st_size);printf("Number of Links: \t%d\n",fileStat.st_nlink);printf("File inode: \t\t%d\n",fileStat.st_ino);

    printf("File Permissions: \t");printf( (S_ISDIR(fileStat.st_mode)) ? "d" : "-");

    http://codewiki.wikidot.com/system-callshttp://codewiki.wikidot.com/c:struct-stathttp://codewiki.wikidot.com/system-callshttp://codewiki.wikidot.com/c:struct-stat
  • 7/31/2019 System Calls Resources

    14/15

    printf( (fileStat.st_mode & S_IRUSR) ? "r" : "-");printf( (fileStat.st_mode & S_IWUSR) ? "w" : "-");printf( (fileStat.st_mode & S_IXUSR) ? "x" : "-");printf( (fileStat.st_mode & S_IRGRP) ? "r" : "-");printf( (fileStat.st_mode & S_IWGRP) ? "w" : "-");printf( (fileStat.st_mode & S_IXGRP) ? "x" : "-");printf( (fileStat.st_mode & S_IROTH) ? "r" : "-");printf( (fileStat.st_mode & S_IWOTH) ? "w" : "-");printf( (fileStat.st_mode & S_IXOTH) ? "x" : "-");printf("\n\n");

    printf("The file %s a symbolic link\n", (S_ISLNK(fileStat.st_mode)) ? "is"

    : "is not");

    return0;}

    The output of this program is shown in the following set of commands:

    Information on the current files in the directory:

    $ ls -ltotal 16-rwxr-xr-x 1 stargazer stargazer 36 2008-05-06 20:50 testfile.sh-rwxr-xr-x 1 stargazer stargazer 7780 2008-05-07 12:36 testProgram-rw-r--r-- 1 stargazer stargazer 1229 2008-05-07 12:04 testProgram.c

    Running the program with the file testfile.sh

    $ ./testProgram testfile.sh

    Information for testfile.sh---------------------------File Size: 36 bytesNumber of Links: 1File inode: 180055File Permissions: -rwxr-xr-x

    The file is not a symbolic link

    Running the program with the files testProgram.c

    $ ./testProgram testProgram.c

    Information for testProgram.c---------------------------File Size: 1229 bytesNumber of Links: 1File inode: 295487File Permissions: -rw-r--r--

    The file is not a symbolic link

  • 7/31/2019 System Calls Resources

    15/15

    Running the program with the directory /home/stargazer

    $ ./testProgram /home/stargazer

    Information for /home/stargazer---------------------------

    File Size: 4096 bytesNumber of Links: 61File inode: 32706File Permissions: drwxr-xr-x

    The file is not a symbolic link

    wait():

    The parent process will often want to wait until all child processes have been

    completed. this can be implemented with the wait() function call.

    wait(): Blocks calling process until the child process terminates. If child process has

    already teminated, the wait() call returns immediately. if the calling process has multiple

    child processes, the function returns when one returns