|
| 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>`; |
0 commit comments