/* * pat.c - an in-kernel representation of myself. * * Copyright (c) 2002 Patrick Mochel * Open Source Development Lab * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Compiled with CFLAGS = -Wall -O2 -fomit-frame-pointer -DMODULE -D__KERNEL__ IDIR = /home/mochel/src/kernel/devel/linux-2.5/include pat.o::pat.c $(CC) $(CFLAGS) -I$(IDIR) -c -o $@ $< */ #include #include #include #include #include #include struct simple_attribute { struct attribute attr; ssize_t (*show)(char * buf, size_t count, loff_t off); }; #define SIMPLE_ATTR(_name,_mode,_show) \ struct simple_attribute sattr_##_name = { \ .attr = {.name = __stringify(_name), .mode = _mode }, \ .show = _show, \ }; static char * who = "myself"; static char * what = "working"; static char * when = "not for long"; static char * where = "office"; static char * why = "catching up"; static char * how = "hungover"; static u32 dollars = 6; static u32 cents = 89; static char * beverage = "coffee"; static int bev_size = 12; static char * music = "Radiohead"; #define to_simple_attr(_attr) container_of(_attr,struct simple_attribute,attr) /* driverfs ops for displaying my attributes */ static int pat_attr_show(struct driver_dir_entry * dir, struct attribute * attr, char * buf, size_t count, loff_t off) { struct simple_attribute * sattr = to_simple_attr(attr); if (sattr->show) return sattr->show(buf,count,off); return 0; } static struct driverfs_ops pat_attr_ops = { .show pat_attr_show, }; static struct driver_dir_entry pat_dir = { .name = "pat", .mode = (S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO), .ops = &pat_attr_ops, }; /* exporting my attributes */ static ssize_t show_who(char * buf, size_t count, loff_t off) { return off ? 0 : snprintf(buf,50,"%s\n",who); } static SIMPLE_ATTR(who,0444,show_who); static ssize_t show_what(char * buf, size_t count, loff_t off) { return off ? 0 : snprintf(buf,50,"%s\n",what); } static SIMPLE_ATTR(what,0444,show_what); static ssize_t show_when(char * buf, size_t count, loff_t off) { return off ? 0 : snprintf(buf,50,"%s\n",when); } static SIMPLE_ATTR(when,0444,show_when); static ssize_t show_where(char * buf, size_t count, loff_t off) { return off ? 0 : snprintf(buf,50,"%s\n",where); } static SIMPLE_ATTR(where,0444,show_where); static ssize_t show_why(char * buf, size_t count, loff_t off) { return off ? 0 : snprintf(buf,50,"%s\n",why); } static SIMPLE_ATTR(why,0444,show_why); static ssize_t show_how(char * buf, size_t count, loff_t off) { return off ? 0 : snprintf(buf,50,"%s\n",how); } static SIMPLE_ATTR(how,0444,show_how); static ssize_t show_cash(char * buf, size_t count, loff_t off) { return off ? 0 : snprintf(buf,50,"%u.%u\n",dollars,cents); } static SIMPLE_ATTR(cash,0444,show_cash); static ssize_t show_beverage(char * buf, size_t count, loff_t off) { return off ? 0 : snprintf(buf,50,"%s\n",beverage); } static SIMPLE_ATTR(beverage,0444,show_beverage); static ssize_t show_bev_size(char * buf, size_t count, loff_t off) { return off ? 0 : snprintf(buf,50,"%u\n",bev_size); } static SIMPLE_ATTR(bev_size,0444,show_bev_size); static ssize_t show_music(char * buf, size_t count, loff_t off) { return off ? 0 : snprintf(buf,50,"%s\n",music); } static SIMPLE_ATTR(music,0444,show_music); static struct simple_attribute * pat_attrs[] = { &sattr_who, &sattr_what, &sattr_when, &sattr_where, &sattr_why, &sattr_how, &sattr_cash, &sattr_beverage, &sattr_bev_size, &sattr_music, NULL, }; static int populate_dir(void) { struct simple_attribute * attr; int i; int error = 0; for (i = 0; (attr = pat_attrs[i]); i++) { if ((error = driverfs_create_file(&attr->attr,&pat_dir))) break; } return error; } static int __init pat_init(void) { driverfs_create_dir(&pat_dir,NULL); return populate_dir(); } static void __exit pat_exit(void) { driverfs_remove_dir(&pat_dir); } subsys_initcall(pat_init); module_exit(pat_exit);