Linux Programming – Part 12: Other System-calls

Not so important actually…

In this section, we’ll take a look at other types of system-calls that are not as commonly used as the ones shown in the previous section. Here, let’s dive into it!

File-offset

Up to this point, we’ve only seen the processes of streaming files. But from here, let’s dive into more details. The previous section’s point where the process ended will be returned when it executes read() system-calls to the same file descriptor. Therefore, the last streamed section, where the last process was finished, could be recorded somewhere, right? As is shown in image 01, the system streams to a specific point in a file, and we call this point a file offset.

image 01 file offset

The file offset is a part of the streaming feature, and it can be controlled via system-calls. One of the most well-known system-call is lseek().

#include <sys/type.h>
#include <unistd>

off_t lseek(int fd, off_t offset, int whence);

lseek() will access the file offset point where you specified in file descriptor fd. There are three different methods and you must specify in whence. Look at chart 01.

flagwhere to
SEEK_SETmove to offset
SEEK_CURmove to ‘current file offset’ + offset
SEEK_ENDmove to ‘the end of file’ + offset
chart 01

image 01
image 02
image 03
image 04

Please note that in some specific cases, you can’t use lseek(), such as a streaming process connected to the terminal, which ends up in an error.

For the record, sleek()’s L is for long. There used to be a legacy system-call, called seek(), and its second argument offset was short. The Long version of the legacy one is today’s sleek() which we currently use.

dup(), dup2()

#include <unistd>

int dup(int oldfd);
int dup2(int oldfd, intnewfd);

dup() and dup2() are system-calls that duplicate the file descriptor oldfd. As you may guess, dup is for duplicate.

Since dup() and dup2() are often used with system-call-related processes, we’ll take a look into it later on…

ioctl()

#include <sys/ioctl.h>

int ioctl(int fd, unsigned long request, ...);

ioctl() is a system call that is specified for controlling external devices, such as:

  • Opening DVD driver’s tray, playing CD songs
  • Running/posing printers
  • Setting SCSI devices’ hardware option settings
  • Settings a device’s communication speeds

The unified interface of UNIX’s open(), read(), write(), and close() system-calls is clean and simple, everything that is messily complicated is all in ioctl().

You will specify a constant number that represents a specific order in the second argument request and will specify another specific controlling order in the third. All available request‘s list is written in man ioctl_list, so I highly recommend you take a look at it at least once.

fcntl()

#include <fcntl.h>
#include <unistd>

int fcntl(int fd, int cmd, ...);

This is another system-call that receives dynamic arguments. The second argument cmd receives a specific controlling method, and the third argument receives another specific method related to the one specified in the second.

The simplest form of its use-case is probably dup(). fcntl(fd, F_DUPFD) is exactly the same as dup(fd). There are many other use cases for it, but they are not something commonly seen, so we’ll skip this system-call. If you’re interested, take a look at it by man 2 fcntl.

Leave a Reply