how to find the implementation of a function in linux? - c

Sometimes, I want to know the implementation of a c function. My editor is vim. I have try ctags and cscope, and man.
man 2|3 only tell me how to use a function.
Both ctags and cscope can just find some of the implementation of functions.
They all can't find some functions. especially some system function(calls).
If a function can be use by include some header file, is there any way easily find the implementation of a function,

select(2) is a system call (but I suggest using poll(2) instead - google for C10K problem to understand why I prefer poll over select). So it is really implemented inside the linux kernel. The libc contains a small stub function (translating the C argument convention to the syscall convention, then doing the real syscall with e.g. some SYSENTER machine instruction). You could look into the source code of MUSL Libc (I recommend MUSL libc because its source is much easier to read) or the real Gnu libc to see that wrapper function.
FD_SET is just a macro, defined in /usr/include/x86_64-linux-gnu/sys/select.h and really in /usr/include/bits/select.h
But you are very right to try to find out how software functions of Linux are implemented: take advantage that it is free software.
Actually, the syscall layer is well defined and quite stable (see the syscalls(2) man page, and read Advanced Linux Programming for more. Look also for the Posix standards). It is much more interesting to study the source code of higher-level libraries using them (e.g. Qt, Gtk, ...).
From an application's point of view, syscalls are elementary "atomic" operations. strace is a handy utility to find which syscalls are done by some process (or running program).

You won't get around pulling in the sources of the module providing the function's implementation.
For Linux most of the modules in use are open source, so access to the sources shall be possible.
Where to get the sources from depends on library and/or the distribution in use. This includes the kernel.
There are distributions which may include all sources. Gentoo is one of those.
For Debian based distros it is easy to pull a package's sources using the apt-get tool:
$ apt-get source <package-name>
Other distros may use other ways to provide sources. Perhaps fellow SO experts might like to comment/answer regarding those.

Related

Where is socket create function implemented in linux

I know the function to create socket:int socket(int domain, int type, int protocol); is located in #include <sys/socket.h> and I can find it on my linux file system.
But where I can find the implementation of this function? I couldn't find a matching one in the kernel source.
Look on kernel.org for the authentic kernel source. Understand that socket(2) is one of the many syscalls(2) (you need to understand precisely what system calls are) so it is implemented inside the kernel as sys_socket and/or sys_socketcall and/or do_socket; sockets and network code are an entire subsystem (net/) of the kernel, so see its net/socket.c, etc etc... See also socketcall(2)
Application user-side code are simply issuing a syscall, so socket(2) is a thin wrapper around a system call (in GNU libc or musl-libc or whatever implementation of the C standard library you are using). See also this.
sys/socket.h should be in /usr/include. Typically, it's a part of the "GNU C Library", but depending on your system, that might also be a different C library (ie. on systems you can't call GNU/Linux, like Android, there might be different libc than glibc).
However, that's just the header, not the implementation of the syscalls beneath! You will have to look through glibc's source code (which usually is not installed, only the headers), and then match what you find there to the system calls implementation in linux.
if you want to check the linux implementation of socket creation, you. can look here

The C language and Mac OSX

I was wondering whether anybody here could help me better understand the relationship between OSX and C. There's some developer information related to C++ in xcode but nothing for C.
I believe one fundamental difference is that osx uses libc as opposed to glibc. Can anybody point me to libc documentation? I can't seem to find any.
I've seen the usr/includes folder but all that does is make me wonder where I can get a reference that elucidates all the options available to me. For instance, I just discovered <tree.h>. That's all well and good but is there any documentation? Or do I need to trawl the includes folder?
It seems that you're asking whether the functionality that OSX provides to you as a programmer is partially different from other *nix systems; focusing on the functionality that OSX's implementation of the C Standard Library provides you with.
Now keep in mind that while the C Standard Library is a very common way to take advantage of the functionality the operating system kernel exposes, it's not the only way. You can use other low-level libraries, or write low-level functions yourself.
Having said that, consider the following:
OSX, like many other *nix systems, is "mostly POSIX-compliant". Meaning that its particular C Standard Library implementation will likely expose headers defined by the POSIX standard. This is the stuff you can rely on regardless of whether you use libc, glibc, or some other implementation of the C Standard Library.
Depending on the particular C Standard Library you're using, it might come with additional functionality, like BSD libc - we say "superset of the POSIX Standard Library" to that. While it can contain implementations of things specific to BSD (and therefore OSX), it mostly seems to contain things that can be implemented regardless of the operating system flavour. For example, the sys/tree.h header that you mention is "an implementation of Red-black tree and Splay tree" - by no means something that couldn't have been implemented on a Linux system!
To sum up:
OSX comes with an implementation of the C Standard Library called BSD libc that provides some additional headers on top of what the POSIX Standard defines.
The difference in functionality between the XNU kernel used by OSX and other *nix kernels will not necessarily be captured in the difference between the C Standard Library implementations. If you want to know what the XNU kernel can do for you that the Linux kernel can't, the place to start is with the kernels themselves.
So your question can be split into:
What is the difference between glibc and BSD libc?
and
What is the difference between the XNU kernel and the Linux kernel?
It's a bit unclear what you're asking.
OS X is based on top of FreeBSD, a POSIX-compliant UNIX operating system. The relationship between OS X and C is that C is one of many programming languages that you can code in to develop for the platform (C is the core of Objective-C, an otherwise unused language that Apple champions).
OS X doesn't use libc. clang, the compiler that ships as part of Apple's developer tools package for OS X, uses libc. There's a difference. If you want to use glib, grab GCC from Homebrew or Macports and use it to compile your programs instead of clang.
Lastly, you can't find documentation for libc, as all C libraries, like libc, glibc, etc, all provide the same set of functions if they are standards-compliant. There tend to be few differences end-user-wise between the different C libraries; so, if you want to find out about a header file, use man, like this: man clang to read clang documentation, for example.
Hope this helps.

