Open the Standard Output and Standard Error Output

Một phần của tài liệu The art of linux kernel design (Trang 197 - 202)

4. Creation and Execution of Process 2 165

4.1 Open the Terminal Device File and Copy the File Handle

4.1.2 Open the Standard Output and Standard Error Output

In Section 4.1.1, opening the standard input device file using the function open was intro- duced. We will open the standard output and standard error output device file. The differ- ence here is the method of copying the file handle.

After the function open() returns, process 1 copies the file handle twice according to calling the function dup() based on the condition that the tty0 device file is opened.

The code of the first copy is as follows:

current->tty = MINOR(inode->i_zone[0]);

tty_table[current->tty].pgrp = current->pgrp;

}

} else if (MAJOR(inode->i_zone[0]) = =5) if (current->tty<0) {

iput(inode);

current->filp[fd] = NULL;

f->f_count = 0;

return -EPERM;

}

/* Likewise with block-devices: check for floppy_change */

if (S_ISBLK(inode->i_mode))

check_disk_change(inode->i_zone[0]);

f->f_mode = inode->i_mode; //set file attributes based on file i node

//attributes

f->f_flags = flag; //set file ID according to parameter flag f->f_count = 1; //the file reference count is incremented f->f_inode = inode; //build relationship between file and

//i-node

f->f_pos = 0; //set file write and read pointer as 0 return (fd);

}

//code path:init/main.c:

void init(void) {

int pid,i;

setup((void *) &drive_info);

(void) open(“/dev/tty0”,O_RDWR,0);

(void) dup(0);//copy the handle to build the standard output device (void) dup(0);

printf(“%d buffers =%d bytes buffer space\n\r”,NR_BUFFERS, NR_BUFFERS*BLOCK_SIZE);

printf(“Free mem:%d bytes\n\r”,memory_end-main_memory_start);

if (!(pid=fork())) {//below if is code of process 2 close(0);

if (open(“/etc/rc”,O_RDONLY,0))

The function dup will eventually be mapped to the system calling function sys_dup() (this mapping process is broadly consistent with the mapping process from the function open to the function sys_open) and called the function dupfd() to copy the file handle.

The code is as follows:

_exit(1);

execve(“/bin/sh”,argv_rc,envp_rc);

_exit(2);

}

if (pid>0)

while (pid ! = wait(&i)) /* nothing */;

……

}

f_mode f_flags f_count f_inode f_pos

ROM BIOS and VGA

Kernel

Enable interrupt The page that task_struct of process 1 resides

task_struct of process 1

0x00000 0x9FFFF 0xFFFFF 0x3FFFFF 0x5FFFFF 0xFFFFFF

Kernel code area Kernel data area

sys_open i node_table[32] file_table[64]

1 0 Process status

Process 0 Process 1

Interruptible Ready

Current process

Figure 4.8 Set the file_table[64] and return fd.

After ensuring the copying conditions, we will find free item in the filp[20] of process 1 and then get the second item filp[1]. The system copies the pointer of the tty0 device file stored in filp[0] to filp[1] and increases the reference number of the file f_count in file_table[0] to 2 in order to realize the effect that process 1 opens the standard output device file tty0.

The code is as follows:

The situation that opens the standard output device file is shown in Figure 4.9.

When dup returns, process 1 calls it again to copy the file handle for the second time and builds the standard error output device.

The code is as follows:

//code path:fs/fcntl.c:

int sys_dup(unsigned int fildes) //system call function in kernel //corresponding to dup

{

return dupfd(fildes,0);//copy handle }

//code path:fs/fcntl.c:

static int dupfd(unsigned int fd, unsigned int arg) {

if (fd >= NR_OPEN || !current->filp[fd])//Detect whether it has the //conditions to copy the file handle return -EBADF;

if (arg >= NR_OPEN) return -EINVAL;

while (arg < NR_OPEN)

if (current->filp[arg])//find free item in filp[20](it is the //second item) of process 1 to copy arg++;

else break;

if (arg >= NR_OPEN) return -EMFILE;

current->close_on_exec &= ~(1<<arg);

(current->filp[arg] = current->filp[fd])->f_count++;

//copy file handle to build standard output device and set //f_count as 2

return arg;

}

//code path:init/main.c:

void init(void) {

int pid,i;

setup((void *) &drive_info);

(void) open(“/dev/tty0”,O_RDWR,0);

(void) dup(0);//copy handle to build the standard output device (void) dup(0); //copy handle again to build the standard error

//output device

printf(“%d buffers =%d bytes buffer space\n\r”,NR_BUFFERS, NR_BUFFERS*BLOCK_SIZE);

printf(“Free mem:%d bytes\n\r”,memory_end-main_memory_start);

if (!(pid=fork())) {//below if is code of process 2 close(0);

if (open(“/etc/rc”,O_RDONLY,0)) _exit(1);

execve(“/bin/sh”,argv_rc,envp_rc);

_exit(2);

}

if (pid>0)

while (pid !=wait(&i)) /* nothing */;

……

} Kernel

ROM BIOS

and VGA Enable

interrupt The page that task_struct of process 1 resides

task_struct of process 1

0x00000 0x9FFFF 0xFFFFF 0x3FFFFF 0x5FFFFF 0xFFFFFF

Kernel code area Kernel data area

file_table[64]

Process status

Duplicate file handle filp[20]

Process 0 Process 1

Interruptible Ready

Current process

Figure 4.9 Duplicate the filp[fd] and open std output device.

//code path:fs/fcntl.c:

static int dupfd(unsigned int fd, unsigned int arg) {

if (fd >= NR_OPEN || !current->filp[fd])/Detect whether it has //the conditions to copy the file handle

return -EBADF;

if (arg >= NR_OPEN) return -EINVAL;

while (arg < NR_OPEN)

if (current->filp[arg])//find free item in filp[20](it is //the third item) of process 1 //to copy

arg++;

else break;

if (arg >= NR_OPEN) return -EMFILE;

current->close_on_exec &= ~(1<<arg);

(current->filp[arg] = current->filp[fd])->f_count++;

//copy file handle to build standard output device and set //f_count as 3

return arg;

}

//code path:init/main.c:

void init(void) {

int pid,i;

setup((void *) &drive_info);

(void) open(“/dev/tty0”,O_RDWR,0);

(void) dup(0);

(void) dup(0);

printf(“%d buffers =%d bytes buffer space\n\r”,NR_BUFFERS, NR_BUFFERS*BLOCK_SIZE);

printf(“Free mem:%d bytes\n\r”,memory_end-main_memory_start);

if (!(pid=fork())) {//process 1 creates process 2 close(0);

if (open(“/etc/rc”,O_RDONLY,0)) _exit(1);

execve(“/bin/sh”,argv_rc,envp_rc);

_exit(2);

}

if (pid>0)

while (pid ! = wait(&i)) /* nothing */;

……

}

Let us go back to the function dupfd() again. As the procedure shown before, the ker- nel finds free item in the filp[20] of process 1. However, this time, it comes to the third item filp[2]. The system copies the pointer of the tty0 device file stored in filp[0] to filp[2] and increases the reference number of the file f_count in file_table[0] to 3 in order to realize the effect that process 1 opens the standard output device file tty0.

The code is as follows:

The situation that opens the standard output device file is shown in Figure 4.10.

At this point, the terminal standard input device file, standard output device file, and standard error output device file have been opened. It means that, in the program, the function printf can be used later (stdio in stdio.h is standard input/output).

Một phần của tài liệu The art of linux kernel design (Trang 197 - 202)

Tải bản đầy đủ (PDF)

(524 trang)