System call naming and numbering

Various commentators have remarked that the name of the proposed new renameat2() system call seems inconsistent; see, for example, these comments in an LWN.net article that discusses renameat2(). The idea is that when system calls are numbered in this fashion, the number should reflect the number of arguments, rather than the being a "version" number. Thus, with five arguments, the new system call should be called renameat5(), in the fashion of other system calls such as accept4() and signalfd4().

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.
The ideal solution, of course, is to avoid the naming problem altogether,
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.

No comments:

Post a Comment