dos.h for Linux?

I have a C program which contains #include <dos.h> header. It shows a compile time error. I know that the dos.h header file is not valid in Linux.
Is there any other equivalent header for dos.h in Linux?
Linux is a Posix/Unix like system, so you should learn the system calls and facilities that you can use. Read the advanced unix programming book (or some equivalent; AUP is considered a very good book). You can also read advanced linux programming (even online, a copy is here). So Linux don't have a dos.h header.
You could also type man 2 intro to get an intro to syscalls, and their list in in syscalls(2) man page. From an application's point of view syscalls are elementary operations provided by the Linux kernel.
The GNU libc provides a big lot of functionality (e.g. standard C functions like malloc and fprintf, and system functions like fgetpwent to query user database, etc etc...) above the system calls. Almost every Linux program uses it.
If you care about coding stuff which should be portably runnable (after recompilation) on other similar systems (e.g. MacOSX or FreeBSD) consider following the Posix standard.
If you want to code a terminal screen application, consider using ncurses.
If you care about graphical interfaces, use a graphical toolkit like Qt or Gtk; they usually interact with an X11 server (and both Qt and Gtk are able to run on some other non Posix systems, e.g. Windows, by providing a common graphical abstraction layer.). Both Gtk and Qt are adding an abstraction layer (Glib and QCore respectively) above system functions and facilities (in particular above the pthreads standard thread library).
At last, Linux is free software; so you might find interesting to look inside the source code (of a library or utility) that you are using. You could even improve it and contribute to it.
In all these aspects, Linux programming is very different from Windows or DOS.
Don't try to mimic every Windows or Dos function into Linux (e.g. don't ask the equivalent of every dos.h function); learn the Posix/Unix way of thinking and coding.
The time(7) man page tells you a lot about time (various meanings and functions about it) on Linux.
Don't forget to ask warnings from the compiler with gcc -Wall -Wextra; as a general rule, improve your source code till you get no warnings.
There cannot be an exact Linux equivalent of dos.h because Linux (i.e. Unix or Posix spec) and Windows are systems with different features and concepts. However several free libraries (I mentioned Glib and QCore) are providing common abstractions to fit into Linux and into Windows, so if you want to develop software portable to Windows and to Linux I suggest using these libraries instead (use them both on Windows and on Linux).
(I also suspect that Microsoft would use legal threats -patent or copyright based- to avoid that free clone of their proprietary dos.h, given their monopolistic reputation and their aversion to standards and to free software; I admit I have strong opinions against Microsoft..)
dos.h header file is interface to the DOS operating system. They are not portable to operating systems other than DOS (means not works in Linux). Which functionality in dos.h you are going to use?
#include<dos.h> is not available for Linux
but if you want to use dos.h for displaying the time you can use the system function and do it like this
prototype -> system(command);
system("date +%H:%M:%S");
if you want your program to sleep for a specific seconds
try this
system("sleep 3") //sleep for a 3 seconds
or use this
std::this_thread::sleep_for(std::chrono::milliseconds(100));
but you have to include the thread header file #include<thread>

automatically linking socket shared library in *nix

