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:
parent
62a16d13b7
commit
e28c39c4fb
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user