Tuesday, 23 February 2016

Is there any way for a function that is called by main to examine the command-line arguments without (a) passing argc and argv as arguments from main to the function or (b) having main copy argc and argv into global variables?

On most UNIX systems, there is no way to do this. Copies of 'argc' and 'argv' are not kept in global variables like environ is.

When is the output from the printfs in Figure 7.3 actually output?

When the program is run interactively, standard output is usually line buffered, so the actual output occurs when each newline is output. If standard output were directed to a file, however, it would probably be fully buffered, and the actual output wouldn’t occur until the standard I/O cleanup is performed.

Write your own dup2 function that performs the same service as the dup2 function described in Section 3.12, without calling the fcntl function. Be sure to handle errors correctly.

An existing file descriptor is duplicated by either of the following functions:
#include <unistd.h>
int dup(int fd);
int dup2(int fd, int fd2);
Both return: new file descriptor if OK, −1 on error
The new file descriptor returned by dup is guaranteed to be the lowest-numbered
available file descriptor. With dup2, we specify the value of the new descriptor with the
fd2 argument. If fd2 is already open, it is first closed. If fd equals fd2, then dup2 returns
fd2 without closing it. Otherwise, the FD_CLOEXEC file descriptor flag is cleared for fd2,
so that fd2 is left open if the process calls exec.
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include    <stdio.h>
#include <unistd.h>

char arr[] = "my name is mydup\n";

int main()
{
    int fd1, fd2;

    char pidstr[128] = "\0";
    fd1 = open ("~/test/file_for_dup", O_CREAT|O_RDWR);
    if (fd1 < 0) {
        perror ("open");
        exit(-1);
    }

    sprintf (pidstr, "/proc/self/fd/%d", fd1);
    printf ("pidstr: %d %s\n", fd1, pidstr);
    write (fd1, arr, sizeof(arr));
    fd2 = open (pidstr, O_RDWR);
    if (fd2 < 0) {
        perror ("open");
        exit(-1);
    }
    lseek (fd2, sizeof (arr), SEEK_SET);
    write (fd2, arr, sizeof(arr));
    close (fd2);
    close (fd1);

}

Assume that a process executes the following three function calls: fd1= open(pathname, oflags); fd2 = dup(fd1); fd3 = open(pathname, oflags); Draw the resulting picture, similar to Figure 3.8. Which descriptors are affected by an fcntl on fd1 with a command of F_SETFD? Which descriptors are affected by an fcntl on fd1 with a command of F_SETFL?

 Each call to open gives us a new file table entry. But since both opens reference the same file, both file table entries point to the same v-node table entry. The call to dup references the existing file table entry. We show this in Figure C.2. An F_SETFD on fd1 affects only the file descriptor flags for fd1. But an F_SETFL on fd1 affects the file table entry that both fd1 and fd2 point to.
Figure C.2. Result of dup and open






The following sequence of code has been observed in various programs: dup2(fd,0); dup2(fd,1); dup2(fd,2); if (fd > 2) close(fd); To see why the if test is needed, assume that fd is 1 and draw a picture of what happens to the three descriptor entries and the corresponding file table entry with each call to dup2. Then assume that fd is 3 and draw the same picture.

If fd is 1, then the dup2(fd, 1) returns 1 without closing descriptor 1. (Remember our discussion of this in Section 3.12.) After the three calls to dup2, all three descriptors point to the same file table entry. Nothing needs to be closed.
If fd is 3, however, after the three calls to dup2, four descriptors are pointing to the same file table entry. In this case, we need to close descriptor 3.

The Bourne shell, Bourne-again shell, and Korn shell notation digit1>&digit2 says to redirect descriptor digit1 to the same file as descriptor digit2. What is the difference between the two commands ./a.out > outfile 2>&1 ./a.out 2>&1 > outfile

Since the shells process their command line from left to right, the command
./a.out > outfile 2>&1
first sets standard output to outfile and then dups standard output onto descriptor 2 (standard error). The result is that standard output and standard error are set to the same file. Descriptors 1 and 2 both point to the same file table entry. With
./a.out 2>&1 > outfile
however, the dup is executed first, causing descriptor 2 to be the terminal (assuming that the command is run interactively). Then standard output is redirected to the file outfile. The result is that descriptor 1 points to the file table entry for outfile, and descriptor 2 points to the file table entry for the terminal