Fix copyright lines
[folly.git] / folly / portability / Fcntl.cpp
1 /*
2  * Copyright 2016-present 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/SysStat.h>
22 #include <folly/portability/Windows.h>
23
24 namespace folly {
25 namespace portability {
26 namespace fcntl {
27 int creat(char const* fn, int pm) {
28   return _creat(fn, pm);
29 }
30
31 int fcntl(int fd, int cmd, ...) {
32   va_list args;
33   int res = -1;
34   va_start(args, cmd);
35   switch (cmd) {
36     case F_GETFD: {
37       HANDLE h = (HANDLE)_get_osfhandle(fd);
38       if (h != INVALID_HANDLE_VALUE) {
39         DWORD flags;
40         if (GetHandleInformation(h, &flags)) {
41           res = int(flags & HANDLE_FLAG_INHERIT);
42         }
43       }
44       break;
45     }
46     case F_SETFD: {
47       int flags = va_arg(args, int);
48       HANDLE h = (HANDLE)_get_osfhandle(fd);
49       if (h != INVALID_HANDLE_VALUE) {
50         if (SetHandleInformation(
51                 h, HANDLE_FLAG_INHERIT, (DWORD)(flags & FD_CLOEXEC))) {
52           res = 0;
53         }
54       }
55       break;
56     }
57     case F_GETFL: {
58       // No idea how to get the IO blocking mode, so return 0.
59       res = 0;
60       break;
61     }
62     case F_SETFL: {
63       int flags = va_arg(args, int);
64       // If it's not a socket, it's probably a pipe.
65       if (folly::portability::sockets::is_fh_socket(fd)) {
66         SOCKET s = (SOCKET)_get_osfhandle(fd);
67         if (s != INVALID_SOCKET) {
68           u_long nonBlockingEnabled = (flags & O_NONBLOCK) ? 1 : 0;
69           res = ioctlsocket(s, FIONBIO, &nonBlockingEnabled);
70         }
71       } else {
72         HANDLE p = (HANDLE)_get_osfhandle(fd);
73         if (GetFileType(p) == FILE_TYPE_PIPE) {
74           DWORD newMode = PIPE_READMODE_BYTE;
75           newMode |= (flags & O_NONBLOCK) ? PIPE_NOWAIT : PIPE_WAIT;
76           if (SetNamedPipeHandleState(p, &newMode, nullptr, nullptr)) {
77             res = 0;
78           }
79         }
80       }
81       break;
82     }
83   }
84   va_end(args);
85   return res;
86 }
87
88 int open(char const* fn, int of, int pm) {
89   int fh;
90   int realMode = _S_IREAD;
91   if ((of & _O_RDWR) == _O_RDWR) {
92     realMode = _S_IREAD | _S_IWRITE;
93   } else if ((of & _O_WRONLY) == _O_WRONLY) {
94     realMode = _S_IWRITE;
95   } else if ((of & _O_RDONLY) != _O_RDONLY) {
96     // One of these needs to be present, just fail if
97     // none are.
98     return -1;
99   }
100   if (!strcmp(fn, "/dev/null")) {
101     // Windows doesn't have a /dev/null, but it does have
102     // NUL, which achieves the same result.
103     fn = "NUL";
104   }
105   errno_t res = _sopen_s(&fh, fn, of, _SH_DENYNO, realMode);
106   return res ? -1 : fh;
107 }
108
109 int posix_fallocate(int fd, off_t offset, off_t len) {
110   // We'll pretend we always have enough space. We
111   // can't exactly pre-allocate on windows anyways.
112   return 0;
113 }
114 }
115 }
116 }
117 #endif