My new SYSCTL table for Linux AppleTalk
The original code in sysctl_net_atalk.c looked like
this:
ctl_table atalk_table[] =
{
{0} /* End of table */
};
I modified the code in this file to look like this:
int sysctl_ddp_reset = 0;
int proc_ddp_reset(ctl_table *ctl, int write, struct file *filp,
void *buffer, size_t *lenp);
ctl_table atalk_table[] =
{
{ /* Writable ddp_reset file (type: integer) */
1, "ddp_reset",
&sysctl_ddp_reset, sizeof(int),
0644, NULL, &proc_ddp_reset
},
{0} /* End of table */
};
The sysctl_ddp_reset variable is basically the
number you get from a read operation on that file. It is easiest to
declare a real integer variable and let the default handler routine
for integer nodes in /proc deal with the handling of
operations.
The actual procedure,
proc_ddp_reset was defined in ddp.c. It is
structured as follows:
int proc_ddp_reset(ctl_table *ctl, int write, struct file *filp,
void *buffer, size_t *lenp)
{
unsigned long flags;
int retv;
retv = proc_dointvec(ctl, write, filp, buffer, lenp);
if (write)
{
struct atalk_iface *iface;
extern int sysctl_ddp_reset;
sysctl_ddp_reset = 0;
save_flags(flags);
cli();
Do what you want here
restore_flags(flags);
}
return (retv);
}
The code first calls proc_dintvec() which services
read, write, seek, etc. It uses the value of
sysctl_ddp_reset() as the contents of the file.
If the operation was a write, we reset the value of the
sysctl_ddp_reset variable to zero (since it shouldn't
be changed by the user). We then get the old machine state
(save_flags) and disable interrupts (cli)
so we are atomic.
After doing our business, restore_flags restores the
machine state, including interrupt status for the routine as it
exits.
