2

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 ?

5
  • I have looked this up and I see theres a bunch of system calls that Linux can make. I found a list of them as well as their syntax on this URL: man7.org/linux/man-pages/man2/syscalls.2.html
    – ryekayo
    Commented Jul 16, 2014 at 15:16
  • You can't, because it's not part of the C standard :p. IOW it depends on the cpu architecture, e.g. x86 or ARM, and has to be written in assembly language. Ref syscall(2)
    – sourcejedi
    Commented Jul 16, 2014 at 15:45
  • What exactly are you trying to achieve? If your goal is to create a portable (i.e. not dependent on any external libraries) executable binary, you could consider static linking... Commented Jul 16, 2014 at 15:50
  • 4
    This question appears to be off-topic per meta.unix.stackexchange.com/a/2937/977
    – derobert
    Commented Jul 16, 2014 at 15:51
  • You can start by looking at 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 how syscall is implemented, you will see some assembler language — different for each cpu-architecture/kernel combination. Commented Jul 16, 2014 at 17:06

2 Answers 2

5

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.

2
  • does that mean that these functions write(),read() are written directly in assembly language..??
    – saurav1405
    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 file src/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.
    – user732
    Commented Jul 18, 2014 at 17:02
3

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.

1
  • kernel code is not relevant to the question. Commented Jul 16, 2014 at 17:08

Not the answer you're looking for? Browse other questions tagged .