ckb-next  v0.2.8 at branch master
ckb-next driver for corsair devices
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
devnode.h File Reference
#include "includes.h"
#include "usb.h"
+ Include dependency graph for devnode.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define S_READDIR   (S_IRWXU | S_IRGRP | S_IROTH | S_IXGRP | S_IXOTH)
 
#define S_READ   (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR)
 
#define S_READWRITE   (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH)
 
#define S_CUSTOM   (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)
 
#define S_CUSTOM_R   (S_IRUSR | S_IWUSR | S_IRGRP)
 

Typedefs

typedef struct _readlines_ctxreadlines_ctx
 Custom readline is needed for FIFOs. fopen()/getline() will die if the data is sent in too fast. More...
 

Functions

void updateconnected ()
 Update the list of connected devices. More...
 
int mkdevpath (usbdevice *kb)
 Create a dev path for the keyboard at index. Returns 0 on success. More...
 
int rmdevpath (usbdevice *kb)
 Remove the dev path for the keyboard at index. Returns 0 on success. More...
 
int mknotifynode (usbdevice *kb, int notify)
 Creates a notification node for the specified keyboard. More...
 
int rmnotifynode (usbdevice *kb, int notify)
 Removes a notification node for the specified keyboard. More...
 
int mkfwnode (usbdevice *kb)
 Writes a keyboard's firmware version and poll rate to its device node. More...
 
void readlines_ctx_init (readlines_ctx *ctx)
 
void readlines_ctx_free (readlines_ctx ctx)
 
unsigned readlines (int fd, readlines_ctx ctx, const char **input)
 

Variables

const char *const devpath
 Device path base ("/dev/input/ckb" or "/var/run/ckb") More...
 
long gid
 Group ID for the control nodes. -1 to give read/write access to everybody. More...
 

Macro Definition Documentation

#define S_CUSTOM   (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)

Definition at line 17 of file devnode.h.

Referenced by _mkdevpath().

#define S_CUSTOM_R   (S_IRUSR | S_IWUSR | S_IRGRP)

Definition at line 18 of file devnode.h.

#define S_READ   (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR)

Definition at line 15 of file devnode.h.

Referenced by _mkdevpath().

#define S_READDIR   (S_IRWXU | S_IRGRP | S_IROTH | S_IXGRP | S_IXOTH)

Definition at line 14 of file devnode.h.

Referenced by _mkdevpath().

#define S_READWRITE   (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH)

Definition at line 16 of file devnode.h.

Referenced by _mkdevpath().

Typedef Documentation

typedef struct _readlines_ctx* readlines_ctx

Definition at line 39 of file devnode.h.

Function Documentation

int mkdevpath ( usbdevice kb)

Definition at line 268 of file devnode.c.

References _mkdevpath(), euid_guard_start, and euid_guard_stop.

Referenced by _setupusb(), and main().

268  {
270  int res = _mkdevpath(kb);
272  return res;
273 }
#define euid_guard_start
Definition: os.h:40
static int _mkdevpath(usbdevice *kb)
Definition: devnode.c:136
#define euid_guard_stop
Definition: os.h:41

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int mkfwnode ( usbdevice kb)

Definition at line 299 of file devnode.c.

References ckb_warn, devpath, usbdevice::fwversion, gid, INDEX_OF, keyboard, usbdevice::pollrate, and S_GID_READ.

Referenced by _mkdevpath(), and fwupdate().

