Make it (mostly) compile with -Weverything.

Also:
- add support for block devices.
- fix various memory leaks.
This commit is contained in:
Jakub Klama 2016-01-31 20:50:18 +01:00
parent 10aaea4971
commit 26f87be168
15 changed files with 297 additions and 98 deletions

View file

@ -1,5 +1,11 @@
CFLAGS := -Wall -Wextra -Werror -g -O0
BUILD_DIR := build
CFLAGS := \
-Weverything \
-Wno-padded \
-Wno-gnu-zero-variadic-macro-arguments \
-Wno-format-nonliteral \
-Werror \
-g \
-O0
LIB_SRCS := \
pack.c \
@ -15,6 +21,7 @@ LIB_SRCS := \
SERVER_SRCS := \
example/server.c
BUILD_DIR := build
LIB_OBJS := $(addprefix build/,$(LIB_SRCS:.c=.o))
SERVER_OBJS := $(SERVER_SRCS:.c=.o)
LIB := lib9p.dylib

View file

@ -119,10 +119,12 @@ dostat(struct l9p_stat *s, char *name, struct stat *buf, bool unix)
if (S_ISLNK(buf->st_mode) && unix)
s->mode |= L9P_DMSYMLINK;
s->atime = buf->st_atime;
s->mtime = buf->st_mtime;
s->length = buf->st_size;
s->name = name;
s->atime = (uint32_t)buf->st_atime;
s->mtime = (uint32_t)buf->st_mtime;
s->length = (uint64_t)buf->st_size;
/* XXX: not thread safe */
s->name = strdup(basename(name));
if (!unix) {
user = getpwuid(buf->st_uid);
@ -148,7 +150,12 @@ dostat(struct l9p_stat *s, char *name, struct stat *buf, bool unix)
return;
}
s->extension = strndup(target, ret);
s->extension = strndup(target, (size_t)ret);
}
if (S_ISBLK(buf->st_mode)) {
asprintf(&s->extension, "b %d %d", major(buf->st_rdev),
minor(buf->st_rdev));
}
}
}
@ -159,8 +166,14 @@ generate_qid(struct stat *buf, struct l9p_qid *qid)
qid->path = buf->st_ino;
qid->version = 0;
if (S_ISREG(buf->st_mode))
qid->type |= L9P_QTFILE;
if (S_ISDIR(buf->st_mode))
qid->type |= L9P_QTDIR;
if (S_ISLNK(buf->st_mode))
qid->type |= L9P_QTSYMLINK;
}
static bool
@ -197,7 +210,7 @@ check_access(struct stat *st, uid_t uid, int amode)
/* Check for group access */
pwd = getpwuid(uid);
getgrouplist(pwd->pw_name, pwd->pw_gid, groups, &ngroups);
getgrouplist(pwd->pw_name, (int)pwd->pw_gid, groups, &ngroups);
for (i = 0; i < ngroups; i++) {
if (st->st_gid == (gid_t)groups[i]) {
@ -253,9 +266,10 @@ fs_clunk(void *softc __unused, struct l9p_request *req)
file = req->lr_fid->lo_aux;
assert(file != NULL);
if (file->dir)
if (file->dir) {
closedir(file->dir);
else {
file->dir = NULL;
} else if (file->fd != -1) {
close(file->fd);
file->fd = -1;
}
@ -270,6 +284,7 @@ fs_create(void *softc, struct l9p_request *req)
struct openfile *file = req->lr_fid->lo_aux;
struct stat st;
char *newname;
mode_t mode = req->lr_req.tcreate.mode & 0777;
assert(file != NULL);
@ -291,12 +306,43 @@ fs_create(void *softc, struct l9p_request *req)
}
if (req->lr_req.tcreate.perm & L9P_DMDIR)
mkdir(newname, 0777);
mkdir(newname, mode);
else if (req->lr_req.tcreate.perm & L9P_DMSYMLINK)
symlink(req->lr_req.tcreate.extension, newname);
else {
else if (req->lr_req.tcreate.perm & L9P_DMDEVICE) {
char type;
int major, minor;
if (sscanf(req->lr_req.tcreate.extension, "%c %u %u",
&type, &major, &minor) < 2) {
l9p_respond(req, EINVAL);
return;
}
switch (type) {
case 'b':
if (mknod(newname, S_IFBLK | mode,
makedev(major, minor)) != 0)
{
l9p_respond(req, errno);
return;
}
break;
case 'c':
if (mknod(newname, S_IFCHR | mode,
makedev(major, minor)) != 0)
{
l9p_respond(req, errno);
return;
}
break;
default:
l9p_respond(req, EINVAL);
return;
}
} else {
file->fd = open(newname,
O_CREAT | O_TRUNC | req->lr_req.tcreate.mode,
O_CREAT | O_TRUNC | mode,
req->lr_req.tcreate.perm);
}
@ -312,6 +358,7 @@ static void
fs_flush(void *softc __unused, struct l9p_request *req)
{
/* XXX: not used because this transport is synchronous */
l9p_respond(req, 0);
}
@ -354,6 +401,7 @@ fs_read(void *softc __unused, struct l9p_request *req)
struct openfile *file;
struct l9p_stat l9stat;
bool unix = req->lr_conn->lc_version >= L9P_2000U;
ssize_t ret;
file = req->lr_fid->lo_aux;
assert(file != NULL);
@ -380,7 +428,27 @@ fs_read(void *softc __unused, struct l9p_request *req)
} else {
size_t niov = l9p_truncate_iov(req->lr_data_iov,
req->lr_data_niov, req->lr_req.io.count);
req->lr_resp.io.count = readv(file->fd, req->lr_data_iov, niov);
#if defined(__FreeBSD__)
ret = preadv(file->fd, req->lr_data_iov, niov,
req->lr_req.io.offset);
#else
/* XXX: not thread safe, should really use aio_listio. */
if (lseek(file->fd, (off_t)req->lr_req.io.offset, SEEK_SET) < 0)
{
l9p_respond(req, errno);
return;
}
ret = (uint32_t)readv(file->fd, req->lr_data_iov, (int)niov);
#endif
if (ret < 0) {
l9p_respond(req, errno);
return;
}
req->lr_resp.io.count = (uint32_t)ret;
}
l9p_respond(req, 0);
@ -438,7 +506,7 @@ fs_stat(void *softc __unused, struct l9p_request *req)
static void
fs_walk(void *softc __unused, struct l9p_request *req)
{
int i;
uint16_t i;
struct stat buf;
struct openfile *file = req->lr_fid->lo_aux;
struct openfile *newfile;
@ -446,7 +514,6 @@ fs_walk(void *softc __unused, struct l9p_request *req)
strcpy(name, file->name);
/* build full path. Stat full path. Done */
for (i = 0; i < req->lr_req.twalk.nwname; i++) {
strcat(name, "/");
strcat(name, req->lr_req.twalk.wname[i]);
@ -470,6 +537,7 @@ fs_write(void *softc, struct l9p_request *req)
{
struct fs_softc *sc = softc;
struct openfile *file;
ssize_t ret;
file = req->lr_fid->lo_aux;
assert(file != NULL);
@ -482,7 +550,26 @@ fs_write(void *softc, struct l9p_request *req)
size_t niov = l9p_truncate_iov(req->lr_data_iov,
req->lr_data_niov, req->lr_req.io.count);
req->lr_resp.io.count = writev(file->fd, req->lr_data_iov, niov);
#if defined(__FreeBSD__)
ret = pwritev(file->fd, req->lr_data_iov, niov,
req->lr_req.io.offset);
#else
/* XXX: not thread safe, should really use aio_listio. */
if (lseek(file->fd, (off_t)req->lr_req.io.offset, SEEK_SET) < 0) {
l9p_respond(req, errno);
return;
}
ret = writev(file->fd, req->lr_data_iov,
(int)niov);
#endif
if (ret < 0) {
l9p_respond(req, errno);
return;
}
req->lr_resp.io.count = (uint32_t)ret;
l9p_respond(req, 0);
}
@ -492,17 +579,33 @@ fs_wstat(void *softc, struct l9p_request *req)
struct fs_softc *sc = softc;
struct openfile *file;
struct l9p_stat *l9stat = &req->lr_req.twstat.stat;
file = req->lr_fid->lo_aux;
assert(file != NULL);
/*
* XXX:
*
* stat(9P) sez:
*
* Either all the changes in wstat request happen, or none of them
* does: if the request succeeds, all changes were made; if it fails,
* none were.
*
* Atomicity is clearly missing in current implementation.
*/
if (sc->fs_readonly) {
l9p_respond(req, EROFS);
return;
}
if (l9stat->atime != (uint32_t)~0) {
/* XXX: not implemented, ignore */
}
if (l9stat->mtime != (uint32_t)~0) {
/* XXX: not implemented, ignore */
}
if (l9stat->dev != (uint32_t)~0) {
@ -511,18 +614,38 @@ fs_wstat(void *softc, struct l9p_request *req)
}
if (l9stat->length != (uint64_t)~0) {
if (file->dir != NULL) {
l9p_respond(req, EINVAL);
return;
}
if (truncate(file->name, (off_t)l9stat->length) != 0) {
l9p_respond(req, errno);
return;
}
}
if (l9stat->n_uid != (uid_t)~0) {
/* XXX: not implemented */
l9p_respond(req, ENOSYS);
return;
}
if (l9stat->n_gid != (uid_t)~0) {
/* XXX: not implemented */
l9p_respond(req, ENOSYS);
return;
}
if (l9stat->mode != (uint32_t)~0) {
if (chmod(file->name, l9stat->mode & 0777) != 0) {
l9p_respond(req, errno);
return;
}
}
if (strlen(l9stat->name) > 0) {
/* XXX: not thread safe */
char *dir = dirname(file->name);
char *newname;
@ -536,9 +659,23 @@ fs_wstat(void *softc, struct l9p_request *req)
}
static void
fs_freefid(void *softc __unused, struct l9p_openfile *f __unused)
fs_freefid(void *softc __unused, struct l9p_openfile *fid)
{
struct openfile *f = fid->lo_aux;
if (f == NULL) {
/* Nothing to do here */
return;
}
if (f->fd != -1)
close(f->fd);
if (f->dir)
closedir(f->dir);
free(f->name);
free(f);
}
int

View file

@ -1,31 +0,0 @@
/*
* Copyright 2016 Jakub Klama <jceel@FreeBSD.org>
* All rights reserved
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted providing that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "../lib9p.h"
int l9p_backend_fs_init(struct l9p_backend **, const char *);

View file

@ -166,3 +166,13 @@ l9p_connection_alloc_fid(struct l9p_connection *conn, uint32_t fid)
return (file);
}
void
l9p_connection_remove_fid(struct l9p_connection *conn, struct l9p_openfile *fid)
{
conn->lc_server->ls_backend->freefid(conn->lc_server->ls_backend->softc,
fid);
ht_remove(&conn->lc_files, fid->lo_fid);
}

View file

@ -78,8 +78,8 @@ enum l9p_qid_type {
L9P_QTFILE = 0x00 /* type bits for plain file */
};
#define L9P_DMDIR 0x80000000
enum {
L9P_DMDIR = 0x80000000,
L9P_DMAPPEND = 0x40000000,
L9P_DMEXCL = 0x20000000,
L9P_DMMOUNT = 0x10000000,

View file

@ -110,7 +110,7 @@ ht_remove(struct ht *h, uint32_t hash)
{
struct ht_entry *entry;
struct ht_item *item, *tmp;
int slot = hash % h->ht_nentries;
size_t slot = hash % h->ht_nentries;
entry = &h->ht_entries[slot];

View file

@ -165,15 +165,22 @@ void l9p_connection_recv(struct l9p_connection *conn, const struct iovec *iov,
void l9p_connection_close(struct l9p_connection *conn);
struct l9p_openfile *l9p_connection_alloc_fid(struct l9p_connection *conn,
uint32_t fid);
void l9p_connection_remove_fid(struct l9p_connection *conn,
struct l9p_openfile *fid);
void l9p_dispatch_request(struct l9p_request *req);
void l9p_respond(struct l9p_request *req, int errnum);
void l9p_seek_iov(struct iovec *iov1, size_t niov1, struct iovec *iov2,
size_t *niov2, size_t seek);
int l9p_truncate_iov(struct iovec *iov, size_t niov, size_t length);
size_t l9p_truncate_iov(struct iovec *iov, size_t niov, size_t length);
void l9p_describe_qid(struct l9p_qid *qid, struct sbuf *sb);
void l9p_describe_fcall(union l9p_fcall *fcall, enum l9p_version version,
struct sbuf *sb);
void l9p_describe_stat(struct l9p_stat *st, struct sbuf *sb);
void l9p_freefcall(union l9p_fcall *fcall);
void l9p_freestat(struct l9p_stat *stat);
int l9p_backend_fs_init(struct l9p_backend **backendp, const char *root);
#endif /* LIB9P_LIB9P_H */

View file

@ -59,6 +59,20 @@ l9p_calloc(size_t n, size_t size)
return (r);
}
static inline void *
l9p_realloc(void *ptr, size_t newsize)
{
void *r = realloc(ptr, newsize);
if (r == NULL) {
fprintf(stderr, "cannot allocate %zd bytes: out of memory\n",
newsize);
abort();
}
return (r);
}
#endif /* _KERNEL */
#endif /* LIB9P_LIB9P_IMPL_H */

1
log.h
View file

@ -38,6 +38,7 @@ enum l9p_log_level
void l9p_logf(enum l9p_log_level level, const char *func, const char *fmt, ...);
#define L9P_DEBUG 1
#if defined(L9P_DEBUG)
#define L9P_LOG(level, fmt, ...) l9p_logf(level, __func__, fmt, ##__VA_ARGS__)
#else

66
pack.c
View file

@ -39,7 +39,7 @@
#include "lib9p_impl.h"
#define N(ary) (sizeof(ary) / sizeof(*ary))
#define STRING_SIZE(s) (L9P_WORD + (s != NULL ? strlen(s) : 0))
#define STRING_SIZE(s) (L9P_WORD + (s != NULL ? (uint16_t)strlen(s) : 0))
#define QID_SIZE (L9P_BYTE + L9P_DWORD + L9P_QWORD)
static int l9p_iov_io(struct l9p_message *, void *, size_t);
@ -73,13 +73,17 @@ l9p_iov_io(struct l9p_message *msg, void *buffer, size_t len)
size_t space = msg->lm_iov[idx].iov_len - msg->lm_cursor_offset;
size_t towrite = MIN(space, left);
if (msg->lm_mode == L9P_PACK)
memcpy(msg->lm_iov[idx].iov_base + msg->lm_cursor_offset,
buffer + done, towrite);
if (msg->lm_mode == L9P_PACK) {
memcpy((char *)msg->lm_iov[idx].iov_base +
msg->lm_cursor_offset, (char *)buffer + done,
towrite);
}
if (msg->lm_mode == L9P_UNPACK)
memcpy(buffer + done, msg->lm_iov[idx].iov_base +
msg->lm_cursor_offset, towrite);
if (msg->lm_mode == L9P_UNPACK) {
memcpy((char *)buffer + done,
(char *)msg->lm_iov[idx].iov_base +
msg->lm_cursor_offset, towrite);
}
msg->lm_cursor_offset += towrite;
@ -97,7 +101,7 @@ l9p_iov_io(struct l9p_message *msg, void *buffer, size_t len)
}
msg->lm_size += done;
return (done);
return ((int)done);
}
static inline int
@ -134,7 +138,7 @@ l9p_pustring(struct l9p_message *msg, char **s)
uint16_t len;
if (msg->lm_mode == L9P_PACK)
len = *s != NULL ? strlen(*s) : 0;
len = *s != NULL ? (uint16_t)strlen(*s) : 0;
if (l9p_pu16(msg, &len) < 0)
return (-1);
@ -364,7 +368,7 @@ l9p_pufcall(struct l9p_message *msg, union l9p_fcall *fcall,
if (msg->lm_mode == L9P_PACK) {
/* Rewind to the beginning */
uint32_t len = msg->lm_size;
uint32_t len = (uint32_t)msg->lm_size;
msg->lm_cursor_offset = 0;
msg->lm_cursor_iov = 0;
@ -384,6 +388,48 @@ l9p_pufcall(struct l9p_message *msg, union l9p_fcall *fcall,
return (0);
}
void
l9p_freefcall(union l9p_fcall *fcall)
{
uint16_t i;
switch (fcall->hdr.type) {
case L9P_TVERSION:
case L9P_RVERSION:
free(fcall->version.version);
return;
case L9P_TATTACH:
free(fcall->tattach.aname);
free(fcall->tattach.uname);
return;
case L9P_TWALK:
for (i = 0; i < fcall->twalk.nwname; i++)
free(fcall->twalk.wname[i]);
return;
case L9P_TCREATE:
case L9P_TOPEN:
free(fcall->tcreate.name);
free(fcall->tcreate.extension);
return;
case L9P_RSTAT:
l9p_freestat(&fcall->rstat.stat);
return;
case L9P_TWSTAT:
l9p_freestat(&fcall->twstat.stat);
return;
}
}
void
l9p_freestat(struct l9p_stat *stat)
{
free(stat->name);
free(stat->extension);
free(stat->uid);
free(stat->gid);
free(stat->muid);
}
uint16_t
l9p_sizeof_stat(struct l9p_stat *stat, enum l9p_version version)
{

View file

@ -117,13 +117,13 @@ l9p_respond(struct l9p_request *req, int errnum)
case L9P_TCLUNK:
case L9P_TREMOVE:
if (req->lr_fid != NULL)
ht_remove(&conn->lc_files, req->lr_fid->lo_fid);
l9p_connection_remove_fid(conn, req->lr_fid);
break;
case L9P_TWALK:
if (errnum != 0 && req->lr_newfid != NULL &&
req->lr_newfid != req->lr_fid)
ht_remove(&conn->lc_files, req->lr_newfid->lo_fid);
l9p_connection_remove_fid(conn, req->lr_newfid);
break;
}
@ -135,7 +135,7 @@ l9p_respond(struct l9p_request *req, int errnum)
else {
req->lr_resp.hdr.type = L9P_RERROR;
req->lr_resp.error.ename = strerror(errnum);
req->lr_resp.error.errnum = errnum;
req->lr_resp.error.errnum = (uint32_t)errnum;
}
l9p_describe_fcall(&req->lr_resp, L9P_2000, sb);
@ -159,6 +159,8 @@ l9p_respond(struct l9p_request *req, int errnum)
req->lr_resp_msg.lm_niov, iosize, conn->lc_send_response_aux);
out:
l9p_freefcall(&req->lr_req);
l9p_freefcall(&req->lr_resp);
free(req);
}
@ -177,13 +179,18 @@ l9p_pack_stat(struct l9p_request *req, struct l9p_stat *st)
sizeof (struct iovec) * req->lr_data_niov);
}
if (req->lr_resp.io.count + size > req->lr_req.io.count)
if (req->lr_resp.io.count + size > req->lr_req.io.count) {
l9p_freestat(st);
return (-1);
}
if (l9p_pustat(msg, st, conn->lc_version) < 0)
if (l9p_pustat(msg, st, conn->lc_version) < 0) {
l9p_freestat(st);
return (-1);
}
req->lr_resp.io.count += size;
l9p_freestat(st);
return (0);
}