I am learning network programming through the sample source codes from this link http://cs.baylor.edu/~donahoo/practical/CSockets/textcode.html. During the compilation, just wondering why in Solaris environment, i have to manually link socket and nsl library in the make file but when in the linux machine, i dont need to do that ?
Documentation used: http://developers.sun.com/solaris/articles/solaris_linux_app.html
This is because linux's libc, the glibc (-lc, which is linked by default to all programs) includes socket part of POSIX; and nis/nis+ dynamic libraries in linux are loaded dynamically by libc too.
But in Solaris, there are a lot of libraries with basic functionality, which are not in libc.
(libc, libucb, libmalloc, libsocket, libxnet, etc). I think, it was a design solution to allow user link only parts of API he needs.
In linux there are some basic libraries outside libc too: libaio, librt, libm.
With separate library it is easier to update only some parts of system; and it is possible to have several implementations (e.g. to provide greater compatibility/workarounds with older versions of UNIX) of some libraries coexisting in same system.
This question is discussed a lot, e.g. http://web.archiveorange.com/archive/v/KcxCHdLNpD6NANxmAt3b http://mail.opensolaris.org/pipermail/opensolaris-code/2007-January/010316.html
are seriously considering folding libnsl and libsocket into libc.
It would be nice to move ONLY the current POSIX-based and other
standards-based functionality (Unix98 etc.) libnsl+libsocket functions
to libc and keep all the compatibilty-wrapper stuff in libnsl/libsocket
to avoid that libc gets bloated with 20years of Unix
backwards-compatibility workarounds
Because in Linux, the entire networking API is implemented in libc.so which is linked into every C program by default, while in Solaris, its implemented in separate libraries.

What's the difference between "C system calls" and "C library routines"?

There are multiple sections in the manpages. Two of them are:
2 Unix and C system calls
3 C Library routines for C programs
For example there is getmntinfo(3) and getfsstat(2), both look like they do the same thing. When should one use which and what is the difference?
System calls are operating system functions, like on UNIX, the malloc() function is built on top of the sbrk() system call (for resizing process memory space).
Libraries are just application code that's not part of the operating system and will often be available on more than one OS. They're basically the same as function calls within your own program.
The line can be a little blurry but just view system calls as kernel-level functionality.
Libraries of common functions are built on top of the system call interface, but applications are free to use both.
System calls are like authentication keys which have the access to use kernel resources.
Above image is from Advanced Linux programming and helps to understand how the user apps interact with kernel.
System calls are the interface between user-level code and the kernel. C Library routines are library calls like any other, they just happen to be really commonly provided (pretty much universally). A lot of standard library routines are wrappers (thin or otherwise) around system calls, which does tend to blur the line a bit.
As to which one to use, as a general rule, use the one that best suits your needs.
The calls described in section 2 of the manual are all relatively thin wrappers around actual calls to system services that trap to the kernel. The C standard library routines described in section 3 of the manual are client-side library functions that may or may not actually use system calls.
This posting has a description of system calls and trapping to the kernel (in a slightly different context) and explains the underlying mechanism behind system calls with some references.
As a general rule, you should always use the C library version. They often have wrappers that handle esoteric things like restarts on a signal (if you have requested that). This is especially true if you have already linked with the library. All rules have reasons to be broken. Reasons to use the direct calls,
You want to be libc agnostic; Maybe with an installer. Such code could run on Android (bionic), uClibc, and more traditional glibc/eglibc systems, regardless of the library used. Also, dynamic loading with wrappers to make a run-time glibc/bionic layer allowing a dual Android/Linux binary.
You need extreme performance. Although this is probably rare and most likely misguided. Probably rethinking the problem will give better performance benefits and not calling the system is often a performance win, which the libc can occasionally do.
You are writing some initramfs or init code without a library; to create a smaller image or boot faster.
You are testing a new kernel/platform and don't want to complicate life with a full blown file system; very similar to the initramfs.
You wish to do something very quickly on program startup, but eventually want to use the libc routines.
To avoid a known bug in the libc.
The functionality is not available through libc.
Sorry, most of the examples are Linux specific, but the rationals should apply to other Unix variants. The last item is quite common when new features are introduced into a kernel. For example when kqueue or epoll where first introduced, there was no libc to support them. This may also happen if the system has an older library, but a newer kernel and you wish to use this functionality.
If your process hasn't used the libc, then most likely something in the system will have. By coding your own variants, you can negate the cache by providing two paths to the same end goal. Also, Unix
will share the code pages between processes. Generally there is no reason not to use the libc version.
Other answers have already done a stellar job on the difference between libc and system calls.

Resources