6672 closei (ip, rw)
int *ip;
{
register *rip;
register dev, maj;
rip = ip;
dev = rip->i_addr[0];
maj = rip->i_addr[0].d major;
switch (rip->i_mode&IFMT) {
case IFCHR:
(*cdevsw[maj].d_close)(dev,rw);
break;
case IFBLK:
(*bdevsw[maj].d_close)(dev,rw);
}
iput(rip);
}
This example has a number of interesting features.
The declaration for “d_major” is
struct {
char d_minor;
char d_major;
}
so that the value assigned to “maj” is the hiqh order byte of the value assigned to “dev”.
In this example, the “switch” statement has onlv two non-null cases, and no “default”. The actions for the recognised cases, e.g.
(*bdevsw[maj].d_close)(dev,rw);
look formidable
First it should be noted that this is a procedure call, with parameters “dev” and “rw”.
Second “bdevsw” (and “cdevsw”) are arrays of structures, whose “d_close” element is a pointer to a function, i.e.
bdevsw[maj]
is the name of a structure, and
bdevsw[maj].d_close
is an element of that structure which happens to be a pointer to a function, so that
*bdevsw[maj].d_close
is the name of a function. The first pair of parentheses is “syntactical sugar” to put the compiler in the right frame of mind!