View file

@ -68,7 +68,7 @@ int
sbuf_vprintf(struct sbuf *s, const char *fmt, va_list args)
{
va_list copy;
size_t req;
int req;
va_copy(copy, args);
req = vsnprintf(NULL, 0, fmt, copy);
@ -76,7 +76,7 @@ sbuf_vprintf(struct sbuf *s, const char *fmt, va_list args)
if (s->s_size + req >= s->s_capacity) {
s->s_capacity = s->s_size + req + 1;
s->s_buf = realloc(s->s_buf, s->s_capacity);
s->s_buf = realloc(s->s_buf, (size_t)s->s_capacity);
}
req = vsnprintf(s->s_buf + s->s_size, req + 1, fmt, args);
@ -103,4 +103,4 @@ sbuf_delete(struct sbuf *s)
{
free(s->s_buf);
free(s);
}
}

View file

@ -37,12 +37,12 @@
struct sbuf
{
char *s_buf;
size_t s_size;
size_t s_capacity;
size_t s_position;
int s_size;
int s_capacity;
int s_position;
};
struct sbuf *sbuf_new_auto();
struct sbuf *sbuf_new_auto(void);
int sbuf_printf(struct sbuf *s, const char *fmt, ...);
int sbuf_vprintf(struct sbuf *s, const char *fmt, va_list args);
int sbuf_done(struct sbuf *s);

