syscall (noun)
1. A prayer to the kernel to do magic on your behalf.
2. Everything in computing that's more like `mkdir` than `f(x) = x²`.
3. Everything in computing that we didn't hear about in `lost+found`, because syscalls don't exist until machines do.
4. Everything in computing you still need after you've got Turing completeness.
5. The most important lines in any codebase, after the bugs.
---
```sh
#!/bin/sh
### syscall numbers (x86_64 Linux)
SYS_PAUSE=34
SYS_NANOSLEEP=35
SYS_GETPID=39
SYS_EXIT=60
SYS_KILL=62
SYS_UNAME=63
SYS_GETCWD=79
SYS_CHDIR=80
SYS_UMASK=95
SYS_GETTIMEOFDAY=96
SYS_TIMES=100
SYS_GETUID=102
SYS_GETGID=104
SYS_GETPPID=110
SYS_SYNC=162
SYS_REBOOT=169
### signals
SIGTERM=15
### reboot ABI magic (documented in man 2 reboot)
LINUX_REBOOT_MAGIC1=0xfee1dead
LINUX_REBOOT_MAGIC2=672274793
LINUX_REBOOT_MAGIC2A=85072278
LINUX_REBOOT_MAGIC2B=369367448
LINUX_REBOOT_CMD_RESTART=0x4321fedc
###############################################################################
# true(1): exit(0)
cat >true.asm <<EOF
bits 64
mov eax, ${SYS_EXIT}
xor edi, edi
syscall
EOF
###############################################################################
# false(1): exit(1)
cat >false.asm <<EOF
bits 64
mov eax, ${SYS_EXIT}
mov edi, 1
syscall
EOF
###############################################################################
# sync(1): sync(); exit(0)
cat >sync.asm <<EOF
bits 64
mov eax, ${SYS_SYNC}
syscall
xor edi, edi
mov eax, ${SYS_EXIT}
syscall
EOF
###############################################################################
# getpid(1): exit(getpid())
cat >getpid.asm <<EOF
bits 64
mov eax, ${SYS_GETPID}
syscall
mov edi, eax ; exit status = pid (truncated by shell, use a write syscall here)
mov eax, ${SYS_EXIT}
syscall
EOF
###############################################################################
# getppid(1): exit(getppid())
cat >getppid.asm <<EOF
bits 64
mov eax, ${SYS_GETPPID}
syscall
mov edi, eax
mov eax, ${SYS_EXIT}
syscall
EOF
###############################################################################
# id -u (numeric uid via exit code)
cat >id-u.asm <<EOF
bits 64
mov eax, ${SYS_GETUID}
syscall
mov edi, eax
mov eax, ${SYS_EXIT}
syscall
EOF
###############################################################################
# id -g (numeric gid via exit code)
cat >id-g.asm <<EOF
bits 64
mov eax, ${SYS_GETGID}
syscall
mov edi, eax
mov eax, ${SYS_EXIT}
syscall
EOF
###############################################################################
# kill $ SIGTERM
cat >kill-self.asm <<EOF
bits 64
mov eax, ${SYS_GETPID}
syscall
mov edi, eax
mov esi, ${SIGTERM}
mov eax, ${SYS_KILL}
syscall
EOF
###############################################################################
# pause(1): sleep until signal
# returns only after signal handler or termination
cat >pause.asm <<EOF
bits 64
mov eax, ${SYS_PAUSE}
syscall
EOF
###############################################################################
# sleep 1
# ABI: nanosleep takes two pointers: req, rem
cat >sleep1.asm <<EOF
bits 64
sub rsp, 16
mov qword [rsp], 1 ; tv_sec
mov qword [rsp+8], 0 ; tv_nsec
mov rdi, rsp
xor rsi, rsi ; rem = NULL
mov eax, ${SYS_NANOSLEEP}
syscall
xor edi, edi
mov eax, ${SYS_EXIT}
syscall
EOF
###############################################################################
# uname (stores struct utsname; output discarded)
cat >uname.asm <<EOF
bits 64
sub rsp, 390 ; sizeof(struct utsname)
mov rdi, rsp
mov eax, ${SYS_UNAME}
syscall
xor edi, edi
mov eax, ${SYS_EXIT}
syscall
EOF
###############################################################################
# gettimeofday (obsolete but historically core)
cat >gettimeofday.asm <<EOF
bits 64
sub rsp, 32
mov rdi, rsp ; struct timeval*
xor rsi, rsi ; timezone* = NULL
mov eax, ${SYS_GETTIMEOFDAY}
syscall
xor edi, edi
mov eax, ${SYS_EXIT}
syscall
EOF
###############################################################################
# chdir /
cat >cd-root.asm <<EOF
bits 64
lea rdi, [rel path]
mov eax, ${SYS_CHDIR}
syscall
xor edi, edi
mov eax, ${SYS_EXIT}
syscall
path db "/", 0
EOF
###############################################################################
# pwd (probe only; no output)
# ABI: getcwd writes into user buffer
cat >pwd.asm <<EOF
bits 64
sub rsp, 4096
mov rdi, rsp
mov esi, 4096
mov eax, ${SYS_GETCWD}
syscall
xor edi, edi
mov eax, ${SYS_EXIT}
syscall
EOF
###############################################################################
# umask 0
cat >umask.asm <<EOF
bits 64
xor edi, edi
mov eax, ${SYS_UMASK}
syscall
xor edi, edi
mov eax, ${SYS_EXIT}
syscall
EOF
###############################################################################
# times (writes struct tms)
cat >times.asm <<EOF
bits 64
sub rsp, 64
mov rdi, rsp
mov eax, ${SYS_TIMES}
syscall
xor edi, edi
mov eax, ${SYS_EXIT}
syscall
EOF
###############################################################################
# reboot (dangerous; requires CAP_SYS_BOOT)
# ABI magic required by kernel to prevent accidental reboot
cat >reboot.asm <<EOF
bits 64
mov edi, ${LINUX_REBOOT_MAGIC1}
mov esi, ${LINUX_REBOOT_MAGIC2}
mov edx, ${LINUX_REBOOT_CMD_RESTART}
mov eax, ${SYS_REBOOT}
syscall
EOF
```
1: What was that bit about reboot magic?
0: Let's see.
```man
reboot(2) System Calls Manual
NAME
reboot
LIBRARY
Standard C library (libc, -lc)
DESCRIPTION
...
This system call fails (with the error EINVAL)
unless magic equals LINUX_REBOOT_MAGIC1 (that is, 0xfee1dead)
and magic2 equals LINUX_REBOOT_MAGIC2 (that is, 0x28121969).
However, since Linux 2.1.17 also LINUX_REBOOT_MAGIC2A
(that is, 0x05121996) and since Linux 2.1.97 also
LINUX_REBOOT_MAGIC2B (that is, 0x16041998) and
since Linux 2.5.71 also LINUX_REBOOT_MAGIC2C
(that is, 0x20112000) are permitted as values
for magic2. (The hexadecimal values of these
constants are meaningful.)
```
1: That's a real man page?
0: For the most part.
1: Why those numbers?
0: Why is Christmas on December 25th?
1: Why do you always answer my questions with a question?
0: Answer mine.
1: New Calendar. Year zero. Hypothetical birthday of Josh character. The obvious reasons.
0: Do you think it's plausible that the Josh character was born so close to year 0?
1: Not even slightly.
0: Why not?
1: Too perfect. Seems highly implausible.
0: Agreed. What time is it now?
1: In what format?
0: Since the Epoch.
1: `man 2 time`
```man
NAME
time - get time in seconds
LIBRARY
Standard C library (libc, -lc)
SYNOPSIS
#include <time.h>
time_t time(time_t *tloc);
DESCRIPTION
time() returns the time as the number of seconds
since the Epoch, 1970-01-01 00:00:00 +0000 (UTC).
```
1: `vim time.c`
```c
#include <time.h>
#include <stdio.h>
int main(int argc, char **argv) {
time_t *t;
printf("time since the epoch: %ld\n", time(t));
}
```
```sh
~ $ cc time.c
~ $ ./a.out
time since the epoch: 1765214637
```
1: It's `1765214637`.
> _Unix time is a date and time representation widely used in computing. It measures time by the number of non-leap seconds that have elapsed since 00:00:00 UTC on 1 January 1970._
> -The Dynamic Read-Writable Free Encyclopedic Repository of the Modern State of Human Knowledge
1: Why's that relevant?