---
# System prepended metadata

title: NCTU UNIX2020 NOTES
tags: [Unix Programming, NCTU]

---

# 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

```cpp
#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 4`KB` ) 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 16`KB`, so the `file.hole` file actually store 8`KB` on the system. But the `cp` command need to parse a file until an `EOF`, so it will parse totally 20`KB` and create `file.nohole`.

## read write effection
buff size choose = 4`KB`( 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
```cpp
#include <stdio.h>

int main(){
    puts("hello");
    puts("world");
}
```
```assembly=
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:`
![](https://i.imgur.com/ucnAIOO.png)
The second call:
![](https://i.imgur.com/THXahpe.png)
> The figures are captured from the ppt of Advanced Programming Environment in the UNIX Environment at NCTU




## Ptrace

Only one interface:
```c
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()`