View file

@ -56,8 +56,8 @@ static int l9p_socket_get_response_buffer(struct l9p_request *,
static int l9p_socket_send_response(struct l9p_request *, const struct iovec *,
const size_t, const size_t, void *);
static void *l9p_socket_thread(void *);
static int xread(int, void *, size_t);
static int xwrite(int, void *, size_t);
static ssize_t xread(int, void *, size_t);
static ssize_t xwrite(int, void *, size_t);
int
l9p_start_server(struct l9p_server *server, const char *host, const char *port)
@ -117,7 +117,7 @@ l9p_start_server(struct l9p_server *server, const char *host, const char *port)
for (i = 0; i < evs; i++) {
struct sockaddr client_addr;
socklen_t client_addr_len;
int news = accept(event[i].ident, &client_addr,
int news = accept((int)event[i].ident, &client_addr,
&client_addr_len);
if (news < 0) {
@ -193,7 +193,7 @@ static int
l9p_socket_readmsg(struct l9p_socket_softc *sc, void **buf, size_t *size)
{
uint32_t msize;
int toread;
size_t toread;
void *buffer;
int fd = sc->ls_fd;
@ -210,7 +210,7 @@ l9p_socket_readmsg(struct l9p_socket_softc *sc, void **buf, size_t *size)
toread = msize - sizeof(uint32_t);
buffer = realloc(buffer, msize);
if (xread(fd, buffer + sizeof(uint32_t), toread) != toread) {
if (xread(fd, (char *)buffer + sizeof(uint32_t), toread) != (ssize_t)toread) {
L9P_LOG(L9P_ERROR, "short read: %s", strerror(errno));
return (-1);
}
@ -255,17 +255,18 @@ l9p_socket_send_response(struct l9p_request *req __unused,
return (-1);
}
free(iov[0].iov_base);
return (0);
}
static int
static ssize_t
xread(int fd, void *buf, size_t count)
{
size_t done = 0;
int ret;
ssize_t ret;
while (done < count) {
ret = read(fd, buf + done, count - done);
ret = read(fd, (char *)buf + done, count - done);
if (ret < 0) {
if (errno == EINTR)
continue;
@ -274,22 +275,22 @@ xread(int fd, void *buf, size_t count)
}
if (ret == 0)
return (done);
return ((ssize_t)done);
done += ret;
done += (size_t)ret;
}
return (done);
return ((ssize_t)done);
}
static int
static ssize_t
xwrite(int fd, void *buf, size_t count)
{
size_t done = 0;
int ret;
ssize_t ret;
while (done < count) {
ret = write(fd, buf + done, count - done);
ret = write(fd, (char *)buf + done, count - done);
if (ret < 0) {
if (errno == EINTR)
continue;
@ -298,10 +299,10 @@ xwrite(int fd, void *buf, size_t count)
}
if (ret == 0)
return (done);
return ((ssize_t)done);
done += ret;
done += (size_t)ret;
}
return (done);
return ((ssize_t)done);
}

View file

@ -91,7 +91,7 @@ l9p_seek_iov(struct iovec *iov1, size_t niov1, struct iovec *iov2,
}
for (j = i; j < niov1; j++) {
iov2[j - i].iov_base = iov1[j].iov_base + remainder;
iov2[j - i].iov_base = (char *)iov1[j].iov_base + remainder;
iov2[j - i].iov_len = iov1[j].iov_len - remainder;
remainder = 0;
}
@ -99,7 +99,7 @@ l9p_seek_iov(struct iovec *iov1, size_t niov1, struct iovec *iov2,
*niov2 = j - i;
}
int
size_t
l9p_truncate_iov(struct iovec *iov, size_t niov, size_t length)
{
size_t i, done = 0;