Add a dummy FlagSaver class.
[folly.git] / folly / portability / Fcntl.cpp
1 /*
2  * Copyright 2016 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <folly/portability/Fcntl.h>
18
19 #ifdef _WIN32
20 #include <folly/portability/Sockets.h>
21 #include <folly/portability/Windows.h>
22
23 namespace folly {
24 namespace portability {
25 namespace fcntl {
26 int creat(char const* fn, int pm) { return _creat(fn, pm); }
27
28 int fcntl(int fd, int cmd, ...) {
29   va_list args;
30   int res = -1;
31   va_start(args, cmd);
32   switch (cmd) {
33     case F_GETFD: {
34       HANDLE h = (HANDLE)_get_osfhandle(fd);
35       if (h != INVALID_HANDLE_VALUE) {
36         DWORD flags;
37         if (GetHandleInformation(h, &flags)) {
38           res = flags & HANDLE_FLAG_INHERIT;
39         }
40       }
41       break;
42     }
43     case F_SETFD: {
44       int flags = va_arg(args, int);
45       HANDLE h = (HANDLE)_get_osfhandle(fd);
46       if (h != INVALID_HANDLE_VALUE) {
47         if (SetHandleInformation(
48                 h, HANDLE_FLAG_INHERIT, (DWORD)(flags & FD_CLOEXEC))) {
49           res = 0;
50         }
51       }
52       break;
53     }
54     case F_GETFL: {
55       // No idea how to get the IO blocking mode, so return 0.
56       res = 0;
57       break;
58     }
59     case F_SETFL: {
60       int flags = va_arg(args, int);
61       if (flags & O_NONBLOCK) {
62         // If it's not a socket, it's probably a pipe, and
63         // those are non-blocking by default with Windows.
64         if (folly::portability::sockets::is_fh_socket(fd)) {
65           SOCKET s = (SOCKET)_get_osfhandle(fd);
66           if (s != INVALID_SOCKET) {
67             u_long nonBlockingEnabled = 1;
68             res = ioctlsocket(s, FIONBIO, &nonBlockingEnabled);
69           }
70         } else {
71           res = 0;
72         }
73       }
74       break;
75     }
76   }
77   va_end(args);
78   return res;
79 }
80
81 int open(char const* fn, int of, int pm) {
82   int fh;
83   errno_t res = _sopen_s(&fh, fn, of, _SH_DENYNO, pm);
84   return res ? -1 : fh;
85 }
86
87 int posix_fallocate(int fd, off_t offset, off_t len) {
88   // We'll pretend we always have enough space. We
89   // can't exactly pre-allocate on windows anyways.
90   return 0;
91 }
92 }
93 }
94 }
95 #endif