Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / common / SC_Win32Utils.cpp
blob36f88a086d6f905a0d7700a9358e1af4705fff20
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 <cstdlib>
26 #include <sys/timeb.h>
27 #include <time.h>
29 #include "SC_Win32Utils.h"
31 void win32_ReplaceCharInString(char* string, int len, char src, char dst)
33 for( int i = 0; i < len; i ++)
34 if(string[i] == src)
35 string[i] = dst;
38 void win32_ExtractContainingFolder(char* folder,const char* pattern,int maxChars)
40 strcpy(folder,pattern);
41 bool backSlashFound = false;
42 int pathLen = strlen(pattern);
43 for( int i = pathLen-2; i >= 0; --i) {
44 if( pattern[i] == '\\') {
45 folder[i+1] = 0;
46 backSlashFound = true;
47 break;
50 if( !backSlashFound )
51 folder[0] = 0;
55 void win32_gettimeofday(timeval* tv, void*)
57 long unsigned secBetween1601and1970 = 11644473600ULL;
58 FILETIME fileTime;
59 GetSystemTimeAsFileTime(&fileTime);
60 tv->tv_sec = (* (unsigned __int64 *) &fileTime / (unsigned __int64)10000000) - secBetween1601and1970;
61 tv->tv_usec = (* (unsigned __int64 *) &fileTime % (unsigned __int64)10000000)/(unsigned __int64)10;
65 void win32_GetHomeFolder(char* homeFolder, int bufLen)
67 char homeFolder_[MAX_PATH];
68 const char *h = 0;
69 if (!(h = ::getenv("home")))
70 h = ::getenv("HOME");
72 if (h)
73 strcpy(homeFolder_,h);
74 else {
75 // for Windows NT HOME might be defined as either $(HOMESHARE)/$(HOMEPATH)
76 // or $(HOMEDRIVE)/$(HOMEPATH)
77 h = ::getenv("HOMESHARE");
78 if (!h)
79 h = ::getenv("HOMEDRIVE");
80 if (h) {
81 strcpy(homeFolder_,h);
82 h = ::getenv("HOMEPATH");
83 if (h)
84 strcat(homeFolder_,h);
87 size_t len = strlen(homeFolder_);
88 if (bufLen < len + 1)
89 fprintf(stderr, "the buffer given to win32_GetHomeFolder(...) is too small\n");
90 strncpy(homeFolder,homeFolder_,len);
91 homeFolder[len]= 0;
94 char* win32_basename(char* path)
96 int pathLen = strlen(path);
97 int lastPathSepFoundPos = -1;
98 int pos = 0;
99 while (path[pathLen-1] == '\\' || path[pathLen-1] == '/') {
100 path[pathLen-1]=0; pathLen--;
102 while(path[pos] != 0) {
103 if (path[pos] == '\\' || path[pos] == '/') {
104 lastPathSepFoundPos = pos;
106 pos++;
108 if (lastPathSepFoundPos == -1)
109 return path;
110 else
111 return path + lastPathSepFoundPos + 1;
114 char* win32_dirname(char* path)
116 int pathLen = strlen(path);
117 int lastPathSepFoundPos = -1;
118 int pos = 0;
119 while (path[pathLen-1] == '\\' || path[pathLen-1] == '/') {
120 path[pathLen-1]=0; pathLen--;
122 while(path[pos] != 0) {
123 if (path[pos] == '\\' || path[pos] == '/') {
124 lastPathSepFoundPos = pos;
126 pos++;
128 if (lastPathSepFoundPos != -1)
129 path[lastPathSepFoundPos]=0;
131 return path;
134 int win32_nanosleep (const struct timespec *requested_time,
135 struct timespec *remaining)
137 DWORD milliseconds = requested_time->tv_sec * 1000
138 + (requested_time->tv_nsec) / 1000000;
139 if (requested_time->tv_nsec < 0 || requested_time->tv_nsec > 1000000) {
140 errno = EINVAL;
141 return -1;
143 Sleep (milliseconds);
144 remaining->tv_sec = 0;
145 remaining->tv_nsec = 0;
146 return 0;
149 /* Based on code from PostgreSQL (pgsql/src/port/pipe.c)
150 * This is a replacement version of pipe for Win32 which allows
151 * returned handles to be used in select(). Note that read/write calls
152 * must be replaced with recv/send.
154 int win32_pipe(int handles[2])
156 SOCKET s;
157 struct sockaddr_in serv_addr;
158 int len = sizeof(serv_addr);
159 handles[0] = handles[1] = INVALID_SOCKET;
161 if ((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
163 printf("win32_pipe failed to create socket: %ui", WSAGetLastError());
164 return -1;
166 memset((void *) &serv_addr, 0, sizeof(serv_addr));
167 serv_addr.sin_family = AF_INET;
168 serv_addr.sin_port = htons(0);
169 serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
170 if (bind(s, (SOCKADDR *) & serv_addr, len) == SOCKET_ERROR)
172 printf("win32_pipe failed to bind: %ui", WSAGetLastError());
173 return -1;
175 if (listen(s, 1) == SOCKET_ERROR)
177 printf("win32_pipe failed to listen to socket: %ui", WSAGetLastError());
178 closesocket(s);
179 return -1;
181 if (getsockname(s, (SOCKADDR *) & serv_addr, &len) == SOCKET_ERROR)
183 printf("win32_pipe failed to getsockname: %ui", WSAGetLastError());
184 closesocket(s);
185 return -1;
187 if ((handles[1] = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
189 printf("win32_pipe failed to create socket 2: %ui", WSAGetLastError());
190 closesocket(s);
191 return -1;
193 if (connect(handles[1], (SOCKADDR *) & serv_addr, len) == SOCKET_ERROR)
195 printf("win32_pipe failed to connect to socket: %ui", WSAGetLastError());
196 closesocket(s);
197 return -1;
199 if ((handles[0] = accept(s, (SOCKADDR *) & serv_addr, &len)) == INVALID_SOCKET)
201 printf("win32_pipe failed to accept socket: %ui", WSAGetLastError());
202 closesocket(handles[1]);
203 handles[1] = INVALID_SOCKET;
204 closesocket(s);
205 return -1;
207 closesocket(s);
208 return 0;
211 int win32_piperead(int s, char *buf, int len)
213 int ret = recv(s, buf, len, 0);
215 if (ret < 0 && WSAGetLastError() == WSAECONNRESET)
216 /* EOF on the pipe! (win32 socket based implementation) */
217 ret = 0;
218 return ret;
221 int win32_pipewrite(int s, char *buf, int len)
223 int ret = send(s, buf, len, 0);
225 if (ret < 0 && WSAGetLastError() == WSAECONNRESET)
226 /* EOF on the pipe! (win32 socket based implementation) */
227 ret = 0;
228 return ret;
231 #endif
232 // _WIN32