misc

How System Calls Work on Linux

  • First, the user application program sets up the arguments for the system call.
  • After the arguments are all set up, the program executes the “system call” instruction.
  • This instruction causes an exceptionan event that causes the processor to jump to a new address and start executing the code there.
  • The instructions at the new address save your user program’s state, figure out what system call you want, call the function in the kernel that implements that system call, restores your user program state, and returns control back to the user program.

A visual explanation of a user application invoking the open() system call:

enter image description here

It should be noted that the system call interface (it serves as the link to system calls made available by the operating system) invokes intended system call in OS kernel and returns status of the system call and any return values. The caller need know nothing about how the system call is implemented or what it does during execution.
Another example: A C program invoking printf() library call, which calls write() system call

enter image description here

 

 

https://www.tldp.org/LDP/khg/HyperNews/get/syscall/syscall86.html

http://www.linux.it/~rubini/docs/ksys/

https://www.ibm.com/developerworks/community/blogs/58e72888-6340-46ac-b488-d31aa4058e9c/entry/linux_system_calls20?lang=en

https://stackoverflow.com/questions/24036214/how-does-a-system-call-work

 

typedef versus #define in C

typedef is different from #define among the following aspects

  • typedef is limited to giving symbolic names to types only, where as #define can be used to define alias for values as well, e.g., you can define 1 as ONE, 3.14 as PI, etc.
  • typedef interpretation is performed by the compiler where #define statements are performed by preprocessor.
  • #define should not be terminated with semicolon, but typedef should be terminated with semicolon.
  • #define will just copy-paste the definition values at the point of use, while typedef is actual definition of a new type.
  • typedef follows the scope rule which means if a new type is defined in a scope (inside a function), then the new type name will only be visible till the scope is there. In case of #define, when preprocessor encounters #define, it replaces all the occurrences, after that (No scope rule is followed).

 

inline function vs a macro

Inline replaces a call to a function with the body of the function, however, inline is just a request to the compiler that could be ignored (you could still pass some flags to the compiler to force inline or use always_inline attribute with gcc).

A macro on the other hand, is expanded by the preprocessor before compilation, so it’s just like text substitution, also macros are not type checked, inline functions are. There’s a comparison in the wiki.

For the sake of completeness, you could still have some kind of type safety with macros, using gcc’s __typeof__ for example, the following generate almost identical code and both cause warnings if used with the wrong types:

#define max(a,b) \
  ({ __typeof__ (a) _a = (a); \
      __typeof__ (b) _b = (b); \
    _a > _b ? _a : _b; })

__attribute__((always_inline)) int max(int a, int b) {
   return (a > b ? a : b);
}

Note: sometimes typeless macros are just what’s needed, for example, have a look at how uthashuses macros to make any C structure hashable without resorting to casts.

https://stackoverflow.com/questions/13375288/inline-function-vs-macro-function

https://www.programmerinterview.com/index.php/c-cplusplus/inline-vs-macro/