0

Since there is no return of 'fd', how does it read/write later for?

ex:

void init(void)
{
 ....
 (void) open("/dev/tty1",O_RDWR,0);
 ....
Mark
  • 325
  • 1
  • 16
  • 2
    The system will create descriptors sequentially. If there are none, it will begin with `0`. – Some programmer dude Feb 11 '19 at 09:44
  • linux 1.0 source code, main.c. https://mirrors.edge.kernel.org/pub/linux/kernel/Historic/old-versions/ – Mark Feb 11 '19 at 09:44
  • 1
    It doesn't need to assign the FD, because it knows this will be FD 0, since nothing else has been opened yet. – Barmar Feb 11 '19 at 09:47
  • Note that before `open` there's the `(void)` cast. The normal behaviour is to use the integer value the function `open` returns. http://man7.org/linux/man-pages/man2/open.2.html – Sir Jo Black Feb 11 '19 at 09:59

1 Answers1

7

open returns a value in there. The cast-to-void is used to signal the compiler that the return value is being deliberately ignored.

The init function is the one where the current thread is prepared to execute the init program in user-space. init will expect the standard in, out and error descriptors be opened. The full code is this:

(void) open("/dev/tty1",O_RDWR,0);
(void) dup(0);
(void) dup(0);

There is no need to store the return value to anything, since the open is guaranteed to use the lowest free descriptor and none are used by the process before entering this function, thus open will return 0. Same rule of returning the lowest free applies to dup as well. After these 3 calls, all descriptors 0, 1, and 2 share the same file description which also means that you can write to standard in and read from standard error.

This is perhaps a micro-optimization, but there is indeed no need to use a variable and make the compiler generate substandard code when the return value of the open is known - it is after all analogous to

int fd = open("/dev/tty1",O_RDWR,0);
assert(fd == 0);
(void) dup(fd);
(void) dup(fd);

In the current revision there is an assert in place, checking that the open does not fail:

/* Open the /dev/console on the rootfs, this should never fail */
if (ksys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
    pr_err("Warning: unable to open an initial console.\n");

(void) ksys_dup(0);
(void) ksys_dup(0);

However, the actual file descriptor return values are being ignored.

  • It's just my opinion, but I'd say code like `(void) open("/dev/tty1",O_RDWR,0);` that assumes the return value will always be zero is unnecessarily fragile. It completely discounts the possibility of failure while also assuming that the context the code runs in will never change. In my experience, both are all too likely to be proven wrong. – Andrew Henle Feb 11 '19 at 14:59
  • @AndrewHenle yes, it could check the return value with `if` and kernel panic if not 0. – Antti Haapala -- Слава Україні Feb 11 '19 at 15:00