/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <gtest/gtest.h>

#include <sys/uio.h>

#include "TemporaryFile.h"

TEST(sys_uio, readv_writev) {
  TemporaryFile tf;

  char buf1[] = "hello";
  char buf2[] = "world";
  iovec ios[] = { { buf1, 5 }, { buf2, 5 } };

  ASSERT_EQ(10, writev(tf.fd, ios, 2));

  ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET));

  memset(buf1, '1', sizeof(buf1));
  memset(buf2, '2', sizeof(buf2));

  ASSERT_EQ(10, readv(tf.fd, ios, 2));
  buf1[5] = buf2[5] = '\0';
  ASSERT_STREQ("hello", buf1);
  ASSERT_STREQ("world", buf2);
}

template <typename ReadFn, typename WriteFn>
void TestPreadVPwriteV(ReadFn read_fn, WriteFn write_fn) {
  TemporaryFile tf;

  char buf[] = "world";
  iovec ios[] = { { buf, 5 } };

  ASSERT_EQ(5, write_fn(tf.fd, ios, 1, 5));
  ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_CUR));

  strcpy(buf, "hello");
  ASSERT_EQ(5, write_fn(tf.fd, ios, 1, 0));
  ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_CUR));

  ASSERT_EQ(5, read_fn(tf.fd, ios, 1, 5));
  ASSERT_STREQ("world", buf);
  ASSERT_EQ(5, read_fn(tf.fd, ios, 1, 0));
  ASSERT_STREQ("hello", buf);
}

TEST(sys_uio, preadv_pwritev) {
  TestPreadVPwriteV(preadv, pwritev);
}

TEST(sys_uio, preadv64_pwritev64) {
  TestPreadVPwriteV(preadv64, pwritev64);
}

TEST(sys_uio, process_vm_readv) {
  ASSERT_EQ(0, process_vm_readv(0, nullptr, 0, nullptr, 0, 0));

  // Test that we can read memory from our own process
  char src[1024] = "This is the source buffer containing some data";
  char dst[1024] = "";
  iovec remote = { src, sizeof src };
  iovec local = { dst, sizeof dst };
  ASSERT_EQ(ssize_t(sizeof src), process_vm_readv(getpid(), &local, 1, &remote, 1, 0));
  // Check whether data was copied (in the correct direction)
  ASSERT_EQ('T', dst[0]);
  ASSERT_EQ(0, memcmp(src, dst, sizeof src));

  // Reading from non-allocated memory should return an error
  remote = { nullptr, sizeof dst };
  ASSERT_EQ(-1, process_vm_readv(getpid(), &local, 1, &remote, 1, 0));
  ASSERT_EQ(EFAULT, errno);
}

TEST(sys_uio, process_vm_writev) {
  ASSERT_EQ(0, process_vm_writev(0, nullptr, 0, nullptr, 0, 0));

  // Test that we can read memory from our own process
  char src[1024] = "This is the source buffer containing some data";
  char dst[1024] = "";
  iovec remote = { dst, sizeof dst };
  iovec local = { src, sizeof src };
  ASSERT_EQ(ssize_t(sizeof src), process_vm_writev(getpid(), &local, 1, &remote, 1, 0));
  // Check whether data was copied (in the correct direction)
  ASSERT_EQ('T', dst[0]);
  ASSERT_EQ(0, memcmp(src, dst, sizeof src));

  // Writing to non-allocated memory should return an error
  remote = { nullptr, sizeof dst };
  ASSERT_EQ(-1, process_vm_writev(getpid(), &local, 1, &remote, 1, 0));
  ASSERT_EQ(EFAULT, errno);
}
