# 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:`

The second call:

> 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()`