|
version 1.1, 2000/06/06 09:11:13
|
version 1.2, 2001/03/01 09:24:52
|
|
|
|
| MODULE_PARM(emlog_debug, "i"); | MODULE_PARM(emlog_debug, "i"); |
| | |
| struct emlog_info *emlog_info_list = NULL; | struct emlog_info *emlog_info_list = NULL; |
| static struct wait_queue *emlog_read_wait = NULL; |
|
| static int emlog_debug; | static int emlog_debug; |
| | |
| #define MIN(x, y) ((x) < (y) ? (x) : y) | #define MIN(x, y) ((x) < (y) ? (x) : y) |
|
|
|
| einfo->read_point = 0; | einfo->read_point = 0; |
| einfo->write_point = 0; | einfo->write_point = 0; |
| | |
| |
#if defined(DECLARE_WAIT_QUEUE_HEAD) |
| |
init_waitqueue_head(&einfo->read_q); |
| |
#else |
| |
init_waitqueue(&einfo->read_q); |
| |
#endif |
| |
|
| /* add it to our linked list */ | /* add it to our linked list */ |
| einfo->next = emlog_info_list; | einfo->next = emlog_info_list; |
| emlog_info_list = einfo; | emlog_info_list = einfo; |
|
|
|
| if (file->f_flags & O_NONBLOCK) | if (file->f_flags & O_NONBLOCK) |
| return -EAGAIN; | return -EAGAIN; |
| | |
| interruptible_sleep_on(&emlog_read_wait); |
interruptible_sleep_on(EMLOG_READQ(einfo)); |
| | |
| /* see if a signal woke us up */ | /* see if a signal woke us up */ |
| if (signal_pending(current)) | if (signal_pending(current)) |
|
|
|
| * reentrancy in emlog_read. */ | * reentrancy in emlog_read. */ |
| write_to_emlog(einfo, message, n); | write_to_emlog(einfo, message, n); |
| kfree(message); | kfree(message); |
| wake_up_interruptible(&emlog_read_wait); |
wake_up_interruptible(EMLOG_READQ(einfo)); |
| schedule(); /* hope that a reader wakes up! */ | schedule(); /* hope that a reader wakes up! */ |
| return n; | return n; |
| } | } |
| | |
| |
|
| |
static unsigned int emlog_poll(struct file *file, poll_table *wait) |
| |
{ |
| |
struct emlog_info *einfo; |
| |
|
| |
if ((einfo = get_einfo(file->f_dentry->d_inode)) == NULL) |
| |
return -EIO; |
| |
|
| |
poll_wait(file, EMLOG_READQ(einfo), wait); |
| |
|
| |
if (!EMLOG_EMPTY(einfo)) |
| |
return POLLIN | POLLRDNORM; |
| |
else |
| |
return 0; |
| |
} |
| |
|
| |
|
| static struct file_operations emlog_fops = { | static struct file_operations emlog_fops = { |
| NULL, /* lseek */ |
read : emlog_read, |
| emlog_read, /* read */ |
write : emlog_write, |
| emlog_write, /* write */ |
open : emlog_open, |
| NULL, /* readdir */ |
release: emlog_release, |
| NULL, /* poll */ |
poll : emlog_poll, |
| NULL, /* ioctl */ |
|
| NULL, /* mmap */ |
|
| emlog_open, /* open */ |
|
| NULL, /* flush */ |
|
| emlog_release, /* release */ |
|
| NULL, /* fsync */ |
|
| NULL /* fasync */ |
|
| }; | }; |
| | |
| | |
|
|
|
| free_einfo(emlog_info_list); | free_einfo(emlog_info_list); |
| } | } |
| | |
| |
|
| |
|