Skip to content

Commit 16f1f1a

Browse files
Merge pull request #60 from zhangzhuang15/dev
Dev
2 parents 2737fdf + c7b8092 commit 16f1f1a

File tree

7 files changed

+387
-6
lines changed

7 files changed

+387
-6
lines changed

.vitepress/config.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,10 @@ export default defineConfig({
288288
text: "Terminal的魔法",
289289
link: "/blog/terminal-io"
290290
},
291+
{
292+
text: 'Kilo, Text Editor',
293+
link: '/blog/terminal-kilo',
294+
},
291295
{
292296
text: "对立统一的一点看法",
293297
link: "/blog/conflict-thought"
@@ -364,6 +368,10 @@ export default defineConfig({
364368
text: '协程-用C语言实现',
365369
link: '/blog/coroutine'
366370
},
371+
{
372+
text: 'System Program with C',
373+
link: '/blog/system-program-with-c'
374+
},
367375
{
368376
text: 'Talk about pthread',
369377
link: '/blog/pthread'

docs/blog/learning-zig.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Zig 是一个系统级编程语言,是C语言的有力替代品。与C语言
99

1010
目前看,比较出色的Zig项目只有Bunjs。
1111

12-
## How to debug zig in vscode
12+
## Debug Zig with Vscode
1313
确保安装 codeLLDB 的vscode 插件。
1414

1515
```shell

docs/blog/programer-and-english.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,4 +117,10 @@ aside: true
117117

118118
**It's made from scratch**, 不是一蹴而就的
119119

120-
**become a loophole**, 变成无底洞
120+
**become a loophole**, 变成无底洞
121+
122+
**It doesnt seem to be the case**, 看来不太符合预期
123+
124+
**I would expect that**, 我预期是...
125+
126+
**keep code more understandable and self-evident**, 令代码更好理解、更直观

docs/blog/sytem-program-with-c.md

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
---
2+
title: "System Program with C"
3+
page: true
4+
aside: true
5+
---
6+
7+
# System Program with C
8+
I talk about learning to write system program with c language.
9+
10+
## Overview
11+
System programming with C is different from normal programming with other languages.Today, popular operating system is created by C, e.g. Windows, MacOS and Linux.As default, operating system provides wrappers of systemcalls in C language out of box. In other words, using C is considered as communicating with operating system directly, bringing your program high performance and minimist runtime.
12+
13+
Other languages, provide wrappers of systemcalls on their own. They might wrap systemcalls with asm, e.g. Go language. They might wrap systemcalls based on C library. They give you more human-friendly way to write program, but it's not direct, simple and performant. You cannot communicate with operating system directy, and have to burden unignored runtime.
14+
15+
Of course, you can write system program in C++ or Rust languages. It seems to be more friendly, readable than C. But it's still important to know how to write system program in C.
16+
17+
## Header File
18+
You should know some c header files, some of them belong to C standard and some of them belong to operating system, so that you can write portable c program.
19+
20+
Every operating system that supports using c developing software, has to implement C standard, promise that people can include c standard header files out of box.
21+
22+
23+
### C Standard Library Header File
24+
#### Input/Output
25+
- `<stdio.h>`
26+
27+
#### Input/Output Extensions
28+
- `<errno.h>`
29+
- Example: errno, EIO, ENOMEM
30+
- `<fcntl.h>`, File control options (POSIX)
31+
- Example: open, O_RDONLY, O_WRONLY
32+
33+
#### Input/Output Format
34+
- `<inttypes.h>`, Integer types and formatting macros (C99)
35+
- Example: PRId32, PRIu64
36+
- `<stdint.h>`, Fixed-width integer types (C99)
37+
- Example: int8_t, uint32_t, INT_MAX
38+
39+
#### String and Memory Manipulation
40+
- `<string.h>`
41+
- Example: strlen, strcpy, strcat, memcmp, memcpy
42+
- `<wchar.h>`, Wide character handling
43+
- Example: wcslen, wcscpy, wcscat
44+
- `<wctype.h>`, Wide character classification and conversion
45+
- Example: iswalpha, towlower
46+
47+
#### Math
48+
- `<math.h>`
49+
- Example: sin, cos, sqrt, pow, ceil, floor
50+
- `<complex.h>`, Complex number arithmetic (C99)
51+
- Example: cabs, creal, cimag
52+
- `<tgmath.h>`, Type-generic macros for math functions (C99)
53+
- Example: tgmath functions automatically select the correct type (e.g., float, double).
54+
55+
#### General Utilities
56+
- `<stdlib.h>`
57+
- Example: malloc, free, exit, atoi, rand, qsort.
58+
- `<stddef.h>`, Standard type definitions
59+
- Example: size_t, ptrdiff_t, NULL
60+
- `<stdarg.h>`, Variable argument handling
61+
- Example: va_start, va_arg, va_end
62+
- `<ctype.h>`, Character classification and conversion
63+
- Example: isalpha, isdigit, toupper, tolower
64+
65+
#### Time and Date
66+
- `<time.h>`
67+
- Example: time, clock, difftime, strftime
68+
69+
#### Signal
70+
- `<signal.h>`
71+
- Example: signal, raise, kill, SIGINT, SIGTERM
72+
73+
#### Localization
74+
- `<locale.h>`, Localization utilities
75+
- Example: setlocale, localeconv.
76+
77+
#### Error Handle
78+
- `<assert.h>`, Diagnostics and assertions
79+
- Example: assert
80+
81+
#### Atomic
82+
- `<stdatomic.h>`, Atomic operations (C11)
83+
- Example: atomic_store, atomic_load
84+
85+
#### Misc
86+
- `<limits.h>`, Defines implementation-specific limits.
87+
- Example: CHAR_MAX, INT_MAX.
88+
- `<float.h>`, Defines floating-point limits.
89+
- Example: FLT_MAX, DBL_MIN.
90+
- `<stdbool.h>`, Boolean type and values (true, false) (C99).
91+
- Example: bool.
92+
- `<iso646.h>`, Alternative spellings for operators (e.g., and, or, not).
93+
- `<stdnoreturn.h>`, Defines the _Noreturn keyword (C11).
94+
- Example: _Noreturn.
95+
96+
97+
### System Library Header File
98+
These header files are implemented by operating system, there might be different among operating systems. These header files provide functionalities that c standard cannot cover. Most of these functionalities wrap systemcalls or depend on systemcalls, of course, they might not use any systemcalls.
99+
100+
- `<sys/types.h>`
101+
- `<sys/ioctl.h>`
102+
- `<sys/time.h>`
103+
- `<termios.h>`
104+
105+
## How to Use C Standard Library
106+
Now you haved learned that what these header files look like. I don't tend to put a list of c functions from these header files, and introduce how to use them one by one.
107+
108+
I just introduce these functions based on practical background.
109+
110+
### Get Random Number
111+
```c
112+
#include <stdlib.h>
113+
#include <time.h>
114+
115+
int main() {
116+
srand(time(NULL));
117+
int random_number_one = rand();
118+
int random_number_two = rand();
119+
return 0;
120+
}
121+
```
122+
`srand` and `rand` from: `<stdlib.h>`;
123+
`time` from: `<time.h>`
124+
125+
### Clear Your Array
126+
```c
127+
#include <string.h>
128+
129+
int main() {
130+
int arr[100];
131+
memset(arr, 0, sizeof(arr));
132+
return 0;
133+
}
134+
```
135+
136+
### Copy Your Array
137+
```c
138+
#include <string.h>
139+
int main() {
140+
int arr[5] = { 1, 2, 3, 4, 5 };
141+
int yrr[5];
142+
memcpy(yrr, arr, sizeof(arr));
143+
return 0;
144+
}
145+
```
146+
147+
### Extract Value from Formatted String
148+
```c
149+
#include <stdio.h>
150+
int main() {
151+
char* s = "hello,20 and peter";
152+
int age;
153+
char name[10];
154+
155+
int nums_parsed = sscanf(s, "hello,%d and %s", &age, name);
156+
157+
if (nums_parsed != 2) {
158+
printf("cannot parse age and name");
159+
return 1;
160+
}
161+
162+
printf("age is %d, and name is %s", age, name);
163+
return 0;
164+
}
165+
```
166+
167+
### Exit Process Hooking
168+
```c
169+
#include <stdlib.h>
170+
171+
void exit_handler() {
172+
173+
};
174+
int main() {
175+
int registered_ok = atexit(exit_handler);
176+
if (registered_ok != 0) {
177+
return -1;
178+
}
179+
return 0;
180+
}
181+
```
182+
183+
### Variable Function Pramaters
184+
```c
185+
#include <stdarg.h>
186+
#include <stdlib.h>
187+
#include <stdio.h>
188+
189+
int putting(const char* s, int** result, ...) {
190+
va_list args;
191+
va_start(args, s);
192+
193+
int value = va_arg(args, int);
194+
char c = va_arg(args, char);
195+
va_end(args);
196+
197+
int* arr = malloc(2*sizeof(int));
198+
arr[0] = value;
199+
arr[1] = (int)c;
200+
*result = arr;
201+
return 2;
202+
}
203+
204+
int main() {
205+
int* result;
206+
int nums = putting("hello", &result, 10, 'c');
207+
for (int i = 0; i < nums; i++) {
208+
printf("%d", result[i]);
209+
}
210+
return 0;
211+
}
212+
```
213+
214+
`va_start`, `va_end`, `va_arg` from: `<stdarg.h>`;
215+
`malloc` from: `<stdlib.h>`;
216+
`printf` from: `<stdio.h>`;

docs/blog/terminal-io.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ Terminal 界面上,因为它并没有监听"main.txt"文件的变动。
4343

4444
既然是终端模拟器,它要起到模拟的作用,就必须遵循一套模版,毕竟没有模仿对象的话,何来模拟之言?这种模版就是一种协定。我们按下Enter键,就会执行一条指令的行为,也是这种协定要求的表现行为。
4545

46-
这种协定具体是怎样的呢?这个就要去阅读《Unix高级编程》的终端IO一节了。这里不细说,而是挑一些紧要的介绍下
46+
这种协定具体是怎样的呢?这个就要去阅读《Unix高级编程》的终端IO一节了。这里不细说,而是挑一些紧要的介绍
4747

4848
## 为什么按下enter键就会执行命令?
4949
Terminal App在启动之后,默认会加载shell程序,可能是 zsh,也可能是 bash,或者其他的。这些shell程序会读取你的输入,使用 `read` 系统函数。它并不知道你什么时候输入完毕了,它只知道什么时候 `read`函数返回。那么 `read`函数什么时候返回呢?就在你按下Enter的时候。
@@ -141,7 +141,7 @@ env | grep TERM
141141
```
142142
然后你就查询这种终端对应的终端控制序列,按照屏幕清空、移动光标等功能做好封装,以供使用。像 Vim 程序,它就是这么干的,封装了很多终端的终端控制序列,总结出同样的接口定义,以达到跨平台、跨终端的目的。你也可以这样做。
143143

144-
人总是像偷懒的,你也不必自己去查终端控制序列,完全可以使用已经封装好的工具,就比如`<curses.h>`, `<ncurses.h>`, 如果你使用的是 Rust 编程,还可以使用`crossterm`。你使用的是 Python , 也没有关系,python也有对 `curses.h` 的封装可以使用
144+
人总是想偷懒的,你也不必自己去查终端控制序列,完全可以使用已经封装好的工具,就比如`<curses.h>`, `<ncurses.h>`, 如果你使用的是 Rust 编程,还可以使用`crossterm`。你使用的是 Python , 也没有关系,python也有对 `curses.h` 的封装
145145

146146
:::tip <TipIcon />
147147
上一节中提到的 `termios.h`, 利用 `tcsetattr` 只是影响了 `read`, `write`
@@ -200,7 +200,7 @@ gcc main.c -lcurses -o main && ./main
200200

201201
你可以使用`tgetflag`查询终端是否支持某个终端控制序列;
202202

203-
对于操作光标的终端控制序列,光靠 `tgetstr` 还不够,还要用上`tgoto`:
203+
对于操作光标的终端控制序列,光靠 `tgetstr` 还不够,有的控制序列字符串要用`tgoto`才能获取:
204204
```c
205205
#include <stdlib.h>
206206
#include <termcap.h>

0 commit comments

Comments
 (0)