04e3f6f765021e3c6d8eccfb42246872dfbdc5a6
[swifty.git] / src / libswift_udp / compat.cpp
1 /*
2  *  compat.cpp
3  *  swift
4  *
5  *  Created by Arno Bakker, Victor Grishchenko
6  *  Copyright 2009-2012 TECHNISCHE UNIVERSITEIT DELFT. All rights reserved.
7  *
8  */
9
10 #include "compat.h"
11 #include <sys/stat.h>
12 #include <stdio.h>
13 #include <assert.h>
14 #ifdef _WIN32
15 #include <tchar.h>
16 #include <io.h>
17 #include <sys/timeb.h>
18 #include <vector>
19 #include <stdexcept>
20 #else
21 #include <unistd.h>
22 #include <sys/time.h>
23 #endif
24
25 namespace swift {
26
27 #ifdef _WIN32
28 static HANDLE map_handles[1024];
29 #endif
30
31 int64_t file_size (int fd) {
32
33 #ifdef WIN32
34         struct _stat32i64 st;
35     _fstat32i64(fd, &st);
36 #else
37     struct stat st;
38     fstat(fd, &st);
39 #endif
40     return st.st_size;
41 }
42
43 int     file_seek (int fd, int64_t offset) {
44 #ifndef _WIN32
45     return lseek(fd,offset,SEEK_SET);
46 #else
47     return _lseeki64(fd,offset,SEEK_SET);
48 #endif
49 }
50
51 int     file_resize (int fd, int64_t new_size) {
52 #ifndef _WIN32
53     return ftruncate(fd, new_size);
54 #else
55     // Arno, 2011-10-27: Use 64-bit version
56     if (_chsize_s(fd,new_size) != 0)
57         return -1;
58     else
59         return 0;
60 #endif
61 }
62
63 void print_error(const char* msg) {
64     perror(msg);
65 #ifdef _WIN32
66     int e = WSAGetLastError();
67     if (e)
68         fprintf(stderr,"windows error #%u\n",e);
69 #endif
70 }
71
72 void*   memory_map (int fd, size_t size) {
73     if (!size)
74         size = file_size(fd);
75     void *mapping;
76 #ifndef _WIN32
77     mapping = mmap (NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
78     if (mapping==MAP_FAILED)
79         return NULL;
80     return mapping;
81 #else
82     HANDLE fhandle = (HANDLE)_get_osfhandle(fd);
83     assert(fd<1024);
84     HANDLE maphandle = CreateFileMapping(     fhandle,
85                                        NULL,
86                                        PAGE_READWRITE,
87                                        0,
88                                        0,
89                                        NULL    );
90     if (maphandle == NULL)
91         return NULL;
92     map_handles[fd] = maphandle;
93
94     mapping = MapViewOfFile         (  maphandle,
95                                        FILE_MAP_WRITE,
96                                        0,
97                                        0,
98                                        0  );
99
100     return mapping;
101 #endif
102 }
103
104 void    memory_unmap (int fd, void* mapping, size_t size) {
105 #ifndef _WIN32
106     munmap(mapping,size);
107     close(fd);
108 #else
109     UnmapViewOfFile(mapping);
110     CloseHandle(map_handles[fd]);
111 #endif
112 }
113
114 #ifdef _WIN32
115
116 size_t pread(int fildes, void *buf, size_t nbyte, __int64 offset)
117 {
118     _lseeki64(fildes,offset,SEEK_SET);
119     return read(fildes,buf,nbyte);
120 }
121
122 size_t pwrite(int fildes, const void *buf, size_t nbyte, __int64 offset)
123 {
124     _lseeki64(fildes,offset,SEEK_SET);
125     return write(fildes,buf,nbyte);
126 }
127
128
129 int inet_aton(const char *cp, struct in_addr *inp)
130 {
131     inp->S_un.S_addr = inet_addr(cp);
132     return 1;
133 }
134
135 #endif
136
137 #ifdef _WIN32
138
139 LARGE_INTEGER get_freq() {
140     LARGE_INTEGER proc_freq;
141     if (!::QueryPerformanceFrequency(&proc_freq))
142         print_error("HiResTimeOfDay: QueryPerformanceFrequency() failed");
143     return proc_freq;
144 }
145
146 tint usec_time(void)
147 {
148         static LARGE_INTEGER last_time;
149         LARGE_INTEGER cur_time;
150         QueryPerformanceCounter(&cur_time);
151         if (cur_time.QuadPart<last_time.QuadPart)
152                 print_error("QueryPerformanceCounter wrapped"); // does this happen?
153         last_time = cur_time;
154         static float freq = 1000000.0/get_freq().QuadPart;
155         tint usec = cur_time.QuadPart * freq;
156         return usec;
157 }
158
159
160 #else
161
162 tint usec_time(void)
163 {
164     struct timeval t;
165     gettimeofday(&t,NULL);
166     tint ret;
167     ret = t.tv_sec;
168     ret *= 1000000;
169     ret += t.tv_usec;
170     return ret;
171 }
172
173 #endif
174
175 void LibraryInit(void)
176 {
177 #ifdef _WIN32
178         static WSADATA _WSAData;
179         // win32 requires you to initialize the Winsock DLL with the desired
180         // specification version
181         WORD wVersionRequested;
182     wVersionRequested = MAKEWORD(2, 2);
183         WSAStartup(wVersionRequested, &_WSAData);
184 #endif
185 }
186
187
188 std::string gettmpdir(void)
189 {
190 #ifdef _WIN32
191   DWORD result = ::GetTempPath(0, _T(""));
192   if (result == 0)
193         throw std::runtime_error("Could not get system temp path");
194
195   std::vector<TCHAR> tempPath(result + 1);
196   result = ::GetTempPath(static_cast<DWORD>(tempPath.size()), &tempPath[0]);
197   if((result == 0) || (result >= tempPath.size()))
198         throw std::runtime_error("Could not get system temp path");
199
200   return std::string(tempPath.begin(), tempPath.begin() + static_cast<std::size_t>(result));
201 #else
202           return std::string("/tmp/");
203 #endif
204 }
205
206 bool    make_socket_nonblocking(evutil_socket_t fd) {
207 #ifdef _WIN32
208     u_long enable = 1;
209     return 0==ioctlsocket(fd, FIONBIO, &enable);
210 #else
211     return 0==fcntl(fd, F_SETFL, O_NONBLOCK);
212 #endif
213 }
214
215 bool    close_socket (evutil_socket_t sock) {
216 #ifdef _WIN32
217     return 0==closesocket(sock);
218 #else
219     return 0==::close(sock);
220 #endif
221 }
222
223     
224 // Arno: not thread safe!
225 struct timeval* tint2tv (tint t) {
226     static struct timeval tv;
227     tv.tv_usec = t%TINT_SEC;
228     tv.tv_sec = t/TINT_SEC;
229     return &tv;
230 }
231
232
233 }