blog

my personnal blog / site
Log | Files | Refs | git clone https://git.ne02ptzero.me/git/blog

commit feeb38bfcbfed8bc958c7ff1842d496507b7b36c
parent 9df5209dae173e4d8ea710b0ff7d68e859e966a0
Author: Louis Solofrizzo <lsolofrizzo@online.net>
Date:   Tue,  2 Apr 2019 00:09:11 +0200

Blog: Add new article, remove junk file

Signed-off-by: Louis Solofrizzo <lsolofrizzo@online.net>

Diffstat:
Dimg/testdisk.log | 480-------------------------------------------------------------------------------
Amarkdown/things-i-use-in-C-everyday.md | 693+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 693 insertions(+), 480 deletions(-)

diff --git a/img/testdisk.log b/img/testdisk.log @@ -1,480 +0,0 @@ - - -Fri Aug 24 01:42:23 2018 -Command line: TestDisk - -TestDisk 7.0, Data Recovery Utility, April 2015 -Christophe GRENIER <grenier@cgsecurity.org> -http://www.cgsecurity.org -OS: Linux, kernel 4.17.14-arch1-1-ARCH (#1 SMP PREEMPT Thu Aug 9 11:56:50 UTC 2018) x86_64 -Compiler: GCC 6.3 -Compilation date: 2017-03-29T18:57:40 -ext2fs lib: 1.44.3, ntfs lib: libntfs-3g, reiserfs lib: 0.3.0.5, ewf lib: none, curses lib: ncurses 6.0 -Warning: can't get size for Disk /dev/mapper/control - 0 B - 0 sectors, sector size=512 -Hard disk list -Disk /dev/mapper/luks - 511 GB / 476 GiB - 999155712 sectors, sector size=512 -Disk /dev/dm-0 - 511 GB / 476 GiB - 999155712 sectors, sector size=512 - -Partition table type (auto): None -Disk /dev/mapper/luks - 511 GB / 476 GiB -Partition table type: None - -Interface Advanced - -recover_EXT2: s_block_group_nr=0/3811, s_mnt_count=13/4294967295, s_blocks_per_group=32768, s_inodes_per_group=8192 -recover_EXT2: s_blocksize=4096 -recover_EXT2: s_blocks_count 124894464 -recover_EXT2: part_size 999155712 - P ext4 0 999155711 999155712 - ext4 blocksize=4096 Large_file Sparse_SB Recover, 511 GB / 476 GiB -search_superblock - -recover_EXT2: s_block_group_nr=0/3811, s_mnt_count=13/4294967295, s_blocks_per_group=32768, s_inodes_per_group=8192 -recover_EXT2: s_blocksize=4096 -recover_EXT2: s_blocks_count 124894464 -recover_EXT2: part_size 999155712 -Ext2 superblock found at sector 2 (block=0, blocksize=4096) - -block_group_nr 1 - -recover_EXT2: "e2fsck -b 32768 -B 4096 device" may be needed -recover_EXT2: s_block_group_nr=1/3811, s_mnt_count=0/4294967295, s_blocks_per_group=32768, s_inodes_per_group=8192 -recover_EXT2: s_blocksize=4096 -recover_EXT2: s_blocks_count 124894464 -recover_EXT2: part_size 999155712 -Ext2 superblock found at sector 262144 (block=32768, blocksize=4096) - -block_group_nr 3 - -recover_EXT2: "e2fsck -b 98304 -B 4096 device" may be needed -recover_EXT2: s_block_group_nr=3/3811, s_mnt_count=0/4294967295, s_blocks_per_group=32768, s_inodes_per_group=8192 -recover_EXT2: s_blocksize=4096 -recover_EXT2: s_blocks_count 124894464 -recover_EXT2: part_size 999155712 -Ext2 superblock found at sector 786432 (block=98304, blocksize=4096) - -block_group_nr 5 - -recover_EXT2: "e2fsck -b 163840 -B 4096 device" may be needed -recover_EXT2: s_block_group_nr=5/3811, s_mnt_count=0/4294967295, s_blocks_per_group=32768, s_inodes_per_group=8192 -recover_EXT2: s_blocksize=4096 -recover_EXT2: s_blocks_count 124894464 -recover_EXT2: part_size 999155712 -Ext2 superblock found at sector 1310720 (block=163840, blocksize=4096) - -block_group_nr 7 - -recover_EXT2: "e2fsck -b 229376 -B 4096 device" may be needed -recover_EXT2: s_block_group_nr=7/3811, s_mnt_count=0/4294967295, s_blocks_per_group=32768, s_inodes_per_group=8192 -recover_EXT2: s_blocksize=4096 -recover_EXT2: s_blocks_count 124894464 -recover_EXT2: part_size 999155712 -Ext2 superblock found at sector 1835008 (block=229376, blocksize=4096) - -block_group_nr 9 - -recover_EXT2: "e2fsck -b 294912 -B 4096 device" may be needed -recover_EXT2: s_block_group_nr=9/3811, s_mnt_count=0/4294967295, s_blocks_per_group=32768, s_inodes_per_group=8192 -recover_EXT2: s_blocksize=4096 -recover_EXT2: s_blocks_count 124894464 -recover_EXT2: part_size 999155712 -Ext2 superblock found at sector 2359296 (block=294912, blocksize=4096) - -block_group_nr 25 - -recover_EXT2: "e2fsck -b 819200 -B 4096 device" may be needed -recover_EXT2: s_block_group_nr=25/3811, s_mnt_count=0/4294967295, s_blocks_per_group=32768, s_inodes_per_group=8192 -recover_EXT2: s_blocksize=4096 -recover_EXT2: s_blocks_count 124894464 -recover_EXT2: part_size 999155712 -Ext2 superblock found at sector 6553600 (block=819200, blocksize=4096) - -block_group_nr 27 - -recover_EXT2: "e2fsck -b 884736 -B 4096 device" may be needed -recover_EXT2: s_block_group_nr=27/3811, s_mnt_count=0/4294967295, s_blocks_per_group=32768, s_inodes_per_group=8192 -recover_EXT2: s_blocksize=4096 -recover_EXT2: s_blocks_count 124894464 -recover_EXT2: part_size 999155712 -Ext2 superblock found at sector 7077888 (block=884736, blocksize=4096) - -block_group_nr 49 - -recover_EXT2: "e2fsck -b 1605632 -B 4096 device" may be needed -recover_EXT2: s_block_group_nr=49/3811, s_mnt_count=0/4294967295, s_blocks_per_group=32768, s_inodes_per_group=8192 -recover_EXT2: s_blocksize=4096 -recover_EXT2: s_blocks_count 124894464 -recover_EXT2: part_size 999155712 -Ext2 superblock found at sector 12845056 (block=1605632, blocksize=4096) - -block_group_nr 81 - -recover_EXT2: "e2fsck -b 2654208 -B 4096 device" may be needed -recover_EXT2: s_block_group_nr=81/3811, s_mnt_count=0/4294967295, s_blocks_per_group=32768, s_inodes_per_group=8192 -recover_EXT2: s_blocksize=4096 -recover_EXT2: s_blocks_count 124894464 -recover_EXT2: part_size 999155712 -Ext2 superblock found at sector 21233664 (block=2654208, blocksize=4096) - ext4 0 999155711 999155712 -superblock 0, blocksize=4096 [] -superblock 32768, blocksize=4096 [] -superblock 98304, blocksize=4096 [] -superblock 163840, blocksize=4096 [] -superblock 229376, blocksize=4096 [] -superblock 294912, blocksize=4096 [] -superblock 819200, blocksize=4096 [] -superblock 884736, blocksize=4096 [] -superblock 1605632, blocksize=4096 [] -superblock 2654208, blocksize=4096 [] - -To repair the filesystem using alternate superblock, run -fsck.ext4 -p -b superblock -B blocksize device - - -dir_partition inode=2 - P ext4 0 999155711 999155712 - ext4 blocksize=4096 Large_file Sparse_SB Recover, 511 GB / 476 GiB -Directory / - 2 drwxr-xr-x 0 0 4096 7-Aug-2018 16:36 . - 2 drwxr-xr-x 0 0 4096 7-Aug-2018 16:36 .. - 23461889 drwxr-xr-x 0 0 4096 23-Aug-2018 11:25 var - 4718593 drwxr-xr-x 0 0 4096 6-Aug-2018 23:11 boot - 1703937 drwxr-xr-x 0 0 4096 6-Aug-2018 23:14 dev - 7602177 drwxr-xr-x 0 0 4096 6-Aug-2018 23:14 run - 14811137 drwxr-xr-x 0 0 4096 24-Aug-2018 01:42 etc - 7733249 drwxrwxrwt 0 0 4096 6-Aug-2018 23:14 tmp - 2621441 dr-xr-xr-x 0 0 4096 6-Aug-2018 23:14 sys - 23592961 dr-xr-xr-x 0 0 4096 6-Aug-2018 23:14 proc - 27394049 drwxr-xr-x 0 0 4096 24-Aug-2018 01:42 usr - 11 lrwxrwxrwx 0 0 7 5-Jan-2018 20:17 bin - 25821185 drwxr-xr-x 0 0 4096 6-Aug-2018 23:24 home - 12 lrwxrwxrwx 0 0 7 5-Jan-2018 20:17 lib - 13 lrwxrwxrwx 0 0 7 5-Jan-2018 20:17 lib64 - 29753345 drwxr-xr-x 0 0 4096 5-Jan-2018 20:17 mnt - 13238273 drwxr-xr-x 0 0 4096 19-Aug-2018 02:16 opt - 17563649 drwxr-x--- 0 0 4096 24-Aug-2018 00:54 root - 14 lrwxrwxrwx 0 0 7 5-Jan-2018 20:17 sbin - 10878977 drwxr-xr-x 0 0 4096 6-Aug-2018 23:14 srv - 14024705 drwxr-xr-x 0 0 4096 7-Aug-2018 16:36 keybase - -dir_partition inode=25821185 - P ext4 0 999155711 999155712 - ext4 blocksize=4096 Large_file Sparse_SB Recover, 511 GB / 476 GiB -Directory /home - 25821185 drwxr-xr-x 0 0 4096 6-Aug-2018 23:24 . - 2 drwxr-xr-x 0 0 4096 7-Aug-2018 16:36 .. - 25821186 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:42 louis - -dir_partition inode=25821186 - P ext4 0 999155711 999155712 - ext4 blocksize=4096 Large_file Sparse_SB Recover, 511 GB / 476 GiB -Directory /home/louis - 25821186 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:42 . - 25821185 drwxr-xr-x 0 0 4096 6-Aug-2018 23:24 .. - 25821187 -rw------- 1000 1000 2060 7-Aug-2018 15:46 .bash_history - 25821188 drwx------ 1000 1000 4096 20-Aug-2018 16:50 .gnupg - 25821189 drwxr-xr-x 1000 1000 4096 6-Aug-2018 23:52 .local - 25821196 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:07 .cache - 25821548 -rw-r--r-- 1000 1000 138 11-Aug-2018 12:38 .xinitrc - 25822534 -rw------- 1000 1000 52 23-Aug-2018 11:25 .Xauthority - 25822458 -rw------- 1000 1000 37060 24-Aug-2018 01:10 .viminfo - 25821219 drwxr-xr-x 1000 1000 4096 22-Aug-2018 14:02 .config - 25821295 drwx------ 1000 1000 4096 6-Aug-2018 23:59 .mozilla - 25821565 drwx------ 1000 1000 4096 14-Aug-2018 13:42 .ssh - 25822563 drwxr-xr-x 1000 1000 4096 7-Aug-2018 00:20 .oh-my-zsh - 25827033 -rw-r--r-- 1000 1000 3436 7-Aug-2018 16:10 .zshrc - 25823825 -rw------- 1000 1000 16 7-Aug-2018 00:37 .esd_auth - 25826112 -rw------- 1000 1000 214497 24-Aug-2018 01:42 .zsh_history - 25821726 -rw-r--r-- 1000 1000 38574 7-Aug-2018 21:48 .zcompdump-darlene-5.5.1 - 25824444 drwx------ 1000 1000 4096 24-Aug-2018 01:00 Downloads - 25824876 drwx------ 1000 1000 4096 7-Aug-2018 01:58 .pki - 26084174 drwxr-xr-x 1000 1000 4096 7-Aug-2018 21:28 .vim - 25827142 -rw-r--r-- 1000 1000 336 7-Aug-2018 13:22 .gtkrc-2.0 - 25827154 drwxr-xr-x 1000 1000 4096 7-Aug-2018 13:22 .kde4 - 25821552 -rw-r--r-- 1000 1000 2889 7-Aug-2018 21:26 .vimrc - 25952955 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:39 Work - 25826901 -rw-r--r-- 1000 1000 258 23-Aug-2018 22:37 .wget-hsts - 25822024 -rw-r--r-- 1000 1000 614 7-Aug-2018 21:38 .gitconfig - 25821662 -rw------- 1000 1000 0 19-Aug-2018 21:51 .tig_history - 25821190 -rw------- 1000 1000 0 7-Aug-2018 21:33 .python_history - 25821621 -rw-r--r-- 1000 1000 109 9-Aug-2018 16:14 .sclack - 25825190 -rwxr-xr-- 1000 1000 79 23-Aug-2018 11:25 .fehbg - 25826420 drwxr-xr-x 1000 1000 4096 9-Aug-2018 13:42 Desktop - 26349233 drwxr-xr-x 1000 1000 4096 8-Aug-2018 14:28 Pictures - 25821372 -rw------- 1000 1000 0 10-Aug-2018 22:50 .viminfo.tmp - 25956722 drwxr-xr-x 1000 1000 4096 9-Aug-2018 14:49 .irssi - 26087437 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:02 .node-gyp - 26087636 drwxr-xr-x 1000 1000 4096 14-Aug-2018 11:22 .java - 25821815 -rw-r--r-- 1000 1000 62613 17-Aug-2018 18:54 .gdbinit - 25821411 -rw------- 1000 1000 0 19-Aug-2018 00:57 .viminfz.tmp - 25821471 -rw------- 1000 1000 0 19-Aug-2018 00:57 .viminfy.tmp - 25823500 -rw------- 1000 1000 0 19-Aug-2018 00:57 .viminfx.tmp - 25823510 -rw------- 1000 1000 0 22-Aug-2018 12:58 .viminfw.tmp - 26218760 drwxr-xr-x 1000 1000 4096 23-Aug-2018 22:55 .bundle - 26219092 drwxr-xr-x 1000 1000 4096 24-Aug-2018 00:58 .npm -X25824291 lrwxrwxrwx 1000 1000 22 24-Aug-2018 01:42 .zsh_history.LOCK -X25826112 -rw------- 1000 1000 214497 24-Aug-2018 01:42 .zsh_history.new -X25823867 -rw------- 1000 1000 88842 21-Aug-2018 19:02 19 -X25823868 -rw------- 1000 1000 45221 24-Aug-2018 00:37 20 -X25823869 -rw------- 1000 1000 8378 20-Aug-2018 15:20 21 -X25823870 -rw------- 1000 1000 9008 20-Aug-2018 15:20 22 -X25823871 -rw------- 1000 1000 35222 20-Aug-2018 15:20 23 -X25823854 -rw------- 1000 1000 7880 23-Aug-2018 22:58 24 -X25823876 -rw------- 1000 1000 9107 20-Aug-2018 15:20 25 -X25823877 -rw------- 1000 1000 9108 20-Aug-2018 15:20 26 -X25823884 -rw------- 1000 1000 9159 20-Aug-2018 15:20 27 -X25823894 -rw------- 1000 1000 9683 13-Aug-2018 20:39 28 -X25823902 -rw-r--r-- 1000 1000 1035 16-Aug-2018 14:22 29 -X25823903 -rw------- 1000 1000 24346 23-Aug-2018 20:19 30 -X25823904 -rw------- 1000 1000 596861 20-Aug-2018 15:20 31 -X25823905 -rw------- 1000 1000 8351 23-Aug-2018 20:19 32 -X25823906 -rw------- 1000 1000 10043 23-Aug-2018 14:33 33 -X25823907 -rw------- 1000 1000 35966 23-Aug-2018 20:19 34 -X25823908 -rw------- 1000 1000 9959 23-Aug-2018 20:19 35 -X25823909 -rw------- 1000 1000 17760 23-Aug-2018 23:28 36 -X25823911 -rw------- 1000 1000 796 20-Aug-2018 15:20 37 -X25823912 -rw------- 1000 1000 559727 24-Aug-2018 01:09 38 -X25823913 -rw------- 1000 1000 9080 23-Aug-2018 20:17 39 -X25823914 -rw------- 1000 1000 12372 23-Aug-2018 19:09 40 -X25823915 -rw------- 1000 1000 7044 23-Aug-2018 22:13 41 -X25823873 -rw------- 1000 1000 11161 24-Aug-2018 01:08 42 -X25823918 -rw------- 1000 1000 69829 23-Aug-2018 16:03 43 -X25823922 -rw------- 1000 1000 3917334 20-Aug-2018 13:25 44 -X25823923 -rw------- 1000 1000 408991 20-Aug-2018 13:25 45 -X25823924 -rw------- 1000 1000 459 15-Aug-2018 04:30 46 -X25823925 -rw------- 1000 1000 37914 23-Aug-2018 20:01 47 -X25822425 -rw------- 1000 1000 460 24-Aug-2018 01:14 .zsh_history.LOCK - -dir_partition inode=25952955 - P ext4 0 999155711 999155712 - ext4 blocksize=4096 Large_file Sparse_SB Recover, 511 GB / 476 GiB -Directory /home/louis/Work - 25952955 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:39 . - 25821186 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:42 .. - 26477790 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:39 perso - 26477789 drwxr-xr-x 1000 1000 4096 14-Aug-2018 12:47 storage - 26477791 drwxr-xr-x 1000 1000 4096 8-Aug-2018 13:59 engineering -X26871376 drwxr-xr-x 1000 1000 0 24-Aug-2018 01:39 save_config -X26087692 drwxr-xr-x 1000 1000 0 24-Aug-2018 01:39 shayla -X26897772 drwxr-xr-x 1000 1000 0 24-Aug-2018 01:02 node_modules -X25952916 -rw-r--r-- 1000 1000 174 24-Aug-2018 01:37 package-lock.json.13289123 -X25952916 -rw-r--r-- 1000 1000 174 24-Aug-2018 01:37 package-lock.json - -dir_partition inode=26477790 - P ext4 0 999155711 999155712 - ext4 blocksize=4096 Large_file Sparse_SB Recover, 511 GB / 476 GiB -Directory /home/louis/Work/perso - 26477790 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:39 . - 25952955 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:39 .. - 25953317 drwxr-xr-x 1000 1000 4096 13-Aug-2018 12:23 neocgit - 27001201 drwxr-xr-x 1000 1000 4096 24-Aug-2018 00:18 blog - 26608648 drwxr-xr-x 1000 1000 4096 9-Aug-2018 17:57 firmware - 26608576 drwxr-xr-x 1000 1000 4096 10-Aug-2018 16:15 Grog-Knight -X26478066 drwxr-xr-x 1000 1000 0 24-Aug-2018 01:39 sdown - 26478087 -rw-r--r-- 1000 1000 1048576000 22-Aug-2018 20:21 output -X27000890 -rw-r--r-- 1000 1000 4096 24-Aug-2018 01:42 benchmark -X27027060 drwxr-xr-x 1000 1000 0 24-Aug-2018 01:39 ssg -X27132143 drwxr-xr-x 1000 1000 0 24-Aug-2018 01:39 jekyll - -dir_partition inode=26478066 - P ext4 0 999155711 999155712 - ext4 blocksize=4096 Large_file Sparse_SB Recover, 511 GB / 476 GiB -Directory /home/louis/Work/perso/sdown -Directory /home/louis/Work/perso - 26477790 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:39 . - 25952955 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:39 .. - 25953317 drwxr-xr-x 1000 1000 4096 13-Aug-2018 12:23 neocgit - 27001201 drwxr-xr-x 1000 1000 4096 24-Aug-2018 00:18 blog - 26608648 drwxr-xr-x 1000 1000 4096 9-Aug-2018 17:57 firmware - 26608576 drwxr-xr-x 1000 1000 4096 10-Aug-2018 16:15 Grog-Knight -X26478066 drwxr-xr-x 1000 1000 0 24-Aug-2018 01:39 sdown - 26478087 -rw-r--r-- 1000 1000 1048576000 22-Aug-2018 20:21 output -X27000890 -rw-r--r-- 1000 1000 4096 24-Aug-2018 01:42 benchmark -X27027060 drwxr-xr-x 1000 1000 0 24-Aug-2018 01:39 ssg -X27132143 drwxr-xr-x 1000 1000 0 24-Aug-2018 01:39 jekyll -Directory /home/louis/Work - 25952955 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:39 . - 25821186 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:43 .. - 26477790 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:43 perso - 26477789 drwxr-xr-x 1000 1000 4096 14-Aug-2018 12:47 storage - 26477791 drwxr-xr-x 1000 1000 4096 8-Aug-2018 13:59 engineering -X26871376 drwxr-xr-x 1000 1000 0 24-Aug-2018 01:39 save_config -X26087692 drwxr-xr-x 1000 1000 0 24-Aug-2018 01:39 shayla -X26897772 drwxr-xr-x 1000 1000 0 24-Aug-2018 01:02 node_modules -X25952916 -rw-r--r-- 1000 1000 174 24-Aug-2018 01:37 package-lock.json.13289123 -X25952916 -rw-r--r-- 1000 1000 174 24-Aug-2018 01:37 package-lock.json - -dir_partition inode=26477790 - P ext4 0 999155711 999155712 - ext4 blocksize=4096 Large_file Sparse_SB Recover, 511 GB / 476 GiB -Directory /home/louis/Work/perso - 26477790 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:43 . - 25952955 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:39 .. - 25953317 drwxr-xr-x 1000 1000 4096 13-Aug-2018 12:23 neocgit - 27001201 drwxr-xr-x 1000 1000 4096 24-Aug-2018 00:18 blog - 26608648 drwxr-xr-x 1000 1000 4096 9-Aug-2018 17:57 firmware - 26608576 drwxr-xr-x 1000 1000 4096 10-Aug-2018 16:15 Grog-Knight - 27131923 drwxr-xr-x 0 0 4096 24-Aug-2018 01:43 home - 26478087 -rw-r--r-- 1000 1000 1048576000 22-Aug-2018 20:21 output -X27000890 -rw-r--r-- 1000 1000 13513 24-Aug-2018 01:42 benchmark -X27027060 drwxr-xr-x 1000 1000 0 24-Aug-2018 01:39 ssg -X27132143 drwxr-xr-x 1000 1000 0 24-Aug-2018 01:39 jekyll - -dir_partition inode=27027060 - P ext4 0 999155711 999155712 - ext4 blocksize=4096 Large_file Sparse_SB Recover, 511 GB / 476 GiB -Directory /home/louis/Work/perso/ssg -Directory /home/louis/Work/perso - 26477790 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:43 . - 25952955 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:39 .. - 25953317 drwxr-xr-x 1000 1000 4096 13-Aug-2018 12:23 neocgit - 27001201 drwxr-xr-x 1000 1000 4096 24-Aug-2018 00:18 blog - 26608648 drwxr-xr-x 1000 1000 4096 9-Aug-2018 17:57 firmware - 26608576 drwxr-xr-x 1000 1000 4096 10-Aug-2018 16:15 Grog-Knight - 27131923 drwxr-xr-x 0 0 4096 24-Aug-2018 01:43 home - 26478087 -rw-r--r-- 1000 1000 1048576000 22-Aug-2018 20:21 output -X27000890 -rw-r--r-- 1000 1000 13513 24-Aug-2018 01:42 benchmark -X27027060 drwxr-xr-x 1000 1000 0 24-Aug-2018 01:39 ssg -X27132143 drwxr-xr-x 1000 1000 0 24-Aug-2018 01:39 jekyll -Directory /home/louis/Work - 25952955 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:39 . - 25821186 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:43 .. - 26477790 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:43 perso - 26477789 drwxr-xr-x 1000 1000 4096 14-Aug-2018 12:47 storage - 26477791 drwxr-xr-x 1000 1000 4096 8-Aug-2018 13:59 engineering -X26871376 drwxr-xr-x 1000 1000 0 24-Aug-2018 01:39 save_config -X26087692 drwxr-xr-x 1000 1000 0 24-Aug-2018 01:39 shayla -X26897772 drwxr-xr-x 1000 1000 0 24-Aug-2018 01:02 node_modules -X25952916 -rw-r--r-- 1000 1000 174 24-Aug-2018 01:37 package-lock.json.13289123 -X25952916 -rw-r--r-- 1000 1000 174 24-Aug-2018 01:37 package-lock.json - -dir_partition inode=26477790 - P ext4 0 999155711 999155712 - ext4 blocksize=4096 Large_file Sparse_SB Recover, 511 GB / 476 GiB -Directory /home/louis/Work/perso - 26477790 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:43 . - 25952955 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:39 .. - 25953317 drwxr-xr-x 1000 1000 4096 13-Aug-2018 12:23 neocgit - 27001201 drwxr-xr-x 1000 1000 4096 24-Aug-2018 00:18 blog - 26608648 drwxr-xr-x 1000 1000 4096 9-Aug-2018 17:57 firmware - 26608576 drwxr-xr-x 1000 1000 4096 10-Aug-2018 16:15 Grog-Knight - 27131923 drwxr-xr-x 0 0 4096 24-Aug-2018 01:43 home - 26478087 -rw-r--r-- 1000 1000 1048576000 22-Aug-2018 20:21 output -X27000890 -rw-r--r-- 1000 1000 16384 24-Aug-2018 01:43 benchmark -X27027060 drwxr-xr-x 1000 1000 0 24-Aug-2018 01:39 ssg -X27132143 drwxr-xr-x 1000 1000 0 24-Aug-2018 01:39 jekyll -Directory /home/louis/Work - 25952955 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:39 . - 25821186 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:43 .. - 26477790 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:43 perso - 26477789 drwxr-xr-x 1000 1000 4096 14-Aug-2018 12:47 storage - 26477791 drwxr-xr-x 1000 1000 4096 8-Aug-2018 13:59 engineering -X26871376 drwxr-xr-x 1000 1000 0 24-Aug-2018 01:39 save_config -X26087692 drwxr-xr-x 1000 1000 0 24-Aug-2018 01:39 shayla -X26897772 drwxr-xr-x 1000 1000 0 24-Aug-2018 01:02 node_modules -X25952916 -rw-r--r-- 1000 1000 174 24-Aug-2018 01:37 package-lock.json.13289123 -X25952916 -rw-r--r-- 1000 1000 174 24-Aug-2018 01:37 package-lock.json -Directory /home/louis - 25821186 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:43 . - 25821185 drwxr-xr-x 0 0 4096 6-Aug-2018 23:24 .. - 25821187 -rw------- 1000 1000 2060 7-Aug-2018 15:46 .bash_history - 25821188 drwx------ 1000 1000 4096 20-Aug-2018 16:50 .gnupg - 25821189 drwxr-xr-x 1000 1000 4096 6-Aug-2018 23:52 .local - 25821196 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:07 .cache - 25821548 -rw-r--r-- 1000 1000 138 11-Aug-2018 12:38 .xinitrc - 25822534 -rw------- 1000 1000 52 23-Aug-2018 11:25 .Xauthority - 25822458 -rw------- 1000 1000 37060 24-Aug-2018 01:10 .viminfo - 25821219 drwxr-xr-x 1000 1000 4096 22-Aug-2018 14:02 .config - 25821295 drwx------ 1000 1000 4096 6-Aug-2018 23:59 .mozilla - 25821565 drwx------ 1000 1000 4096 14-Aug-2018 13:42 .ssh - 25822563 drwxr-xr-x 1000 1000 4096 7-Aug-2018 00:20 .oh-my-zsh - 25827033 -rw-r--r-- 1000 1000 3436 7-Aug-2018 16:10 .zshrc - 25823825 -rw------- 1000 1000 16 7-Aug-2018 00:37 .esd_auth - 25826112 -rw------- 1000 1000 214543 24-Aug-2018 01:43 .zsh_history - 25821726 -rw-r--r-- 1000 1000 38574 7-Aug-2018 21:48 .zcompdump-darlene-5.5.1 - 25824444 drwx------ 1000 1000 4096 24-Aug-2018 01:00 Downloads - 25824876 drwx------ 1000 1000 4096 7-Aug-2018 01:58 .pki - 26084174 drwxr-xr-x 1000 1000 4096 7-Aug-2018 21:28 .vim - 25827142 -rw-r--r-- 1000 1000 336 7-Aug-2018 13:22 .gtkrc-2.0 - 25827154 drwxr-xr-x 1000 1000 4096 7-Aug-2018 13:22 .kde4 - 25821552 -rw-r--r-- 1000 1000 2889 7-Aug-2018 21:26 .vimrc - 25952955 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:39 Work - 25826901 -rw-r--r-- 1000 1000 258 23-Aug-2018 22:37 .wget-hsts - 25822024 -rw-r--r-- 1000 1000 614 7-Aug-2018 21:38 .gitconfig - 25821662 -rw------- 1000 1000 0 19-Aug-2018 21:51 .tig_history - 25821190 -rw------- 1000 1000 0 7-Aug-2018 21:33 .python_history - 25821621 -rw-r--r-- 1000 1000 109 9-Aug-2018 16:14 .sclack - 25825190 -rwxr-xr-- 1000 1000 79 23-Aug-2018 11:25 .fehbg - 25826420 drwxr-xr-x 1000 1000 4096 9-Aug-2018 13:42 Desktop - 26349233 drwxr-xr-x 1000 1000 4096 8-Aug-2018 14:28 Pictures - 25821372 -rw------- 1000 1000 0 10-Aug-2018 22:50 .viminfo.tmp - 25956722 drwxr-xr-x 1000 1000 4096 9-Aug-2018 14:49 .irssi - 26087437 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:02 .node-gyp - 26087636 drwxr-xr-x 1000 1000 4096 14-Aug-2018 11:22 .java - 25821815 -rw-r--r-- 1000 1000 62613 17-Aug-2018 18:54 .gdbinit - 25821411 -rw------- 1000 1000 0 19-Aug-2018 00:57 .viminfz.tmp - 25821471 -rw------- 1000 1000 0 19-Aug-2018 00:57 .viminfy.tmp - 25823500 -rw------- 1000 1000 0 19-Aug-2018 00:57 .viminfx.tmp - 25823510 -rw------- 1000 1000 0 22-Aug-2018 12:58 .viminfw.tmp - 26218760 drwxr-xr-x 1000 1000 4096 23-Aug-2018 22:55 .bundle - 26219092 drwxr-xr-x 1000 1000 4096 24-Aug-2018 00:58 .npm -X25824737 -rw------- 1000 1000 0 24-Aug-2018 01:43 .zsh_history.LOCK -X25826112 -rw------- 1000 1000 214543 24-Aug-2018 01:43 .zsh_history.new -X25823867 -rw------- 1000 1000 88842 21-Aug-2018 19:02 19 -X25823868 -rw------- 1000 1000 45221 24-Aug-2018 00:37 20 -X25823869 -rw------- 1000 1000 8378 20-Aug-2018 15:20 21 -X25823870 -rw------- 1000 1000 9008 20-Aug-2018 15:20 22 -X25823871 -rw------- 1000 1000 35222 20-Aug-2018 15:20 23 -X25823854 -rw------- 1000 1000 7880 23-Aug-2018 22:58 24 -X25823876 -rw------- 1000 1000 9107 20-Aug-2018 15:20 25 -X25823877 -rw------- 1000 1000 9108 20-Aug-2018 15:20 26 -X25823884 -rw------- 1000 1000 9159 20-Aug-2018 15:20 27 -X25823894 -rw------- 1000 1000 9683 13-Aug-2018 20:39 28 -X25823902 -rw-r--r-- 1000 1000 1035 16-Aug-2018 14:22 29 -X25823903 -rw------- 1000 1000 24346 23-Aug-2018 20:19 30 -X25823904 -rw------- 1000 1000 596861 20-Aug-2018 15:20 31 -X25823905 -rw------- 1000 1000 8351 23-Aug-2018 20:19 32 -X25823906 -rw------- 1000 1000 10043 23-Aug-2018 14:33 33 -X25823907 -rw------- 1000 1000 35966 23-Aug-2018 20:19 34 -X25823908 -rw------- 1000 1000 9959 23-Aug-2018 20:19 35 -X25823909 -rw------- 1000 1000 17760 23-Aug-2018 23:28 36 -X25823911 -rw------- 1000 1000 796 20-Aug-2018 15:20 37 -X25823912 -rw------- 1000 1000 559727 24-Aug-2018 01:09 38 -X25823913 -rw------- 1000 1000 9080 23-Aug-2018 20:17 39 -X25823914 -rw------- 1000 1000 12372 23-Aug-2018 19:09 40 -X25823915 -rw------- 1000 1000 7044 23-Aug-2018 22:13 41 -X25823873 -rw------- 1000 1000 11161 24-Aug-2018 01:08 42 -X25823918 -rw------- 1000 1000 69829 23-Aug-2018 16:03 43 -X25823922 -rw------- 1000 1000 3917334 20-Aug-2018 13:25 44 -X25823923 -rw------- 1000 1000 408991 20-Aug-2018 13:25 45 -X25823924 -rw------- 1000 1000 459 15-Aug-2018 04:30 46 -X25823925 -rw------- 1000 1000 37914 23-Aug-2018 20:01 47 -X25822425 -rw------- 1000 1000 460 24-Aug-2018 01:14 .zsh_history.LOCK -Directory /home - 25821185 drwxr-xr-x 0 0 4096 6-Aug-2018 23:24 . - 2 drwxr-xr-x 0 0 4096 7-Aug-2018 16:36 .. - 25821186 drwxr-xr-x 1000 1000 4096 24-Aug-2018 01:43 louis -Directory / - 2 drwxr-xr-x 0 0 4096 7-Aug-2018 16:36 . - 2 drwxr-xr-x 0 0 4096 7-Aug-2018 16:36 .. - 23461889 drwxr-xr-x 0 0 4096 23-Aug-2018 11:25 var - 4718593 drwxr-xr-x 0 0 4096 6-Aug-2018 23:11 boot - 1703937 drwxr-xr-x 0 0 4096 6-Aug-2018 23:14 dev - 7602177 drwxr-xr-x 0 0 4096 6-Aug-2018 23:14 run - 14811137 drwxr-xr-x 0 0 4096 24-Aug-2018 01:42 etc - 7733249 drwxrwxrwt 0 0 4096 6-Aug-2018 23:14 tmp - 2621441 dr-xr-xr-x 0 0 4096 6-Aug-2018 23:14 sys - 23592961 dr-xr-xr-x 0 0 4096 6-Aug-2018 23:14 proc - 27394049 drwxr-xr-x 0 0 4096 24-Aug-2018 01:42 usr - 11 lrwxrwxrwx 0 0 7 5-Jan-2018 20:17 bin - 25821185 drwxr-xr-x 0 0 4096 6-Aug-2018 23:24 home - 12 lrwxrwxrwx 0 0 7 5-Jan-2018 20:17 lib - 13 lrwxrwxrwx 0 0 7 5-Jan-2018 20:17 lib64 - 29753345 drwxr-xr-x 0 0 4096 5-Jan-2018 20:17 mnt - 13238273 drwxr-xr-x 0 0 4096 19-Aug-2018 02:16 opt - 17563649 drwxr-x--- 0 0 4096 24-Aug-2018 00:54 root - 14 lrwxrwxrwx 0 0 7 5-Jan-2018 20:17 sbin - 10878977 drwxr-xr-x 0 0 4096 6-Aug-2018 23:14 srv - 14024705 drwxr-xr-x 0 0 4096 7-Aug-2018 16:36 keybase - -TestDisk exited normally. diff --git a/markdown/things-i-use-in-C-everyday.md b/markdown/things-i-use-in-C-everyday.md @@ -0,0 +1,693 @@ +--- +title: C Tricks that I use everyday +summary: Collections of macros and GCC tricks in order to make life easier +route: c-tricks-that-i-use-everyday +date: 2019-02-02 +list: false +--- + +# C Tricks that I use everyday + +Some time ago, I've made a +[presentation](https://git.ne02ptzero.me/C_Advanced_Tips_n_Tricks?h=master) in +the 42 school, talking about 'Advanced' C languages tricks. Since then, I've +made some new discoveries about "Magic macros" and I thought writing a blog +post about it would be a good idea. + +So, in this post, I will look over some compiler flags as always use in my +projects, some `C{99,11}` standards macros, and finally some GCC only macros / +attributes. + +### Compiler flags + +##### `-Wall -Wextra -Werror` + +The holy trinity. It enables all default warnings and extra warnings for the +compiler. The `-Werror` is there to actually stop compilation when a warning is +raised. I sometime don't put the `-Werror` flag in my compilations options, +mainly when I compile external software (eg; `sqlite3`) in my tree. + +##### `-fstack-protector -fstack-protector-strong` + +Buffer overflow protection. Consider the following function: + + void function(void) + { + char *buf = alloca(256); + + /* Don't allow gcc to optimise away the buf */ + asm volatile("" :: "m" (buf)); + } + +Compiled with `-fno-stack-protector`: + + 08048404 <function>: + push %ebp ; prologue + mov %esp,%ebp + + sub $0x128,%esp ; reserve 0x128B on the stack + lea 0xf(%esp),%eax ; eax = esp + 0xf + and $0xfffffff0,%eax ; align eax + mov %eax,-0xc(%ebp) ; save eax in the stack frame + + leave ; epilogue + ret + +Compiled with `-fstack-protector`: + + 08048464 <function>: + push %ebp ; prologue + mov %esp,%ebp + + sub $0x128,%esp ; reserve 0x128B on the stack + + mov %gs:0x14,%eax ; load stack canary using gs + mov %eax,-0xc(%ebp) ; save it in the stack frame + xor %eax,%eax ; clear the register + + lea 0xf(%esp),%eax ; eax = esp + 0xf + and $0xfffffff0,%eax ; align eax + mov %eax,-0x10(%ebp) ; save eax in the stack frame + + mov -0xc(%ebp),%eax ; load canary + xor %gs:0x14,%eax ; compare against one in gs + je 8048493 <fun+0x2f> + call 8048340 <__stack_chk_fail@plt> + + leave ; epilogue + ret + +As you can see here, the compiler did had some protections on the stack +allocation; after the function prologue a +[canary](https://en.wikipedia.org/wiki/Stack_buffer_overflow#Stack_canaries) is +loaded and saved in the stack. Later, just before the epilogue, the canary is +verified against the original. If the values mismtach, the `__stack_chk_fail` +branch is taken and results in a pretty crash: + + *** stack smashing detected *** + +It is worth noting that the `-fstack-protector-strong` flag is fairly recent, +so you can't use it on old GCC cross compile toolchains. There's also a +performance cost of using the `-fstack-protector` flag, but I personally think +that the benefit of the protection outweight the performance. + +##### `-pipe` + +This flag is the only one on this list that does not affect compiled code, but +it simply avoid temporary files on compilation, thus speeding up the build a +bit. I think modern build manager like CMake or Ninja do use that by default. + +##### `-Wshadow` + +This flag will make the compiler raise a warning on variable shadowing. Here's +a simple example of that: + + int function(void) + { + int a = 0; + + [...] + while (condition) + { + /** + * Here, this variable shadows the + * function global scope one + */ + int a = 10; + } + } + +I mainly use this flag in order to force me to keep my codebase clean. I've +found that shadowing variables can be pretty confusing for an external reader, +especially on big functions. + +##### `-Wunreachable-code` + +The compiler will warn if it found that code is unreachable. The example is +pretty simple: + + int function(void) + { + [...] + return 0; + printf("Hello !\n"); /* We will never go there */ + } + +With an example like that, you can think that someone with half a brain does not +need the compiler to help him notice that the `printf(3)` is unreachable, but I've found this flag to be pretty useful on a large codebase when you're working on big functions and miss something: + + int very_big_function(void) + { + [...] + + + if (condition) + + return 1; + + else + + return 0; + + [...] /* Some legacy code */ + } + +Here we can see that my patch is gonna change the comportement of the function, +and any code after the `if/else` is never gonna be executed. Again, if you're +fully awake when you code this you will see it before the compiler does, but if +you don't, it's nice to have an error at compilation rather than runtime. + +##### `-Wswitch-enum` + +This flag will force the developer to reference every enum entry when used in a +switch: + + typedef enum { + OUT_FORMAT_JSON, + OUT_FORMAT_CSV, + OUT_FORMAT_HTML + } out_format_t; + + [...] + + const char *format_data(void *some_data, out_format_t format) + { + switch (format) + { + case OUT_FORMAT_JSON: + return format_data_to_json(some_data); + case OUT_FORMAT_CSV: + return format_data_to_csv(some_data); + } + } + +Here we can see that I forgot to use the `OUT_FORMAT_HTML` entry in my switch, +and the compiler will warn me about it. The warning is not about "referencing +every entry of the enum in the switch" it is more about asking a question on +this function. Indeed, my use case may be: "This data will never be formatted +to HTML, so there's no use to handle it in the switch". So, as a good practice, +maybe an assert is a good thing to add: + + case OUT_FORMAT_HTML: + assert(!"You can't format this data in HTML"); + +Or maybe you just forgot to code the html format function, and the compiler +will remind you that the API do support three output format, and you must +handle all of them: + + case OUT_FORMAT_HTML: + return format_data_to_html(some_data); + +##### `-Wstrict-prototypes` + +This flag will make the compiler raise a warning on nonsense legacy C prototypes: + + int function(a, b) + { + /* You guessed it, a & b are integers */ + } + +I do not want that in my codebases. + +##### `-D_FORTIFY_SOURCE=2` + +`GNULibc` hardening. Consider the following function: + + void function(const char *s) + { + char buf[256]; + + strcpy(buf, s); + + /* Don't allow gcc to optimise away the buf */ + asm volatile("" :: "m" (buf)); + } + +Compiled without the flag: + + 08048450 <function>: + push %ebp ; prologue + mov %esp,%ebp + + sub $0x118,%esp ; reserve 0x118B on the stack + mov 0x8(%ebp),%eax ; load parameter `s` to eax + mov %eax,0x4(%esp) ; save parameter for strcpy + lea -0x108(%ebp),%eax ; count `buf` in eax + mov %eax,(%esp) ; save parameter for strcpy + call 8048320 <strcpy@plt> + + leave ; epilogue + ret + +With the flag: + + 08048470 <function>: + push %ebp ; prologue + mov %esp,%ebp + + sub $0x118,%esp ; reserve 0x118B on the stack + movl $0x100,0x8(%esp) ; save value 256 as parameter + mov 0x8(%ebp),%eax ; load parameter `s` to eax + mov %eax,0x4(%esp) ; save parameter for strcpy + lea -0x108(%ebp),%eax ; count `buf` in eax + mov %eax,(%esp) ; save parameter for strcpy + call 8048370 <__strcpy_chk@plt> + + leave ; epilogue + return + +You can see that the compiler called `__strcpy_chk` instead of `strcpy`. Those +`__XXX_chk` functions are actually GCC builtins that are more safe than +original libc's one, mainly because the compiler will be forced to check that +the destination buffer will be big enough to receive the data, else the program +will crash with a pretty: + + *** buffer overflow detected ***: + +Of course in my example, one must use the `strncpy` function instead of +`strcpy` in order to be more safer already. Actually GCC does this automatically +those days (when the buffer destination size is known), hence the bit on +assembly in order to prevent gcc's optimizing. + +There is a good number of GCC builtins that are more safe than the libc, you can +find the full list [here](https://www.ibm.com/support/knowledgecenter/en/SSXVZZ_13.1.5/com.ibm.xlcpp1315.lelinux.doc/compiler_ref/bif_gcc_objectsize__builtin_chk.html) + +##### `-fPIE -pie` + +Enable [ASLR](https://en.wikipedia.org/wiki/Address_space_layout_randomization) +on the binary. + +##### `-Wl,-z,noexecstack` + +Linker flag that [disable stack +execution](https://linux.die.net/man/8/execstack) on the binary. See `ld(1)` +manual for more information. + +##### `-Wl,-z,relro -Wl,-z,now` + +Linker ELF Hardening flags. See `ld(1)` manual for more information. + +### Macros + +##### `COUNT_OF` + + #define COUNT_OF(ptr) (sizeof(ptr) / sizeof((ptr)[0])) + +Consider the following C snippet: + + static const char *strings[] = { + "Hello", + "World", + NULL + }; + + for (size_t i = 0; strings[i] != NULL; i++) + printf("Value is = %s\n", strings[i]); + +Pretty basic stuff. The key thing here is the `NULL` value in the array. This +entry sole purpose is to stop the reading loop. Thing is, the compiler (thus +you) already know the size of the array, you just need to use it: + + static const char *strings[] = { + "Hello", + "World" + }; + + for (size_t i = 0; i < COUNT_OF(strings); i++) + printf("Value is = %s\n", strings[i]); + +We just loose the `NULL` in the array, and the behavior is the same. + +##### `STATIC_ARRAY_FOREACH` + + #define STATIC_ARRAY_FOREACH(item, array) \ + for (size_t keep = 1, index = 0; \ + keep && index < COUNT_OF(array); \ + keep = !keep, index++) \ + for (item = &array[index]; keep; keep = !keep) + +Consider the previous iteration snippet: + + static const char *strings[] = { + "Hello", + "World" + }; + + for (size_t i = 0; i < COUNT_OF(strings); i++) + printf("Value is = %s\n", strings[i]); + +In this particular case, we don't need the value of `i`, beside for array +access. The `STATIC_ARRAY_FOREACH` macro is there to iterate over an array with +more 'pure' approach: + + const char *str[] = { + "Hello", + "World!" + }; + + STATIC_ARRAY_FOREACH(const char **ptr, str) + { + printf("%s\n", *ptr); + } + +##### `static_assert` + + #define static_assert _Static_assert + +Consider the following code: + + typedef enum { + ERROR_ONE, + ERROR_TWO, + ERROR_THREE, + ERROR_FOUR + } error_t; + + const char *error_to_str(error_t error) + { + static const char *str[] = { + [ERROR_ONE] = "Error One", + [ERROR_TWO] = "Error Two", + [ERROR_THREE] = "Error three" + }; + + return str[error]; + } + +Pretty basic error handling: We've got an enum that's gonna be used by +functions in order to return an error if any, and we got the helper +`error_to_str` in order to translate this error code in a more human-friendly +string. +Thing is, my `error_to_str` function isn't safe, at all. As you can see, I +forgot to put the fourth entry (`ERROR_FOUR`). Thus if one ask for the +translated string of `ERROR_FOUR`, it is greeted with a `segfault`. There are +three possible approaches here: + +- Change the function in a `switch/case` `if/elseif/else` tree. That way, we + can handle OOB error codes. +- Add a condition before the return in order to check that the asked entry does exists before accessing it +- Add a `static_assertion` (eg; A condition tested at compilation) in order to + check that the string array is not missing any entries. + +We're gonna use the last option, since I think it is the more elegant approach, +and big bonus: It happens at compilation. + + typedef enum { + ERROR_ONE, + ERROR_TWO, + ERROR_THREE, + ERROR_FOUR, + /* Always keep this one last */ + ERROR_MAX + } error_t; + + + const char *error_to_str(error_t error) + { + static const char *str[] = { + [ERROR_ONE] = "Error One", + [ERROR_TWO] = "Error Two", + [ERROR_THREE] = "Error three" + }; + + static_assert(COUNT_OF(str) == ERROR_MAX, "An error string is missing"); + + return str[error]; + } + +Let's try to compile this: + + $> gcc static_assert.c + [...] + static_assert.c:20:5: error: negative width in bit-field ‘__error_if_negative’ + static_assert(COUNT_OF(str) == ERROR_MAX, "An error string is missing"); + +As you can see, we catch the mistake at compilation, meaning that the patch +will never be merged in this state (You must have a build bot / CI, but that's +pretty common). In large codebase, it's human to add en entry to an enum like +that and forget to look on every function that must be updated with it. Keep in +mind that this is one of various `static_assert` usage, but it is the one I use +the most. + + +##### `STR` + + #define QUOTE_ME(x) #x + #define STR(x) QUOTE_ME(x) + +Take the following snippet: + + #define MAX_ARGC 3 + + int main(int ac, const char **av) + { + if (ac > MAX_ARGC) + { + printf("Maximum argc number is: %d\n", MAX_ARGC); + return 1; + } + + printf("All good! %s\n", av[1]); + return 0; + } + +Pretty common: We've got a macro that defines an integer, and we need to print +the value of macro. Thing is, we just need to put quotes on the value in order +to print it, since the preprocessor already knows the value of the define. So +instead of calling the `printf` runtime with `%d`, we can simply do: + + printf("Maximum argc number is: " STR(MAX_ARGC) "\n"); + +##### `__printf_function` + + #define __printf_function(...) __attribute__((format (printf, __VA_ARGS__))) + +Consider the following function: + + static void custom_log(const char *fmt, ...) + { + va_list ap; + + va_start(ap, fmt); + vfprintf(stdout, fmt, ap); + va_end(ap); + } + +As you can see, we've got a wrapper over `vfprintf` for some reason, and we +need to take the printf format argument (with `stdarg`) on this function. Thing +is, GCC does not know that we use the printf format in this function, and the +following snippet will compile: + + custom_log("Value is %s\n", 10); + +We just need to telle the compiler that the function use the `printf` format: + + __printf_function(1, 2) + static void custom_log(const char *fmt, ...) + +And we are greeted with: + + error: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ + +##### `__unused` + + #define __unused __attribute__((unused)) + +Pretty straightforward; If you need to tell the compiler that a variable isn't +used, instead of doing `(void)variable;` you can do: + + void *callback(void *ctx, __unused void *data) + { + [...] + } + +##### `typeof` + + #define typeof __typeof__ + +Pretty much self explanatory: + + #define auto(n, val) typeof(val) n = val + + int a; + typeof(a) b = 10; + + auto(c, 150); + + printf("%d\n", b); + printf("%d\n", c); + +##### `offsetof` & `container_of` + + #define offsetof(TYPE, MEMBER) ((size_t)&((TYPE *)0)->MEMBER) + #define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + +It is worth noting that GCC provides the `__compiler_offsetof` internal, and +thus `offsetof` does not need to be declared with the `0` trick like I did +above. `container_of` determine the parent structure from a pointer at compilation. It is +known to be used in the LK linked-lists. Here's a [really good blog +post](https://www.stupid-projects.com/container_of/) that explains how the +macro works. + +### Tricks + +##### Optionnal named parameters + + typedef struct { + int do_print; + char *name; + } some_function_args_t; + + void some_function(int required_a, int required_b, some_function_args_t *args) + { + printf("required_a = %d\n", required_a); + printf("required_b = %d\n", required_b); + printf("opt.do_printf = %d\n", args->do_print); + printf("opt.name = %s\n\n", args->name); + } + #define some_function(a, b, ...) \ + some_function(a, b, &(some_function_args_t){__VA_ARGS__}) + + int main(void) + { + some_function(1, 2); + some_function(1, 2, .do_print = 1); + some_function(1, 2, .name = "Louis"); + some_function(1, 2, .name = "Louis", .do_print = 3); + return 0; + } + +This trick is pretty much self explanatory; the above code do compile and is +standard `C11`. The main trick is to use `C11` feature of named structure +parameters, and use it to make optionnal / orderless named arguments, like in +python. + +##### `defer` + +Defers the cleanup of a variable when it get out of scope + + #define __defer_fd __attribute__((__cleanup__(cleanup_fd))) + + static void cleanup_fd(int *fd) + { + if (*fd != -1) + close(*fd); + } + + int file = open("/etc/passwd", O_RDONLY); + +If you compile something like that, the file descriptor needs to be closed at +the end of the function in order to avoid leaks: + + ==25924== FILE DESCRIPTORS: 4 open at exit. + ==25924== Open file descriptor 3: /etc/passwd + ==25924== at 0x497F4C2: open (in /usr/lib/libc-2.28.so) + ==25924== by 0x10918D: main (in /tmp/a.out) + +But if you add the `__defer` attribute, the function `cleanup_fd` will be +called just when the variable will get out of scope: + + int __defer_fd file = open("/etc/passwd", O_RDONLY); + + [...] + + ==24113== FILE DESCRIPTORS: 3 open at exit + +##### Explicit code breakpoint + +Put an explicit breakpoint in the code + + #include <sys/types.h> + #include <signal.h> + + static bool breakpoint_initialized = false; + static bool breakpoint_under_debug = false; + + static inline void trap(int __unused signum) + { + breakpoint_initialized = true; + } + + static inline void breakpoint_init(void) + { + struct sigaction old, __new; + + __new.sa_handler = trap; + __new.sa_flags = 0; + sigemptyset(&__new.sa_mask); + sigaction(SIGTRAP, &__new, &old); + kill(getpid(), SIGTRAP); + sigaction(SIGTRAP, &old, NULL); + + if (!breakpoint_initialized) + { + breakpoint_initialized = true; + breakpoint_under_debug = true; + } + } + + /** + * Use this macro in order to set a breakpoint in the code, for GDB + */ + # define BREAKPOINT() breakpoint() + + static inline void breakpoint(void) + { + if (!breakpoint_initialized) + breakpoint_init(); + if (breakpoint_under_debug) + kill(getpid(), SIGTRAP); + } + +Consider this example: + + printf("Hello!\n"); + BREAKPOINT(); + printf("World!\n"); + + +If you run it without debugging: + + $> ./a.out + Hello! + World! + +Under gdb: + + (gdb) r + Starting program: /tmp/a.out + Hello! + + Program received signal SIGTRAP, Trace/breakpoint trap. + 0x00007ffff7df307b in kill () from /usr/lib/libc.so.6 + (gdb) bt + #0 0x00007ffff7df307b in kill () from /usr/lib/libc.so.6 + #1 0x0000555555555208 in breakpoint_init () at main.c:25 + #2 0x000055555555526b in breakpoint () at main.c:43 + #3 0x000055555555529f in main () at main.c:51 + +### Optimisation + +##### `likely/unlikely` + + #define likely(x) __builtin_expect((x), 1) + #define unlikely(x) __builtin_expect((x), 0) + +Inform the compiler about the probability of a condition + + char *s = malloc(1024); + if (unlikely(s == NULL)) + { + /* ERROR */ + } + else + { + /* OK */ + } + +##### `hot_function/cold_function` + + #define __hot_function __attribute__((hot)) + #define __cold_function __attribute__((cold)) + +Inform the compiler about functions that are called often or not. Hot could be +used for event callbacks for example, and cold for function that are never +called, like a `panic()` function.