299  {
300  int index = INDEX_OF(kb, keyboard);
301  char fwpath[strlen(devpath) + 12];
302  snprintf(fwpath, sizeof(fwpath), "%s%d/fwversion", devpath, index);
303  FILE* fwfile = fopen(fwpath, "w");
304  if(fwfile){
305  fprintf(fwfile, "%04x", kb->fwversion);
306  fputc('\n', fwfile);
307  fclose(fwfile);
308  chmod(fwpath, S_GID_READ);
309  if(gid >= 0)
310  chown(fwpath, 0, gid);
311  } else {
312  ckb_warn("Unable to create %s: %s\n", fwpath, strerror(errno));
313  remove(fwpath);
314  return -1;
315  }
316  char ppath[strlen(devpath) + 11];
317  snprintf(ppath, sizeof(ppath), "%s%d/pollrate", devpath, index);
318  FILE* pfile = fopen(ppath, "w");
319  if(pfile){
320  fprintf(pfile, "%d ms", kb->pollrate);
321  fputc('\n', pfile);
322  fclose(pfile);
323  chmod(ppath, S_GID_READ);
324  if(gid >= 0)
325  chown(ppath, 0, gid);
326  } else {
327  ckb_warn("Unable to create %s: %s\n", fwpath, strerror(errno));
328  remove(ppath);
329  return -2;
330  }
331  return 0;
332 }
ushort fwversion
Definition: structures.h:239
usbdevice keyboard[9]
remember all usb devices. Needed for closeusb().
Definition: device.c:10
long gid
Group ID for the control nodes. -1 to give read/write access to everybody.
Definition: devnode.c:16
#define ckb_warn(fmt, args...)
Definition: includes.h:52
const char *const devpath
Definition: devnode.c:11
#define INDEX_OF(entry, array)
Definition: includes.h:27
char pollrate
Definition: structures.h:241
#define S_GID_READ
Definition: devnode.c:17

+ Here is the caller graph for this function:

int mknotifynode ( usbdevice kb,
int  notify 
)

Definition at line 108 of file devnode.c.

References _mknotifynode(), euid_guard_start, and euid_guard_stop.

Referenced by readcmd().

108  {
110  int res = _mknotifynode(kb, notify);
112  return res;
113 }
#define euid_guard_start
Definition: os.h:40
int _mknotifynode(usbdevice *kb, int notify)
Definition: devnode.c:87
#define euid_guard_stop
Definition: os.h:41

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

unsigned readlines ( int  fd,
readlines_ctx  ctx,
const char **  input 
)

Definition at line 353 of file devnode.c.

References _readlines_ctx::buffer, _readlines_ctx::buffersize, ckb_warn, _readlines_ctx::leftover, _readlines_ctx::leftoverlen, and MAX_BUFFER.

Referenced by devmain().

353  {
354  // Move any data left over from a previous read to the start of the buffer
355  char* buffer = ctx->buffer;
356  int buffersize = ctx->buffersize;
357  int leftover = ctx->leftover, leftoverlen = ctx->leftoverlen;
358  memcpy(buffer, buffer + leftover, leftoverlen);
359  // Read data from the file
360  ssize_t length = read(fd, buffer + leftoverlen, buffersize - leftoverlen);
361  length = (length < 0 ? 0 : length) + leftoverlen;
362  leftover = ctx->leftover = leftoverlen = ctx->leftoverlen = 0;
363  if(length <= 0){
364  *input = 0;
365  return 0;
366  }
367  // Continue buffering until all available input is read or there's no room left
368  while(length == buffersize){
369  if(buffersize == MAX_BUFFER)
370  break;
371  int oldsize = buffersize;
372  buffersize += 4096;
373  ctx->buffersize = buffersize;
374  buffer = ctx->buffer = realloc(buffer, buffersize + 1);
375  ssize_t length2 = read(fd, buffer + oldsize, buffersize - oldsize);
376  if(length2 <= 0)
377  break;
378  length += length2;
379  }
380  buffer[length] = 0;
381  // Input should be issued one line at a time and should end with a newline.
382  char* lastline = memrchr(buffer, '\n', length);
383  if(lastline == buffer + length - 1){
384  // If the buffer ends in a newline, process the whole string
385  *input = buffer;
386  return length;
387  } else if(lastline){
388  // Otherwise, chop off the last line but process everything else
389  *lastline = 0;
390  leftover = ctx->leftover = lastline + 1 - buffer;
391  leftoverlen = ctx->leftoverlen = length - leftover;
392  *input = buffer;
393  return leftover - 1;
394  } else {
395  // If a newline wasn't found at all, process the whole buffer next time
396  *input = 0;
397  if(length == MAX_BUFFER){
398  // Unless the buffer is completely full, in which case discard it
399  ckb_warn("Too much input (1MB). Dropping.\n");
400  return 0;
401  }
402  leftoverlen = ctx->leftoverlen = length;
403  return 0;
404  }
405 }
int buffersize
Definition: devnode.c:337
char * buffer
Definition: devnode.c:336
#define ckb_warn(fmt, args...)
Definition: includes.h:52
int leftoverlen
Definition: devnode.c:338
#define MAX_BUFFER
Definition: devnode.c:334

+ Here is the caller graph for this function:

void readlines_ctx_free ( readlines_ctx  ctx)

Definition at line 348 of file devnode.c.

References _readlines_ctx::buffer.

Referenced by devmain().

348  {
349  free(ctx->buffer);
350  free(ctx);
351 }
char * buffer
Definition: devnode.c:336

+ Here is the caller graph for this function:

void readlines_ctx_init ( readlines_ctx ctx)

Definition at line 341 of file devnode.c.

Referenced by devmain().

341  {
342  // Allocate buffers to store data
343  *ctx = calloc(1, sizeof(struct _readlines_ctx));
344  int buffersize = (*ctx)->buffersize = 4095;
345  (*ctx)->buffer = malloc(buffersize + 1);
346 }

+ Here is the caller graph for this function:

int rmdevpath ( usbdevice kb)

Definition at line 275 of file devnode.c.

References _rmnotifynode(), ckb_info, ckb_warn, devpath, euid_guard_start, euid_guard_stop, INDEX_OF, usbdevice::infifo, keyboard, OUTFIFO_MAX, and rm_recursive().

Referenced by closeusb(), and quitWithLock().

275  {
277  int index = INDEX_OF(kb, keyboard);
278  if(kb->infifo != 0){
279 #ifdef OS_LINUX
280  write(kb->infifo - 1, "\n", 1); // hack to prevent the FIFO thread from perma-blocking
281 #endif
282  close(kb->infifo - 1);
283  kb->infifo = 0;
284  }
285  for(int i = 0; i < OUTFIFO_MAX; i++)
286  _rmnotifynode(kb, i);
287  char path[strlen(devpath) + 2];
288  snprintf(path, sizeof(path), "%s%d", devpath, index);
289  if(rm_recursive(path) != 0 && errno != ENOENT){
290  ckb_warn("Unable to delete %s: %s\n", path, strerror(errno));
292  return -1;
293  }
294  ckb_info("Removed device path %s\n", path);
296  return 0;
297 }
usbdevice keyboard[9]
remember all usb devices. Needed for closeusb().
Definition: device.c:10
int infifo
Definition: structures.h:225
#define ckb_warn(fmt, args...)
Definition: includes.h:52
const char *const devpath
Definition: devnode.c:11
#define ckb_info(fmt, args...)
Definition: includes.h:55
#define euid_guard_start
Definition: os.h:40
#define INDEX_OF(entry, array)
Definition: includes.h:27
int rm_recursive(const char *path)
Definition: devnode.c:19
#define euid_guard_stop
Definition: os.h:41
int _rmnotifynode(usbdevice *kb, int notify)
Definition: devnode.c:115
#define OUTFIFO_MAX
Definition: structures.h:24

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int rmnotifynode ( usbdevice kb,
int  notify 
)

Definition at line 129 of file devnode.c.

References _rmnotifynode(), euid_guard_start, and euid_guard_stop.

Referenced by readcmd().

129  {
131  int res = _rmnotifynode(kb, notify);
133  return res;
134 }
#define euid_guard_start
Definition: os.h:40
#define euid_guard_stop
Definition: os.h:41
int _rmnotifynode(usbdevice *kb, int notify)
Definition: devnode.c:115

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void updateconnected ( )

Definition at line 81 of file devnode.c.

References _updateconnected(), euid_guard_start, and euid_guard_stop.

Referenced by _setupusb(), and closeusb().

81  {
85 }
#define euid_guard_start
Definition: os.h:40
void _updateconnected()
_updateconnected Update the list of connected devices.
Definition: devnode.c:55
#define euid_guard_stop
Definition: os.h:41

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation

const char* const devpath

Definition at line 8 of file devnode.h.

Referenced by MainWindow::MainWindow().

long gid

Definition at line 16 of file devnode.c.

Referenced by _mkdevpath(), _mknotifynode(), _updateconnected(), main(), and mkfwnode().