C provides library functions such as write(),read().. for system calls.How to make a system call without using any library in linux in C ?
2 Answers
Ambition or a overly severe urge for purity can lead you to do in-line assembly. For example, on x86_64 systems, you can do an open(2)
system call like this:
#include <sys/syscall.h>
int
linux_open(const char *pathname, unsigned long flags, unsigned long mode)
{
long ret;
asm volatile ("syscall" : "=a" (ret) : "a" (__NR_open),
"D" (pathname), "S" (flags), "d" (mode) :
"cc", "memory", "rcx",
"r8", "r9", "r10", "r11" );
if (ret < 0)
{
errno = -ret;
ret = -1;
}
return (int) ret;
}
You can look at the source of more comprehensible libc's (like Musl) to find out how system calls get implemented, too.
-
does that mean that these functions write(),read() are written directly in assembly language..?? Commented Jul 18, 2014 at 14:31
-
@saurav1405 - you can look at the source to find out, but for Musl libc, you can look at
http://git.musl-libc.org/cgit/musl/tree/src/unistd/read.c
- it's in C, but it uses a macro that I trace to the filesrc/thread/x86_64/syscall_cp.s
. The macro expands into in-line assembly. So I'm not sure what to call it: "written in assembly" or "written in C with a line or two of assembly". Probably the latter.– user732Commented Jul 18, 2014 at 17:02
In order to do system calls you normally have to execute some functions on the CPU that are not part of the C language specification. The system calls are either written in assembly for the CPU, and linked against, or some CPU specific inline assembly within a C function is used.
Within the Linux kernel there are various macros defined to support this, because all system calls require a very similar setup. The result is that it is often quite unclear where the CPU specific assembler is actually coming from, but if you dig deep enough, you will get at it.
syscall
still part of glibc, it is the lowest level of all the system calls, all others could be implemented using it. Then download the source code of glibc, and look at howsyscall
is implemented, you will see some assembler language — different for each cpu-architecture/kernel combination.