mirror of
https://github.com/RGBCube/serenity
synced 2025-07-23 08:17:34 +00:00
Kernel: Make writev() work again
Vector::ensure_capacity() makes sure the underlying vector buffer can contain all the data, but it doesn't update the Vector::size(). As a result, writev() would simply collect all the buffers to write, and then do nothing.
This commit is contained in:
parent
b93f6b07c2
commit
b011857e4f
2 changed files with 35 additions and 1 deletions
|
@ -1539,7 +1539,7 @@ ssize_t Process::sys$writev(int fd, const struct iovec* iov, int iov_count)
|
||||||
|
|
||||||
u64 total_length = 0;
|
u64 total_length = 0;
|
||||||
Vector<iovec, 32> vecs;
|
Vector<iovec, 32> vecs;
|
||||||
vecs.ensure_capacity(iov_count);
|
vecs.resize(iov_count);
|
||||||
copy_from_user(vecs.data(), iov, iov_count * sizeof(iovec));
|
copy_from_user(vecs.data(), iov, iov_count * sizeof(iovec));
|
||||||
for (auto& vec : vecs) {
|
for (auto& vec : vecs) {
|
||||||
if (!validate_read(vec.iov_base, vec.iov_len))
|
if (!validate_read(vec.iov_base, vec.iov_len))
|
||||||
|
|
|
@ -28,8 +28,10 @@
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#define EXPECT_ERROR_2(err, syscall, arg1, arg2) \
|
#define EXPECT_ERROR_2(err, syscall, arg1, arg2) \
|
||||||
|
@ -255,6 +257,37 @@ void test_rmdir_while_inside_dir()
|
||||||
ASSERT(rc == 0);
|
ASSERT(rc == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_writev()
|
||||||
|
{
|
||||||
|
int pipefds[2];
|
||||||
|
pipe(pipefds);
|
||||||
|
|
||||||
|
iovec iov[2];
|
||||||
|
iov[0].iov_base = const_cast<void*>((const void*)"Hello");
|
||||||
|
iov[0].iov_len = 5;
|
||||||
|
iov[1].iov_base = const_cast<void*>((const void*)"Friends");
|
||||||
|
iov[1].iov_len = 7;
|
||||||
|
int nwritten = writev(pipefds[1], iov, 2);
|
||||||
|
if (nwritten < 0) {
|
||||||
|
perror("writev");
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
if (nwritten != 12) {
|
||||||
|
fprintf(stderr, "Didn't write 12 bytes to pipe with writev\n");
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
char buffer[32];
|
||||||
|
int nread = read(pipefds[0], buffer, sizeof(buffer));
|
||||||
|
if (nread != 12 || memcmp(buffer, "HelloFriends", 12)) {
|
||||||
|
fprintf(stderr, "Didn't read the expected data from pipe after writev\n");
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
close(pipefds[0]);
|
||||||
|
close(pipefds[1]);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int, char**)
|
int main(int, char**)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -280,6 +313,7 @@ int main(int, char**)
|
||||||
test_unlink_symlink();
|
test_unlink_symlink();
|
||||||
test_eoverflow();
|
test_eoverflow();
|
||||||
test_rmdir_while_inside_dir();
|
test_rmdir_while_inside_dir();
|
||||||
|
test_writev();
|
||||||
|
|
||||||
EXPECT_ERROR_2(EPERM, link, "/", "/home/anon/lolroot");
|
EXPECT_ERROR_2(EPERM, link, "/", "/home/anon/lolroot");
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue