uvt: ctx: add major/minor helpers

Two new functions to retrieve the current major number and dynamically
allocate minor numbers.
This can be used by clients that allocate more than one CDEV for VTs to
dynamically retrieve a new minor number.

Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
This commit is contained in:
David Herrmann 2013-03-05 01:29:10 +01:00
parent 62a16d13b7
commit e28c39c4fb
4 changed files with 56 additions and 0 deletions

View File

@ -30,6 +30,9 @@ global:
uvt_ctx_unref;
uvt_ctx_get_fd;
uvt_ctx_dispatch;
uvt_ctx_get_major;
uvt_ctx_new_minor;
uvt_ctx_free_minor;
uvt_cdev_new;
uvt_cdev_ref;

View File

@ -261,6 +261,10 @@ void uvt_ctx_unref(struct uvt_ctx *ctx);
int uvt_ctx_get_fd(struct uvt_ctx *ctx);
void uvt_ctx_dispatch(struct uvt_ctx *ctx);
unsigned int uvt_ctx_get_major(struct uvt_ctx *ctx);
int uvt_ctx_new_minor(struct uvt_ctx *ctx, unsigned int *out);
void uvt_ctx_free_minor(struct uvt_ctx *ctx, unsigned int minor);
/* pty tty implementation */
struct uvt_tty_null;

View File

@ -33,9 +33,12 @@
#include <eloop.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/major.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "shl_array.h"
#include "shl_flagset.h"
#include "shl_llog.h"
#include "shl_misc.h"
#include "uvt.h"
@ -60,6 +63,13 @@ int uvt_ctx_new(struct uvt_ctx **out, uvt_log_t log, void *log_data)
ctx->llog = log;
ctx->llog_data = log_data;
/* Default major/minor uses the TTY_MAJOR number with an offset of 2^15
* to avoid ID-clashes with any in-kernel TTY driver. As kernel drivers
* use static IDs only, a lower number would be fine, too, but lets be
* safe and just use high numbers. */
ctx->major = TTY_MAJOR;
ctx->minor_offset = 16384;
llog_debug(ctx, "new ctx %p", ctx);
ret = ev_eloop_new(&ctx->eloop, ctx->llog, ctx->llog_data);
@ -72,9 +82,15 @@ int uvt_ctx_new(struct uvt_ctx **out, uvt_log_t log, void *log_data)
goto err_eloop;
}
ret = shl_flagset_new(&ctx->minors);
if (ret)
goto err_file;
*out = ctx;
return 0;
err_file:
free(ctx->cuse_file);
err_eloop:
ev_eloop_unref(ctx->eloop);
err_free:
@ -99,6 +115,7 @@ void uvt_ctx_unref(struct uvt_ctx *ctx)
llog_debug(ctx, "free ctx %p", ctx);
shl_flagset_free(ctx->minors);
free(ctx->cuse_file);
ev_eloop_unref(ctx->eloop);
free(ctx);
@ -121,3 +138,31 @@ void uvt_ctx_dispatch(struct uvt_ctx *ctx)
ev_eloop_dispatch(ctx->eloop, 0);
}
SHL_EXPORT
unsigned int uvt_ctx_get_major(struct uvt_ctx *ctx)
{
return ctx->major;
}
SHL_EXPORT
int uvt_ctx_new_minor(struct uvt_ctx *ctx, unsigned int *out)
{
int ret;
ret = shl_flagset_alloc(ctx->minors, out);
if (ret)
return ret;
*out += ctx->minor_offset;
return 0;
}
SHL_EXPORT
void uvt_ctx_free_minor(struct uvt_ctx *ctx, unsigned int minor)
{
if (!ctx || minor < ctx->minor_offset)
return;
shl_flagset_unset(ctx->minors, minor - ctx->minor_offset);
}

View File

@ -34,6 +34,7 @@
#include <eloop.h>
#include <stdlib.h>
#include <uvt.h>
#include "shl_array.h"
#include "shl_dlist.h"
#include "shl_hook.h"
#include "shl_llog.h"
@ -53,6 +54,9 @@ struct uvt_ctx {
struct ev_eloop *eloop;
char *cuse_file;
unsigned int major;
unsigned int minor_offset;
struct shl_array *minors;
};
/* character devices */