diff --git a/drivers/syslog/ramlog.c b/drivers/syslog/ramlog.c index 7ca5358681..df65b4d414 100644 --- a/drivers/syslog/ramlog.c +++ b/drivers/syslog/ramlog.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -57,16 +58,16 @@ struct ramlog_dev_s { #ifndef CONFIG_RAMLOG_NONBLOCKING - volatile uint8_t rl_nwaiters; /* Number of threads waiting for data */ + volatile uint8_t rl_nwaiters; /* Number of threads waiting for data */ #endif - volatile uint16_t rl_head; /* The head index (where data is added) */ - volatile uint16_t rl_tail; /* The tail index (where data is removed) */ - sem_t rl_exclsem; /* Enforces mutually exclusive access */ + volatile size_t rl_head; /* The head index (where data is added) */ + volatile size_t rl_tail; /* The tail index (where data is removed) */ + sem_t rl_exclsem; /* Enforces mutually exclusive access */ #ifndef CONFIG_RAMLOG_NONBLOCKING - sem_t rl_waitsem; /* Used to wait for data */ + sem_t rl_waitsem; /* Used to wait for data */ #endif - size_t rl_bufsize; /* Size of the RAM buffer */ - FAR char *rl_buffer; /* Circular RAM buffer */ + size_t rl_bufsize; /* Size of the RAM buffer */ + FAR char *rl_buffer; /* Circular RAM buffer */ /* The following is a list if poll structures of threads waiting for * driver events. The 'struct pollfd' reference for each open is also @@ -95,6 +96,8 @@ static ssize_t ramlog_read(FAR struct file *filep, FAR char *buffer, size_t buflen); static ssize_t ramlog_write(FAR struct file *filep, FAR const char *buffer, size_t buflen); +static int ramlog_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); static int ramlog_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup); @@ -109,7 +112,7 @@ static const struct file_operations g_ramlogfops = ramlog_read, /* read */ ramlog_write, /* write */ NULL, /* seek */ - NULL, /* ioctl */ + ramlog_ioctl, /* ioctl */ ramlog_poll /* poll */ #ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS , NULL /* unlink */ @@ -534,11 +537,47 @@ static ssize_t ramlog_write(FAR struct file *filep, FAR const char *buffer, return len; } +/**************************************************************************** + * Name: ramlog_ioctl + ****************************************************************************/ + +static int ramlog_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct ramlog_dev_s *priv; + int ret; + + DEBUGASSERT(inode && inode->i_private); + priv = (FAR struct ramlog_dev_s *)inode->i_private; + + ret = nxsem_wait(&priv->rl_exclsem); + if (ret < 0) + { + return ret; + } + + switch (cmd) + { + case FIONREAD: + *(FAR int *)((uintptr_t)arg) = (priv->rl_bufsize + priv->rl_head - + priv->rl_tail) % priv->rl_bufsize; + break; + default: + ret = -ENOTTY; + break; + } + + nxsem_post(&priv->rl_exclsem); + + return ret; +} + /**************************************************************************** * Name: ramlog_poll ****************************************************************************/ -int ramlog_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup) +static int ramlog_poll(FAR struct file *filep, FAR struct pollfd *fds, + bool setup) { FAR struct inode *inode = filep->f_inode; FAR struct ramlog_dev_s *priv;