a library call versus a system call
Picture two kinds of help you might ask for at work. Some questions a colleague at the next desk can answer instantly without leaving the room - that is fast, local, no big deal. Other questions need someone to physically go to a secured building, badge in, do the task, and come back - slower, and it involves crossing a guarded boundary. Library calls are the colleague at the next desk; system calls are the trip to the secured building.
A library call is a call to a function that lives in user space, in a library linked into your program - the C standard library, a math library, your own helpers. It runs in user mode, in the same privilege level as the rest of your code, and crosses no protection boundary; it is, mechanically, just a jump-and-return inside your process. A system call, by contrast, is a request to the kernel: it traps across the user/kernel boundary, switches privilege mode, runs trusted kernel code, and switches back. The confusing part is that many library calls and many system calls have similar-looking C syntax - you write strlen(s) and read(fd, buf, n) the same way - so the distinction is invisible in the source. The difference is in where the work happens and whether the privilege wall was crossed.
Why it matters: this distinction drives both performance and correctness reasoning. A library call that stays in user mode is cheap; one that ends up making a system call pays the boundary-crossing cost. It also affects how you debug: ltrace shows library calls, while strace shows system calls, and a single library call like fwrite() might trigger several or zero system calls depending on buffering. A common beginner misconception is that every standard-library function 'goes to the OS' - most do not; only the ones that need a privileged operation cross over.
strlen(s) is a pure library call - it counts characters in memory and never enters the kernel. write(1, s, n) is a system call - it traps in to put bytes on standard output. fputs(s, stdout) is a library call that may buffer your text and only later make a write() system call.
Same C syntax, very different machinery: only some calls cross into the kernel.
You cannot tell from the source code alone whether a function is a library call or a system call - that depends on what the function does internally. The reliable tells are tools (strace vs ltrace) and documentation, not the way the call is written.