2 * Copyright 2016 Facebook, Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include <folly/portability/Unistd.h>
22 #include <folly/portability/Sockets.h>
23 #include <folly/portability/Windows.h>
25 // Generic wrapper for the p* family of functions.
26 template <class F, class... Args>
27 static int wrapPositional(F f, int fd, off_t offset, Args... args) {
28 off_t origLoc = lseek(fd, 0, SEEK_CUR);
29 if (origLoc == (off_t)-1) {
32 if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {
36 int res = (int)f(fd, args...);
39 if (lseek(fd, origLoc, SEEK_SET) == (off_t)-1) {
51 namespace portability {
53 int access(char const* fn, int am) { return _access(fn, am); }
55 int chdir(const char* path) { return _chdir(path); }
58 if (folly::portability::sockets::is_fh_socket(fh)) {
59 SOCKET h = (SOCKET)_get_osfhandle(fh);
60 return closesocket(h);
65 int dup(int fh) { return _dup(fh); }
67 int dup2(int fhs, int fhd) { return _dup2(fhs, fhd); }
70 HANDLE h = (HANDLE)_get_osfhandle(fd);
71 if (h == INVALID_HANDLE_VALUE) {
74 if (!FlushFileBuffers(h)) {
80 int ftruncate(int fd, off_t len) {
81 if (_lseek(fd, len, SEEK_SET)) {
85 HANDLE h = (HANDLE)_get_osfhandle(fd);
86 if (h == INVALID_HANDLE_VALUE) {
89 if (!SetEndOfFile(h)) {
95 char* getcwd(char* buf, int sz) { return _getcwd(buf, sz); }
97 int getdtablesize() { return _getmaxstdio(); }
99 int getgid() { return 1; }
101 pid_t getpid() { return pid_t(GetCurrentProcessId()); }
103 // No major need to implement this, and getting a non-potentially
104 // stale ID on windows is a bit involved.
105 pid_t getppid() { return (pid_t)1; }
107 int getuid() { return 1; }
109 int isatty(int fh) { return _isatty(fh); }
111 int lockf(int fd, int cmd, off_t len) { return _locking(fd, cmd, len); }
113 long lseek(int fh, long off, int orig) { return _lseek(fh, off, orig); }
115 int rmdir(const char* path) { return _rmdir(path); }
117 int pipe(int* pth) { return _pipe(pth, 0, _O_BINARY); }
119 int pread(int fd, void* buf, size_t count, off_t offset) {
120 return wrapPositional(_read, fd, offset, buf, (unsigned int)count);
123 int pwrite(int fd, const void* buf, size_t count, off_t offset) {
124 return wrapPositional(_write, fd, offset, buf, (unsigned int)count);
127 int read(int fh, void* buf, unsigned int mcc) { return _read(fh, buf, mcc); }
129 ssize_t readlink(const char* path, char* buf, size_t buflen) {
134 HANDLE h = CreateFile(path,
139 FILE_FLAG_BACKUP_SEMANTICS,
141 if (h == INVALID_HANDLE_VALUE) {
145 DWORD ret = GetFinalPathNameByHandleA(h, buf, buflen - 1, VOLUME_NAME_DOS);
146 if (ret >= buflen || ret >= MAX_PATH || !ret) {
156 void* sbrk(intptr_t i) { return (void*)-1; }
158 int setmode(int fh, int md) { return _setmode(fh, md); }
160 unsigned int sleep(unsigned int seconds) {
161 Sleep((DWORD)(seconds * 1000));
165 size_t sysconf(int tp) {
170 return (size_t)inf.dwPageSize;
172 case _SC_NPROCESSORS_ONLN: {
175 return (size_t)inf.dwNumberOfProcessors;
182 long tell(int fh) { return _tell(fh); }
184 int truncate(const char* path, off_t len) {
185 int fd = _open(path, O_WRONLY);
189 if (ftruncate(fd, len)) {
193 return _close(fd) ? -1 : 0;
196 int usleep(unsigned int ms) {
197 Sleep((DWORD)(ms / 1000));
201 int write(int fh, void const* buf, unsigned int mcc) {
202 return _write(fh, buf, mcc);