The truth is that there has been little consistency in the numbering conventions used for new system calls. In a few cases, such numbering has represented successive "versions" of a system call (for example, mmap2() and sync_file_range2()). In several other cases, the numbering has reflected the argument count. And in at least one fortuitous case, the numbering has reflected the argument count and the "version" (dup(), dup2(), and dup3()).
The use of "version numbers" in the names of new system calls doesn't have have any strong arguments in its favor. However, the convention of
naming system calls according to the number of arguments seems even worse, for a number of reasons. Among these are the following:
- The number of arguments exposed by a system call may differ from the number of arguments exposed by the corresponding wrapper function. For example, the pselect6() system call has six arguments, while the C library pselect() wrapper function has just 5 arguments.
- A new "version" of a system call might have the same number of arguments as the numbered system call it replaces. That precise situation hasn't occurred so far, but there has been at least one case where a system call named according to its number of arguments has had the same number of arguments as the call it supersedes: epoll_create() and epoll_create1() both have the same number of arguments.
- Finally, if a system call supports a flags argument, then it is possible that a subsequent enhancement to the system call may allow additional arguments to be specified, depending on the use of special bit values in the flags argument (clone(), fcntl(), mremap(), and open() are existing examples of such variadic system calls). In that case, the naming system no longer bears any relation to the number of arguments in the system call.
by avoiding the need to create new versions of systems calls, which was the main point of my recent LWN.net article, Flags as a system call API design pattern.