System Calls in Unix and Windows
The interface between a process and an operating system is provided by system calls. In general, system calls are available as assembly language instructions. They are also included in the manuals used by the assembly level programmers.
Unix System Calls
System calls in Unix are used for file system control, process control, interprocess communication etc. Access to the Unix kernel is only available through these system calls. Generally, system calls are similar to function calls, the only difference is that they remove the control from the user process.
There are around 80 system calls in the Unix interface currently. Details about some of the important ones are given as follows —
System Call | Description |
---|---|
access() | This checks if a calling process has access to the required file |
chdir() | The chdir command changes the current directory of the system |
chmod() | The mode of a file can be changed using this command |
chown() | This changes the ownership of a particular file |
kill() | This system call sends kill signal to one or more processes |
link() | A new file name is linked to an existing file using link system call. |
open() | This opens a file for the reading or writing process |
pause() | The pause call suspends a file until a particular signal occurs. |
stime() | This system call sets the correct time. |
times() | Gets the parent and child process times |
alarm() | The alarm system call sets the alarm clock of a process |
fork() | A new process is created using this command |
chroot() | This changes the root directory of a file. |
exit() | The exit system call is used to exit a process. |
Windows System Calls
System calls in Windows are used for file system control, process control, interprocess communication, main memory management, I/O device handling, security etc. The programs interact with the Windows operating system using the system calls. Since system calls are the only way to access the kernel, all the programs requiring resources must use system calls.
Details about some of the important system calls in Windows are given as follows —
select interrupted system call
I am creating a timer which runs approximately every second and which is waiting for a key to be pressed (which i am not doing). While it is running it shows:
Can you tell me why its this is happening:
1 Answer 1
It may be worth mentioning two things:
- Blocking functions such as select , read , etc.. get interrupted by signals. You may like to set SA_RESTART flag when calling sigaction . man signal(7) :
If a signal handler is invoked while a system call or library function call is blocked, then either:
- the call is automatically restarted after the signal handler returns; or
- the call fails with the error EINTR.
Which of these two behaviors occurs depends on the interface and whether or not the signal handler was established using the SA_RESTART flag (see sigaction(2)). The details vary across UNIX systems; below, the details for Linux.
- In the signal handler you should only call async signal safe functions. Or use the self-pipe trick to avoid doing anything in the signal handler at all.
Alternatively, there is a way to have timers without using timer_create and timerfd_create . select accepts a timeout argument which can be used to specify time till the next timer expiry. Then, select returns 0 if the timeout occurred. This method applies to other event demultiplexing APIs, such as poll and epoll .
Select() system call in threads?
I am reading data from multiple serial ports. At present I am using a custom signal handler (by setting sa_handler) to compare and wake threads based on file descriptor information. I was searching for a way out to have individual threads with unique signal handlers, in this regard I found that select system call is to be used.
Now I have following questions:
- If I am using a thread (Qt) then where do I put the select system call to monitor the serial port?
- Is the select system call thread safe?
- Is it CPU intensive because there are many things happening in my app including GUI update?
Please do not mind, if you find these questions ridiculous. I have never used such a mechanism for serial communication.
2 Answers 2
The POSIX specification (select) is the place to look for the select definition. I personally recommend poll — it has a better interface and can handle any number of descriptors, rather than a system-defined limit.
If I understand correctly you’re waking threads based on the state of certain descriptors. A better way would be to have each thread have its own descriptor and call select itself. You see, select does not modify the system state, and as long as you use thread-local variables it’ll be safe. However, you will definitely want to ensure you do not close a descriptor that a thread depends on.
Using select / poll with a timeout leaves the «waiting» up to the kernel side, which means the thread is usually put to sleep. While the thread is sleeping it is not using any CPU time. A while/for loop on a select call without a timeout on the other hand will give you a higher CPU usage as you’re constantly spinning in the loop.
Hope this helps.
EDIT: Also, select / poll can have unpredictable results when working with the same descriptor in multiple threads. The simple reason for this is that the first thread might be woken up because the descriptor is ready for reading, but the second thread has to wait for the next «available for reading» wakeup.
As long as you’re not select ing on the same descriptor in multiple threads you should not have a problem.
Select system call windows
Windows System Call Tables
The repository contains system call tables collected from all modern and most older releases of Windows, starting with Windows NT.
Both 32-bit and 64-bit builds were analyzed, and the tables were extracted from both the core kernel image ( ntoskrnl.exe ) and the graphical subsystem ( win32k.sys ).
The data is formatted in the CSV and JSON formats for programmatic use, and as an HTML table for manual inspection.
The HTML files are also hosted on my blog under the following links:
The following major versions of Windows are included in the tables:
System | x86 versions | x64 versions |
---|---|---|
Windows NT | SP3 Terminal Server, SP3, SP4, SP5, SP6 | – |
Windows 2000 | SP0, SP1, SP2, SP3, SP4 | – |
Windows XP | SP0, SP1, SP2, SP3 | SP1, SP2 |
Windows Server 2003 | SP0, SP1, SP2, R2, R2 SP2 | SP0, SP2, R2, R2 SP2 |
Windows Vista | SP0, SP1, SP2 | SP0, SP1, SP2 |
Windows Server 2008 | SP0, SP2 | SP0, SP2, R2, R2 SP1 |
Windows 7 | SP0, SP1 | SP0, SP1 |
Windows Server 2012 | – | SP0, R2 |
Windows 8 | 8.0, 8.1 | 8.0, 8.1 |
Windows 10 | 1507, 1511, 1607, 1703, 1709, 1803, 1809, 1903, 1909, 2004, 20H2 | 1507, 1511, 1607, 1703, 1709, 1803, 1809, 1903, 1909, 2004, 20H2 |
Windows Server 2016 and later are not included, as their syscall tables are equivalent to that of Windows 10:
Windows Server version | Windows 10 release |
---|---|
2016 LTSC (1607) | 1607 |
1709 | 1709 |
1803 | 1803 |
2019 LTSC (1809) | 1809 |
1903 | 1903 |
1909 | 1909 |
2004 | 2004 |
20H2 | 20H2 |
Historical system call counts
Below is a line chart showing the progression of Windows system call development over time. It covers all major desktop versions of Windows starting with Windows NT 4.0 released in August 1996, up to the most recent versions of Windows 10. Server editions are not included as their kernels are equivalent to their desktop counterparts. The analysis was performed on x86 builds for consistency, as this is the only CPU architecture which covers all available systems. There might be very small differences on x64 builds of the kernel or the less popular editions (e.g. Windows NT 4.0 Terminal Server), but they are insignificant for the purpose of this overview chart.
We would like to thank the following contributors to the project: Woodmann, Deus, Gynvael Coldwind, MeMek, Alex, Omega Red, Wandering Glitch.
Can I access Windows Kernel system calls directly?
I have been doing research into Windows internals, and have just recently learned about system calls and I am wondering if it is possible to use these system calls like functions? I understand they aren’t really meant to be accessed externally.
For instance: NtUserEmptyClipboard is a system call in Win32k.sys, and it’s address is 0x117f
If I wanted to use this call like a function, how could I do so?
4 Answers 4
What you want to do depends heavily on the architecture you’re interested, but the thing to know is, that ntdll.dll is the user-mode trampoline for every syscall — i.e. the only one who actually makes syscalls at the end of the day is ntdll.
So, let’s disassemble one of these methods in WinDbg, by opening up any old exe (I picked notepad). First, use x ntdll!* to find the symbols exported by ntdll:
So, let’s pick one at random, NtReadFile looks neato. Let’s disassemble it:
Here, we see that we stuff away rcx , put the syscall number into eax , then call the syscall instruction. Every syscall has a number that is assigned arbitrarily by Windows (i.e. this number is a secret handshake between ntdll and the kernel, and changes whenever Microsoft wants)
None of these instructions are «magic», you could execute them in your app directly too (but there’s no practical reason to do so, of course — just for funsies)
EmptyClipboard is one of so-called «Win32 API» and NtUserEmptyClipboard is a corresponding «native API».
Unlike Linux syscall(2) , we are rarely supposed to directly call «native API». I heard they are in ntdll.dll rather than win32k.sys . But we should be able to invoke them just like normal functions defined in a normal DLL.
I strongly doubt that 0x117f is the address you’re looking for. I suspect it might be the value which you need to pass to GetProcAddress . But I don’t know for sure, since those things vary across Windows versions (that’s why ordinary people use documented functions instead)
The main part of the native API is exported via normal functions from ntdll.dll. You can load this dll into your process and call these functions just like any other API functions. As long as you have the right function prototypes and parameters, the calls will work just fine. What they do internally is transition from usermode to kernelmode and then they use an offset into the system service descriptor table (SSDT) to find the address of the function in kernel mode memory, and then the function is called. There is an open source project http://nativetest.codeplex.com/ that makes calls to the native api that you might refer to.
The functions in win32k.sys are not exposed in ntdll.dll. As far as I can tell they are not exposed anywhere. The address you have listed — I believe — is actually an offset into the SSDT. If you really needed to call this function, you would have to make the transition from usermode to kernelmode yourself, putting all the parameters for the function and the SSDT offset into the right places.
As others have recommended, I would suggest to find the usermode API to help accomplish what you want to do. FWIW, in user32.dll the function EmptyClipboard appears to forward directly to NtUserEmptyClipboard, according to the link /dump output.