Implemented _{user|kern}_{read|write}v() functions.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9765 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2004-11-03 14:54:10 +00:00
parent 283c934877
commit 9d171dd8f9

View File

@ -319,8 +319,8 @@ _user_read(int fd, off_t pos, void *buffer, size_t length)
if (descriptor->ops->fd_read) {
bytesRead = descriptor->ops->fd_read(descriptor, pos, buffer, &length);
if (bytesRead >= B_OK) {
if (length > 0x7fffffff)
bytesRead = 0x7fffffff;
if (length > SSIZE_MAX)
bytesRead = SSIZE_MAX;
else
bytesRead = (ssize_t)length;
@ -334,6 +334,65 @@ _user_read(int fd, off_t pos, void *buffer, size_t length)
}
ssize_t
_user_readv(int fd, off_t pos, const iovec *userVecs, size_t count)
{
struct file_descriptor *descriptor;
ssize_t bytesRead = 0;
status_t status;
iovec *vecs;
uint32 i;
/* This is a user_function, so abort if we have a kernel address */
if (!IS_USER_ADDRESS(userVecs))
return B_BAD_ADDRESS;
vecs = malloc(sizeof(iovec) * count);
if (vecs == NULL)
return B_NO_MEMORY;
if (user_memcpy(vecs, userVecs, sizeof(iovec) * count) < B_OK) {
status = B_BAD_ADDRESS;
goto err;
}
descriptor = get_fd(get_current_io_context(false), fd);
if (!descriptor) {
status = B_FILE_ERROR;
goto err;
}
if (pos == -1)
pos = descriptor->pos;
if (descriptor->ops->fd_read) {
for (i = 0; i < count; i++) {
size_t length = vecs[i].iov_len;
status = descriptor->ops->fd_read(descriptor, pos, vecs[i].iov_base, &length);
if (status < B_OK) {
bytesRead = status;
break;
}
if ((uint32)bytesRead + length > SSIZE_MAX)
bytesRead = SSIZE_MAX;
else
bytesRead += (ssize_t)length;
descriptor->pos = pos + length;
}
} else
bytesRead = B_BAD_VALUE;
put_fd(descriptor);
return bytesRead;
err:
free(vecs);
return status;
}
ssize_t
_user_write(int fd, off_t pos, const void *buffer, size_t length)
{
@ -353,8 +412,8 @@ _user_write(int fd, off_t pos, const void *buffer, size_t length)
if (descriptor->ops->fd_write) {
bytesWritten = descriptor->ops->fd_write(descriptor, pos, buffer, &length);
if (bytesWritten >= B_OK) {
if (length > 0x7fffffff)
bytesWritten = 0x7fffffff;
if (length > SSIZE_MAX)
bytesWritten = SSIZE_MAX;
else
bytesWritten = (ssize_t)length;
@ -368,6 +427,65 @@ _user_write(int fd, off_t pos, const void *buffer, size_t length)
}
ssize_t
_user_writev(int fd, off_t pos, const iovec *userVecs, size_t count)
{
struct file_descriptor *descriptor;
ssize_t bytesWritten = 0;
status_t status;
iovec *vecs;
uint32 i;
/* This is a user_function, so abort if we have a kernel address */
if (!IS_USER_ADDRESS(userVecs))
return B_BAD_ADDRESS;
vecs = malloc(sizeof(iovec) * count);
if (vecs == NULL)
return B_NO_MEMORY;
if (user_memcpy(vecs, userVecs, sizeof(iovec) * count) < B_OK) {
status = B_BAD_ADDRESS;
goto err;
}
descriptor = get_fd(get_current_io_context(false), fd);
if (!descriptor) {
status = B_FILE_ERROR;
goto err;
}
if (pos == -1)
pos = descriptor->pos;
if (descriptor->ops->fd_write) {
for (i = 0; i < count; i++) {
size_t length = vecs[i].iov_len;
status = descriptor->ops->fd_write(descriptor, pos, vecs[i].iov_base, &length);
if (status < B_OK) {
bytesWritten = status;
break;
}
if ((uint32)bytesWritten + length > SSIZE_MAX)
bytesWritten = SSIZE_MAX;
else
bytesWritten += (ssize_t)length;
descriptor->pos = pos + length;
}
} else
bytesWritten = B_BAD_VALUE;
put_fd(descriptor);
return bytesWritten;
err:
free(vecs);
return status;
}
off_t
_user_seek(int fd, off_t pos, int seekType)
{
@ -516,8 +634,8 @@ _kern_read(int fd, off_t pos, void *buffer, size_t length)
if (descriptor->ops->fd_read) {
bytesRead = descriptor->ops->fd_read(descriptor, pos, buffer, &length);
if (bytesRead >= B_OK) {
if (length > 0x7fffffff)
bytesRead = 0x7fffffff;
if (length > SSIZE_MAX)
bytesRead = SSIZE_MAX;
else
bytesRead = (ssize_t)length;
@ -531,6 +649,45 @@ _kern_read(int fd, off_t pos, void *buffer, size_t length)
}
ssize_t
_kern_readv(int fd, off_t pos, const iovec *vecs, size_t count)
{
struct file_descriptor *descriptor;
ssize_t bytesRead = 0;
status_t status;
uint32 i;
descriptor = get_fd(get_current_io_context(false), fd);
if (!descriptor)
return B_FILE_ERROR;
if (pos == -1)
pos = descriptor->pos;
if (descriptor->ops->fd_read) {
for (i = 0; i < count; i++) {
size_t length = vecs[i].iov_len;
status = descriptor->ops->fd_read(descriptor, pos, vecs[i].iov_base, &length);
if (status < B_OK) {
bytesRead = status;
break;
}
if ((uint32)bytesRead + length > SSIZE_MAX)
bytesRead = SSIZE_MAX;
else
bytesRead += (ssize_t)length;
descriptor->pos = pos + length;
}
} else
bytesRead = B_BAD_VALUE;
put_fd(descriptor);
return bytesRead;
}
ssize_t
_kern_write(int fd, off_t pos, const void *buffer, size_t length)
{
@ -547,8 +704,8 @@ _kern_write(int fd, off_t pos, const void *buffer, size_t length)
if (descriptor->ops->fd_write) {
bytesWritten = descriptor->ops->fd_write(descriptor, pos, buffer, &length);
if (bytesWritten >= B_OK) {
if (length > 0x7fffffff)
bytesWritten = 0x7fffffff;
if (length > SSIZE_MAX)
bytesWritten = SSIZE_MAX;
else
bytesWritten = (ssize_t)length;
@ -562,6 +719,45 @@ _kern_write(int fd, off_t pos, const void *buffer, size_t length)
}
ssize_t
_kern_writev(int fd, off_t pos, const iovec *vecs, size_t count)
{
struct file_descriptor *descriptor;
ssize_t bytesWritten = 0;
status_t status;
uint32 i;
descriptor = get_fd(get_current_io_context(false), fd);
if (!descriptor)
return B_FILE_ERROR;
if (pos == -1)
pos = descriptor->pos;
if (descriptor->ops->fd_write) {
for (i = 0; i < count; i++) {
size_t length = vecs[i].iov_len;
status = descriptor->ops->fd_write(descriptor, pos, vecs[i].iov_base, &length);
if (status < B_OK) {
bytesWritten = status;
break;
}
if ((uint32)bytesWritten + length > SSIZE_MAX)
bytesWritten = SSIZE_MAX;
else
bytesWritten += (ssize_t)length;
descriptor->pos = pos + length;
}
} else
bytesWritten = B_BAD_VALUE;
put_fd(descriptor);
return bytesWritten;
}
off_t
_kern_seek(int fd, off_t pos, int seekType)
{