1645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Copyright 2014 The Chromium Authors. All rights reserved.
2645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Use of this source code is governed by a BSD-style license that can be
3645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// found in the LICENSE file.
4645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
5645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/test/test_utils.h"
6645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
7645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <fcntl.h>
8645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <stddef.h>
9645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <unistd.h>
10645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
11645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/posix/eintr_wrapper.h"
12645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
13645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace mojo {
14645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace edk {
15645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace test {
16645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
17645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezbool BlockingWrite(const PlatformHandle& handle,
18645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                   const void* buffer,
19645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                   size_t bytes_to_write,
20645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                   size_t* bytes_written) {
21645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  int original_flags = fcntl(handle.handle, F_GETFL);
22645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  if (original_flags == -1 ||
23645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      fcntl(handle.handle, F_SETFL, original_flags & (~O_NONBLOCK)) != 0) {
24645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return false;
25645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
26645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
27645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ssize_t result = HANDLE_EINTR(write(handle.handle, buffer, bytes_to_write));
28645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
29645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  fcntl(handle.handle, F_SETFL, original_flags);
30645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
31645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  if (result < 0)
32645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return false;
33645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
34645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  *bytes_written = result;
35645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  return true;
36645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
37645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
38645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezbool BlockingRead(const PlatformHandle& handle,
39645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                  void* buffer,
40645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                  size_t buffer_size,
41645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                  size_t* bytes_read) {
42645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  int original_flags = fcntl(handle.handle, F_GETFL);
43645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  if (original_flags == -1 ||
44645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      fcntl(handle.handle, F_SETFL, original_flags & (~O_NONBLOCK)) != 0) {
45645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return false;
46645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
47645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
48645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ssize_t result = HANDLE_EINTR(read(handle.handle, buffer, buffer_size));
49645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
50645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  fcntl(handle.handle, F_SETFL, original_flags);
51645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
52645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  if (result < 0)
53645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return false;
54645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
55645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  *bytes_read = result;
56645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  return true;
57645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
58645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
59645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezbool NonBlockingRead(const PlatformHandle& handle,
60645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                     void* buffer,
61645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                     size_t buffer_size,
62645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                     size_t* bytes_read) {
63645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ssize_t result = HANDLE_EINTR(read(handle.handle, buffer, buffer_size));
64645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
65645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  if (result < 0) {
66645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    if (errno != EAGAIN && errno != EWOULDBLOCK)
67645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      return false;
68645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
69645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    *bytes_read = 0;
70645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  } else {
71645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    *bytes_read = result;
72645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
73645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
74645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  return true;
75645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
76645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
77645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezScopedPlatformHandle PlatformHandleFromFILE(base::ScopedFILE fp) {
78645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  CHECK(fp);
79645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  int rv = dup(fileno(fp.get()));
80645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  PCHECK(rv != -1) << "dup";
81645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  return ScopedPlatformHandle(PlatformHandle(rv));
82645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
83645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
84645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezbase::ScopedFILE FILEFromPlatformHandle(ScopedPlatformHandle h,
85645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                        const char* mode) {
86645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  CHECK(h.is_valid());
87645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  base::ScopedFILE rv(fdopen(h.release().handle, mode));
88645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  PCHECK(rv) << "fdopen";
89645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  return rv;
90645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
91645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
92645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}  // namespace test
93645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}  // namespace edk
94645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}  // namespace mojo
95