hi,

i am reading the book "Operating Systems Design and Implementation 3rd edition" which analyzes the minix source code... in the part of filesystems we see this code

PUBLIC _PROTOTYPE (int (*call_vec[]), (void) ) = {
	no_sys,		/*  0 = unused	*/
	do_exit,	/*  1 = exit	*/
	do_fork,	/*  2 = fork	*/
	do_read,	/*  3 = read	*/
	do_write,	/*  4 = write	*/
	do_open,	/*  5 = open	*/
	do_close,	/*  6 = close	*/
	no_sys,		/*  7 = wait	*/
	do_creat,	/*  8 = creat	*/
	do_link,	/*  9 = link	*/
	do_unlink,	/* 10 = unlink	*/
	no_sys,		/* 11 = waitpid	*/
	do_chdir,	/* 12 = chdir	*/
	no_sys,		/* 13 = time	*/
	do_mknod,	/* 14 = mknod	*/
	do_chmod,	/* 15 = chmod	*/
	do_chown,	/* 16 = chown	*/
	no_sys,		/* 17 = break	*/
	do_stat,	/* 18 = stat	*/
	do_lseek,	/* 19 = lseek	*/
	no_sys,		/* 20 = getpid	*/
	do_mount,	/* 21 = mount	*/
	do_umount,	/* 22 = umount	*/
	do_set,		/* 23 = setuid	*/
	no_sys,		/* 24 = getuid	*/
	do_stime,	/* 25 = stime	*/
	no_sys,		/* 26 = ptrace	*/
	no_sys,		/* 27 = alarm	*/
	do_fstat,	/* 28 = fstat	*/
	no_sys,		/* 29 = pause	*/
	do_utime,	/* 30 = utime	*/
	no_sys,		/* 31 = (stty)	*/
	no_sys,		/* 32 = (gtty)	*/
	do_access,	/* 33 = access	*/
	no_sys,		/* 34 = (nice)	*/
	no_sys,		/* 35 = (ftime)	*/
	do_sync,	/* 36 = sync	*/
	no_sys,		/* 37 = kill	*/
	do_rename,	/* 38 = rename	*/
	do_mkdir,	/* 39 = mkdir	*/
	do_unlink,	/* 40 = rmdir	*/
	do_dup,		/* 41 = dup	*/
	do_pipe,	/* 42 = pipe	*/
	no_sys,		/* 43 = times	*/
	no_sys,		/* 44 = (prof)	*/
	no_sys,		/* 45 = unused	*/
	do_set,		/* 46 = setgid	*/
	no_sys,		/* 47 = getgid	*/
	no_sys,		/* 48 = (signal)*/
	no_sys,		/* 49 = unused	*/
	no_sys,		/* 50 = unused	*/
	no_sys,		/* 51 = (acct)	*/
	no_sys,		/* 52 = (phys)	*/
	no_sys,		/* 53 = (lock)	*/
	do_ioctl,	/* 54 = ioctl	*/
	do_fcntl,	/* 55 = fcntl	*/
	no_sys,		/* 56 = (mpx)	*/
	no_sys,		/* 57 = unused	*/
	no_sys,		/* 58 = unused	*/
	do_exec,	/* 59 = execve	*/
	do_umask,	/* 60 = umask	*/
	do_chroot,	/* 61 = chroot	*/
	do_setsid,	/* 62 = setsid	*/
	no_sys,		/* 63 = getpgrp	*/

	no_sys,		/* 64 = KSIG: signals originating in the kernel	*/
	do_unpause,	/* 65 = UNPAUSE	*/
	no_sys, 	/* 66 = unused  */
	do_revive,	/* 67 = REVIVE	*/
	no_sys,		/* 68 = TASK_REPLY	*/
	no_sys,		/* 69 = unused */
	no_sys,		/* 70 = unused */
	no_sys,		/* 71 = si */
	no_sys,		/* 72 = sigsuspend */
	no_sys,		/* 73 = sigpending */
	no_sys,		/* 74 = sigprocmask */
	no_sys,		/* 75 = sigreturn */
	do_reboot,	/* 76 = reboot */
	do_svrctl,	/* 77 = svrctl */

	no_sys,		/* 78 = unused */
	do_getsysinfo,  /* 79 = getsysinfo */
	no_sys,		/* 80 = unused */
	do_devctl,	/* 81 = devctl */
	do_fstatfs,	/* 82 = fstatfs */
	no_sys,		/* 83 = memalloc */
	no_sys,		/* 84 = memfree */
	do_select,	/* 85 = select */
	do_fchdir,	/* 86 = fchdir */
	do_fsync,	/* 87 = fsync */
	no_sys,		/* 88 = getpriority */
	no_sys,		/* 89 = setpriority */
	no_sys,		/* 90 = gettimeofday */
};

The problem is that i fail to understand what the hell is the above {syntactically}...

any help will be appreciated,
-nicolas

PS:: the source code is copied from the file src/servers/fs/table.c {that can be downloaded from here so there is no typo!
PS2:: merry christmas to all!! :)

call_vec is a array of pointer to functions which pass void and return int.
PUBLIC _PROTOTYPE should be some typedef.

An addition to dubeyprateek's reply....
PUBLIC is a preprocessor defination and _PROTOTYPE is typedef.

can you elaborate a bit more, because i still can't quite get it....

call_vec is a array of pointer to functions which pass void and return int.

shouldn't then be written like this int (*call_vec[])(void) thank you both for your answers!

-nicolas

PUBLIC _PROTOTYPE indicates folowing routine is a System call handler. Systems-tasks are more like a hardware abstraction. The call_vec table is an array of function pointers that is indexed by the
system-call number. In each line, the address of a system-call handler function is
assigned to one entry in the table and the index of the entry is the system-call number.
We could call the system-handler function directly using the system call _syscall. _syscall
takes three parameters: the recipient process, system-call number, and pointer to a
message structure.
PUBLIC int _syscall(int who, int syscallnr, register message *msgptr);

since _PROTOTYPE is a preprocessor macro, it's defination looks like
#define _PROTOTYPE(function, params) function params
Hence, int (*call_vec[]), (void) gets resolved to int (*call_vec[])(void)

Comments
awsome!!

since _PROTOTYPE is a preprocessor macro, it's defination looks like
#define _PROTOTYPE(function, params) function params
Hence, int (*call_vec[]), (void) gets resolved to int (*call_vec[])(void)

you are right... the book mentions this trick when it talks about process implementation....

When compiling a C program the data types of the arguments and the returned values of functions must be known before code that references such data can be generated. In a complex system ordering of function definitions to meet this requirement is difficult, so C allows use of function prototypes to declare the arguments and return value types of a function before it is defined. The most important macro in ansi.h is _PROTOTYPE. This macro allows us to write function prototypes in the form

_PROTOTYPE (return-type function-name, (argument-type argument, ... ) )

and have this transformed by the C preprocessor into

return-type function-name(argument-type, argument, ...)

if the compiler is an ANSI Standard C compiler, or

return-type function-name()

if the compiler is an old-fashioned (i.e., Kernighan & Ritchie) compiler.

-nicolas

thank you all for your help!!

This question has already been answered. Start a new discussion instead.