Search code examples
apioperating-systemposixglibclibc

What is glibc and POSIX exactly?


I am really confused. Please look at the following picture: enter image description here I found out that there is a library in linux called glibc, which when we execute our c/c++ programs we use its functions and it calls the appropriate system call. In fact it's API that we can use. But I'm confused. Does glibc put in operating system that we use it for our c/c++ programs? So when we write a python/ruby/... program there is no standard library or API , like glibc, that we call its functions and it calls the appropriate system call. So how our codes in python/ruby/... run? Also, what is POSIX? I read wikipedia, but I can't understand. How does it relate to glibc? Please give me examples and simple explanations that I can find out


Solution

  • POSIX is a computer standard which is used to standardize operating-systems. Otherwise operating-systems would all be disparate and there wouldn't be any common things between them (a bit like what Microsoft does with Windows). An open standard (unlike Windows) makes computing more accessible and more affordable in some complex ways. Today, you could think that Linux is in some ways being a non-profit organization which promotes open source computing and free/affordable computing. Linux's websites are mostly in the .org as they are organisms which promote the open computing effort.

    UNIX in the meantime is an operating-system which is POSIX compliant.

    Since glibc works on Linux and Linux is very UNIX-like (see https://www.quora.com/Is-Linux-compatible-with-UNIX), then glibc should work on UNIX systems. Since UNIX is POSIX compliant (see https://linuxhint.com/is_linux_posix_compliant/), then Linux is mostly POSIX compliant.

    For how all that relates you can look at my answer on cs.stackexchange.com here https://cs.stackexchange.com/questions/136298/how-are-kernels-and-operating-systems-in-general-written-in-c/136330#136330.

    When you write a C app on Linux, you include headers from glibc to use the standard functions like malloc, fork etc. When you compile your app, you either compile it statically or dynamically. When you compile it statically, you include all the kernel code in the executable like mmap's code. Basically, when mmap is called from your main function, the CPU jumps to the function which is mapped in virtual memory. Where it "stops" including the code, is when you jump to kernel code using int 0x80 on older x86 32 bits processors. I don't know about the system call convention for x86-64 honestly. It is probably similar. When your code calls int 0x80 on x86, it interrupts the CPU and it jumps to shared-by-all-processes kernel code. This kernel code cannot be included in your executable because it is interrupt code. So mmap is included in your executable up until the system call. The rest of the work is done in the interrupt handler and then returns to mmap which now has the new address of the allocated memory chunk. mmap then returns to the glibc caller which, like you said, is a wrapper around kernel code calls. When you link dynamically, it is the same except linking happens just before runtime.

    POSIX relates to glibc in that POSIX defines the standard API which is going to be called by glibc to implement the C convention. It is really a convention over a convention. The C convention is another convention. It says: if you write this then this should be the result after running the program. Glibc is really looking to implement the C convention but on POSIX compliant systems like Linux.

    In the meantime, Python/Ruby etc. are higher level languages mostly written in lower level languages like C++/C. The Python program which runs your python commands is written in C and compiled. Then you write a Python program which is then interpreted during runtime by the C program. There really is nothing magical. It is just a convention over a convention over a convention. POSIX implements the standard for system calls that glibc uses to implement the C convention that Python uses to implement the Python shell which interprets your Python programs at runtime.