NCTU UNIX2020 NOTES

tags: NCTU, Unix Programming

file descriptors

while user open a file, kernel then handle a table called file descriptor table which store the opened file information(i.e., a pointer to the file), and the table index is file descriptor.

So, the file descriptor is a non negative integer.

stdin stdout, stderr

0 stdin
1 stdout
2 stderr

  • redirection
$cat /etc/passwd
$cat < /etc/passwd
$cat /etc/passwd | cat | cat
$cat /etc/passwd | cat | cat > /tmp/p.txt

in the third command, the second cat command's stdin is replace by the first command cat /etc/passwd 's stdout by an interface pipe.

file hole

#include "apue.h“ /* fig 3.2 */
#include <fcntl.h>
char buf1[] = "abcdefghij“, buf2[] = "ABCDEFGHIJ";

int main(void) { 
    int fd;
    if ((fd = creat("file.hole", FILE_MODE)) < 0)
        err_sys("creat error");
    if (write(fd, buf1, 10) != 10)
        err_sys("buf1 write error");
    /* offset now = 10 */
    if (lseek(fd, 16384, SEEK_SET) == -1)
        err_sys("lseek error");
    /* offset now = 16384 */
    if (write(fd, buf2, 10) != 10)
        err_sys("buf2 write error");
    /* offset now = 16394 */
    exit(0);
}
$ ./fig3.2-hole
$ ls -l file.hole
-rw-r--r-- 1 chuang chuang 16394 2009-01-01 11:45 file.hole
$ hexdump -C file.hole
00000000 61 62 63 64 65 66 67 68 69 6a 00 00 00 00 00 00 |abcdefghij......|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00004000 41 42 43 44 45 46 47 48 49 4a |ABCDEFGHIJ|
0000400a
$ cp file.hole file.nohole
$ ls -ls file.*
8 -rw-r--r-- 1 chuang chuang 16394 2009-01-01 11:45 file.hole
20 -rw-r--r-- 1 chuang chuang 16394 2009-01-01 11:49 file.nohole

The file system will create a data block ( usually is 4KB ) to store the first 10 bytes, after the lseek operation, system find that the first data block is not enough to store, so it will create the other block which locate between the first block is 16KB, so the file.hole file actually store 8KB on the system. But the cp command need to parse a file until an EOF, so it will parse totally 20KB and create file.nohole.

read write effection

buff size choose = 4KB( equivalent to kernel block size )

buffer mode

  • fully buffered
    • outout when then buffer is full
  • line buffered
    • output when meet the newline ( i.e., '\n' )
  • unbuffered
    • output immediatly

we could set buffer mode by C library

  • void setbuf(FILE *fp, char *buf)
    • buf must be the size of BUFSIZ
  • int setvbuf(FILE *fp, char *buf, int mode, size_t size)
    • Returns: 0 if OK, nonzero on error

Buffering mode

  • _IOFBF: fully buffered
  • _IOLBF: line buffered
  • _IONBF: unbuffered

Loading a shared library in dynaimic loading

#include <stdio.h>

int main(){
    puts("hello");
    puts("world");
}
0x555555554500 pushq 0x200b02(%rip) # 0x555555755008 0x555555554506 jmpq *0x200b04(%rip) # 0x555555755010 0x55555555450c nopl 0x0(%rax) 0x555555554510 <puts@plt> jmpq *0x200b02(%rip) # 0x555555755018 0x555555554516 <puts@plt+6> pushq $0x0 0x55555555451b <puts@plt+11> jmpq 0x555555554500 # resolver

When the first time call puts, we would reach the <puts@plt> at line 3 to check whether the shared library is linked, but how to check?

The line 3 would jump to the puts's GOT which offset is 0x555555755008 and the value of this offset is an address. If the address is the next instruction of <puts@plt> ( i.e., <puts@plt+6> ), then will jump to <puts@plt+6>, and goto the next instruction ( i.e., <puts@plt+11> ) which is reslover to update the GOT's value which is the address of puts.

So that we could goto the puts library without running resolver again after the first calling of puts, since the puts's GOT is updated from the address of <puts@plt+6> to the address of puts by resolver.

The first call:`

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

The second call:
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

The figures are captured from the ppt of Advanced Programming Environment in the UNIX Environment at NCTU

Ptrace

Only one interface:

long ptrace(enum __ptrace_request request, 
        pid_t pid. void *addr, void *data);

ptrace full request-list is in the manual page.

  1. PTRACE_ATTACH
    • Parent: calls ptrace(PTRACE_ATTACH) or
    • Child: calls ptrace(PTRACE_TRACEME)
    • After above cmd, a SIGSTOP signal is sent to the tracee.
      • Use waitpid() to wait for the child process
      • Determine the status of the child by using WIFSTOPPED()