3

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 ?

closed as off-topic by derobert, Anthon, cuonglm, Hauke Laging, jasonwryan Jul 16 '14 at 18:16

  • This question does not appear to be about Unix or Linux within the scope defined in the help center.
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 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 Jul 16 '14 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 Jul 16 '14 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... – Rouben Tchakhmakhtchian Jul 16 '14 at 15:50
  • 4
    This question appears to be off-topic per meta.unix.stackexchange.com/a/2937/977 – derobert Jul 16 '14 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. – ctrl-alt-delor Jul 16 '14 at 17:06
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.

  • does that mean that these functions write(),read() are written directly in assembly language..?? – saurav1405 Jul 18 '14 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. – Bruce Ediger Jul 18 '14 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.

  • kernel code is not relevant to the question. – ctrl-alt-delor Jul 16 '14 at 17:08

Not the answer you're looking for? Browse other questions tagged or ask your own question.