Changeset View
Changeset View
Standalone View
Standalone View
sys/compat/linuxkpi/common/src/linux_seq_file.c
Show All 39 Lines | |||||
#include <linux/file.h> | #include <linux/file.h> | ||||
#undef file | #undef file | ||||
MALLOC_DEFINE(M_LSEQ, "seq_file", "seq_file"); | MALLOC_DEFINE(M_LSEQ, "seq_file", "seq_file"); | ||||
ssize_t | ssize_t | ||||
seq_read(struct linux_file *f, char *ubuf, size_t size, off_t *ppos) | seq_read(struct linux_file *f, char *ubuf, size_t size, off_t *ppos) | ||||
{ | { | ||||
struct seq_file *m = f->private_data; | struct seq_file *m; | ||||
struct sbuf *sbuf; | |||||
void *p; | void *p; | ||||
int rc; | ssize_t rc; | ||||
off_t pos = 0; | |||||
p = m->op->start(m, &pos); | m = f->private_data; | ||||
sbuf = m->buf; | |||||
p = m->op->start(m, ppos); | |||||
markj: Is this a bug fix? | |||||
Done Inline ActionsYes. jfree: Yes. | |||||
rc = m->op->show(m, p); | rc = m->op->show(m, p); | ||||
if (rc) | if (rc) | ||||
return (rc); | return (rc); | ||||
return (size); | |||||
rc = sbuf_finish(sbuf); | |||||
if (rc) | |||||
return (rc); | |||||
rc = sbuf_len(sbuf); | |||||
if (*ppos >= rc || size < 1) | |||||
return (-EINVAL); | |||||
size = min(rc - *ppos, size); | |||||
rc = strscpy(ubuf, sbuf_data(sbuf) + *ppos, size); | |||||
/* add 1 for null terminator */ | |||||
if (rc > 0) | |||||
rc += 1; | |||||
return (rc); | |||||
} | } | ||||
int | int | ||||
seq_write(struct seq_file *seq, const void *data, size_t len) | seq_write(struct seq_file *seq, const void *data, size_t len) | ||||
{ | { | ||||
return (sbuf_bcpy(seq->buf, data, len)); | return (sbuf_bcpy(seq->buf, data, len)); | ||||
} | } | ||||
Show All 30 Lines | |||||
{ | { | ||||
} | } | ||||
int | int | ||||
seq_open(struct linux_file *f, const struct seq_operations *op) | seq_open(struct linux_file *f, const struct seq_operations *op) | ||||
{ | { | ||||
struct seq_file *p; | struct seq_file *p; | ||||
if (f->private_data != NULL) | |||||
log(LOG_WARNING, "%s private_data not NULL", __func__); | |||||
if ((p = malloc(sizeof(*p), M_LSEQ, M_NOWAIT|M_ZERO)) == NULL) | if ((p = malloc(sizeof(*p), M_LSEQ, M_NOWAIT|M_ZERO)) == NULL) | ||||
return (-ENOMEM); | return (-ENOMEM); | ||||
f->private_data = p; | p->buf = sbuf_new_auto(); | ||||
p->op = op; | |||||
p->file = f; | p->file = f; | ||||
p->op = op; | |||||
f->private_data = (void *) p; | |||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
single_open(struct linux_file *f, int (*show)(struct seq_file *, void *), void *d) | single_open(struct linux_file *f, int (*show)(struct seq_file *, void *), void *d) | ||||
{ | { | ||||
struct seq_operations *op; | struct seq_operations *op; | ||||
int rc = -ENOMEM; | int rc = -ENOMEM; | ||||
Show All 12 Lines | single_open(struct linux_file *f, int (*show)(struct seq_file *, void *), void *d) | ||||
} | } | ||||
return (rc); | return (rc); | ||||
} | } | ||||
int | int | ||||
seq_release(struct inode *inode __unused, struct linux_file *file) | seq_release(struct inode *inode __unused, struct linux_file *file) | ||||
{ | { | ||||
struct seq_file *m; | struct seq_file *m; | ||||
struct sbuf *s; | |||||
m = file->private_data; | m = file->private_data; | ||||
s = m->buf; | |||||
sbuf_delete(s); | |||||
free(m, M_LSEQ); | free(m, M_LSEQ); | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
single_release(struct vnode *v, struct linux_file *f) | single_release(struct vnode *v, struct linux_file *f) | ||||
{ | { | ||||
const struct seq_operations *op; | const struct seq_operations *op; | ||||
struct seq_file *m; | struct seq_file *m; | ||||
int rc; | int rc; | ||||
/* be NULL safe */ | /* be NULL safe */ | ||||
if ((m = f->private_data) == NULL) | if ((m = f->private_data) == NULL) | ||||
return (0); | return (0); | ||||
op = m->op; | op = m->op; | ||||
rc = seq_release(v, f); | rc = seq_release(v, f); | ||||
free(__DECONST(void *, op), M_LSEQ); | free(__DECONST(void *, op), M_LSEQ); | ||||
return (rc); | return (rc); | ||||
} | |||||
void | |||||
seq_vprintf(struct seq_file *m, const char *fmt, va_list args) | |||||
{ | |||||
sbuf_vprintf(m->buf, fmt, args); | |||||
} | |||||
void | |||||
seq_printf(struct seq_file *m, const char *fmt, ...) | |||||
{ | |||||
va_list args; | |||||
va_start(args, fmt); | |||||
seq_vprintf(m, fmt, args); | |||||
va_end(args); | |||||
} | } |
Is this a bug fix?