cmake build system: visiblity support for clang
[supercollider.git] / common / SC_Win32Utils.cpp
blob33fae573e28c47d37da1a7c8fe6d2bcabff78876
1 /*
2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #ifdef _WIN32
23 #include <cstdio>
24 #include <cstring>
25 #include <sys/timeb.h>
26 #include <time.h>
28 #include "SC_Win32Utils.h"
30 void win32_ReplaceCharInString(char* string, int len, char src, char dst)
32 for( int i = 0; i < len; i ++)
33 if(string[i] == src)
34 string[i] = dst;
37 void win32_ExtractContainingFolder(char* folder,const char* pattern,int maxChars)
39 strcpy(folder,pattern);
40 bool backSlashFound = false;
41 int pathLen = strlen(pattern);
42 for( int i = pathLen-2; i >= 0; --i) {
43 if( pattern[i] == '\\') {
44 folder[i+1] = 0;
45 backSlashFound = true;
46 break;
49 if( !backSlashFound )
50 folder[0] = 0;
54 void win32_gettimeofday(timeval* tv, void*)
56 long unsigned secBetween1601and1970 = 11644473600ULL;
57 FILETIME fileTime;
58 GetSystemTimeAsFileTime(&fileTime);
59 tv->tv_sec = (* (unsigned __int64 *) &fileTime / (unsigned __int64)10000000) - secBetween1601and1970;
60 tv->tv_usec = (* (unsigned __int64 *) &fileTime % (unsigned __int64)10000000)/(unsigned __int64)10;
64 void win32_GetHomeFolder(char* homeFolder, int bufLen)
66 char homeFolder_[_MAX_PATH];
67 const char *h = 0;
68 if (!(h = ::getenv("home")))
69 h = ::getenv("HOME");
71 if (h)
72 strcpy(homeFolder_,h);
73 else {
74 // for Windows NT HOME might be defined as either $(HOMESHARE)/$(HOMEPATH)
75 // or $(HOMEDRIVE)/$(HOMEPATH)
76 h = ::getenv("HOMESHARE");
77 if (!h)
78 h = ::getenv("HOMEDRIVE");
79 if (h) {
80 strcpy(homeFolder_,h);
81 h = ::getenv("HOMEPATH");
82 if (h)
83 strcat(homeFolder_,h);
86 size_t len = strlen(homeFolder_);
87 if (bufLen < len + 1)
88 fprintf(stderr, "the buffer given to win32_GetHomeFolder(...) is too small\n");
89 strncpy(homeFolder,homeFolder_,len);
90 homeFolder[len]= 0;
93 char* win32_basename(char* path)
95 int pathLen = strlen(path);
96 int lastPathSepFoundPos = -1;
97 int pos = 0;
98 while (path[pathLen-1] == '\\' || path[pathLen-1] == '/') {
99 path[pathLen-1]=0; pathLen--;
101 while(path[pos] != 0) {
102 if (path[pos] == '\\' || path[pos] == '/') {
103 lastPathSepFoundPos = pos;
105 pos++;
107 if (lastPathSepFoundPos == -1)
108 return path;
109 else
110 return path + lastPathSepFoundPos + 1;
113 char* win32_dirname(char* path)
115 int pathLen = strlen(path);
116 int lastPathSepFoundPos = -1;
117 int pos = 0;
118 while (path[pathLen-1] == '\\' || path[pathLen-1] == '/') {
119 path[pathLen-1]=0; pathLen--;
121 while(path[pos] != 0) {
122 if (path[pos] == '\\' || path[pos] == '/') {
123 lastPathSepFoundPos = pos;
125 pos++;
127 if (lastPathSepFoundPos != -1)
128 path[lastPathSepFoundPos]=0;
130 return path;
133 int win32_nanosleep (const struct timespec *requested_time,
134 struct timespec *remaining)
136 DWORD milliseconds = requested_time->tv_sec * 1000
137 + (requested_time->tv_nsec) / 1000000;
138 if (requested_time->tv_nsec < 0 || requested_time->tv_nsec > 1000000) {
139 errno = EINVAL;
140 return -1;
142 Sleep (milliseconds);
143 remaining->tv_sec = 0;
144 remaining->tv_nsec = 0;
145 return 0;
148 /* Based on code from PostgreSQL (pgsql/src/port/pipe.c)
149 * This is a replacement version of pipe for Win32 which allows
150 * returned handles to be used in select(). Note that read/write calls
151 * must be replaced with recv/send.
153 int win32_pipe(int handles[2])
155 SOCKET s;
156 struct sockaddr_in serv_addr;
157 int len = sizeof(serv_addr);
158 handles[0] = handles[1] = INVALID_SOCKET;
160 if ((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
162 printf("win32_pipe failed to create socket: %ui", WSAGetLastError());
163 return -1;
165 memset((void *) &serv_addr, 0, sizeof(serv_addr));
166 serv_addr.sin_family = AF_INET;
167 serv_addr.sin_port = htons(0);
168 serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
169 if (bind(s, (SOCKADDR *) & serv_addr, len) == SOCKET_ERROR)
171 printf("win32_pipe failed to bind: %ui", WSAGetLastError());
172 return -1;
174 if (listen(s, 1) == SOCKET_ERROR)
176 printf("win32_pipe failed to listen to socket: %ui", WSAGetLastError());
177 closesocket(s);
178 return -1;
180 if (getsockname(s, (SOCKADDR *) & serv_addr, &len) == SOCKET_ERROR)
182 printf("win32_pipe failed to getsockname: %ui", WSAGetLastError());
183 closesocket(s);
184 return -1;
186 if ((handles[1] = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
188 printf("win32_pipe failed to create socket 2: %ui", WSAGetLastError());
189 closesocket(s);
190 return -1;
192 if (connect(handles[1], (SOCKADDR *) & serv_addr, len) == SOCKET_ERROR)
194 printf("win32_pipe failed to connect to socket: %ui", WSAGetLastError());
195 closesocket(s);
196 return -1;
198 if ((handles[0] = accept(s, (SOCKADDR *) & serv_addr, &len)) == INVALID_SOCKET)
200 printf("win32_pipe failed to accept socket: %ui", WSAGetLastError());
201 closesocket(handles[1]);
202 handles[1] = INVALID_SOCKET;
203 closesocket(s);
204 return -1;
206 closesocket(s);
207 return 0;
210 int win32_piperead(int s, char *buf, int len)
212 int ret = recv(s, buf, len, 0);
214 if (ret < 0 && WSAGetLastError() == WSAECONNRESET)
215 /* EOF on the pipe! (win32 socket based implementation) */
216 ret = 0;
217 return ret;
220 int win32_pipewrite(int s, char *buf, int len)
222 int ret = send(s, buf, len, 0);
224 if (ret < 0 && WSAGetLastError() == WSAECONNRESET)
225 /* EOF on the pipe! (win32 socket based implementation) */
226 ret = 0;
227 return ret;
230 #endif
231 // _WIN32