00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "GroupsockHelper.hh"
00022
00023 #if defined(__WIN32__) || defined(_WIN32)
00024 #include <time.h>
00025 extern "C" int initializeWinsockIfNecessary();
00026 #else
00027 #include <stdarg.h>
00028 #include <time.h>
00029 #include <fcntl.h>
00030 #define initializeWinsockIfNecessary() 1
00031 #endif
00032 #include <stdio.h>
00033
00034
00035 netAddressBits SendingInterfaceAddr = INADDR_ANY;
00036 netAddressBits ReceivingInterfaceAddr = INADDR_ANY;
00037
00038 static void socketErr(UsageEnvironment& env, char const* errorMsg) {
00039 env.setResultErrMsg(errorMsg);
00040 }
00041
00042 NoReuse::NoReuse(UsageEnvironment& env)
00043 : fEnv(env) {
00044 groupsockPriv(fEnv)->reuseFlag = 0;
00045 }
00046
00047 NoReuse::~NoReuse() {
00048 groupsockPriv(fEnv)->reuseFlag = 1;
00049 reclaimGroupsockPriv(fEnv);
00050 }
00051
00052
00053 _groupsockPriv* groupsockPriv(UsageEnvironment& env) {
00054 if (env.groupsockPriv == NULL) {
00055 _groupsockPriv* result = new _groupsockPriv;
00056 result->socketTable = NULL;
00057 result->reuseFlag = 1;
00058 env.groupsockPriv = result;
00059 }
00060 return (_groupsockPriv*)(env.groupsockPriv);
00061 }
00062
00063 void reclaimGroupsockPriv(UsageEnvironment& env) {
00064 _groupsockPriv* priv = (_groupsockPriv*)(env.groupsockPriv);
00065 if (priv->socketTable == NULL && priv->reuseFlag == 1) {
00066
00067 delete priv;
00068 env.groupsockPriv = NULL;
00069 }
00070 }
00071
00072 static int createSocket(int type) {
00073
00074
00075 int sock;
00076
00077 #ifdef SOCK_CLOEXEC
00078 sock = socket(AF_INET, type|SOCK_CLOEXEC, 0);
00079 if (sock != -1 || errno != EINVAL) return sock;
00080
00081 #endif
00082
00083 sock = socket(AF_INET, type, 0);
00084 #ifdef FD_CLOEXEC
00085 if (sock != -1) fcntl(sock, F_SETFD, FD_CLOEXEC);
00086 #endif
00087 return sock;
00088 }
00089
00090 int setupDatagramSocket(UsageEnvironment& env, Port port) {
00091 if (!initializeWinsockIfNecessary()) {
00092 socketErr(env, "Failed to initialize 'winsock': ");
00093 return -1;
00094 }
00095
00096 int newSocket = createSocket(SOCK_DGRAM);
00097 if (newSocket < 0) {
00098 socketErr(env, "unable to create datagram socket: ");
00099 return newSocket;
00100 }
00101
00102 int reuseFlag = groupsockPriv(env)->reuseFlag;
00103 reclaimGroupsockPriv(env);
00104 if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEADDR,
00105 (const char*)&reuseFlag, sizeof reuseFlag) < 0) {
00106 socketErr(env, "setsockopt(SO_REUSEADDR) error: ");
00107 closeSocket(newSocket);
00108 return -1;
00109 }
00110
00111 #if defined(__WIN32__) || defined(_WIN32)
00112
00113 #else
00114 #ifdef SO_REUSEPORT
00115 if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEPORT,
00116 (const char*)&reuseFlag, sizeof reuseFlag) < 0) {
00117 socketErr(env, "setsockopt(SO_REUSEPORT) error: ");
00118 closeSocket(newSocket);
00119 return -1;
00120 }
00121 #endif
00122
00123 #ifdef IP_MULTICAST_LOOP
00124 const u_int8_t loop = 1;
00125 if (setsockopt(newSocket, IPPROTO_IP, IP_MULTICAST_LOOP,
00126 (const char*)&loop, sizeof loop) < 0) {
00127 socketErr(env, "setsockopt(IP_MULTICAST_LOOP) error: ");
00128 closeSocket(newSocket);
00129 return -1;
00130 }
00131 #endif
00132 #endif
00133
00134
00135 netAddressBits addr = INADDR_ANY;
00136 #if defined(__WIN32__) || defined(_WIN32)
00137 #else
00138 if (port.num() != 0 || ReceivingInterfaceAddr != INADDR_ANY) {
00139 #endif
00140 if (port.num() == 0) addr = ReceivingInterfaceAddr;
00141 MAKE_SOCKADDR_IN(name, addr, port.num());
00142 if (bind(newSocket, (struct sockaddr*)&name, sizeof name) != 0) {
00143 char tmpBuffer[100];
00144 sprintf(tmpBuffer, "bind() error (port number: %d): ",
00145 ntohs(port.num()));
00146 socketErr(env, tmpBuffer);
00147 closeSocket(newSocket);
00148 return -1;
00149 }
00150 #if defined(__WIN32__) || defined(_WIN32)
00151 #else
00152 }
00153 #endif
00154
00155
00156 if (SendingInterfaceAddr != INADDR_ANY) {
00157 struct in_addr addr;
00158 addr.s_addr = SendingInterfaceAddr;
00159
00160 if (setsockopt(newSocket, IPPROTO_IP, IP_MULTICAST_IF,
00161 (const char*)&addr, sizeof addr) < 0) {
00162 socketErr(env, "error setting outgoing multicast interface: ");
00163 closeSocket(newSocket);
00164 return -1;
00165 }
00166 }
00167
00168 return newSocket;
00169 }
00170
00171 Boolean makeSocketNonBlocking(int sock) {
00172 #if defined(__WIN32__) || defined(_WIN32)
00173 unsigned long arg = 1;
00174 return ioctlsocket(sock, FIONBIO, &arg) == 0;
00175 #elif defined(VXWORKS)
00176 int arg = 1;
00177 return ioctl(sock, FIONBIO, (int)&arg) == 0;
00178 #else
00179 int curFlags = fcntl(sock, F_GETFL, 0);
00180 return fcntl(sock, F_SETFL, curFlags|O_NONBLOCK) >= 0;
00181 #endif
00182 }
00183
00184 Boolean makeSocketBlocking(int sock) {
00185 #if defined(__WIN32__) || defined(_WIN32)
00186 unsigned long arg = 0;
00187 return ioctlsocket(sock, FIONBIO, &arg) == 0;
00188 #elif defined(VXWORKS)
00189 int arg = 0;
00190 return ioctl(sock, FIONBIO, (int)&arg) == 0;
00191 #else
00192 int curFlags = fcntl(sock, F_GETFL, 0);
00193 return fcntl(sock, F_SETFL, curFlags&(~O_NONBLOCK)) >= 0;
00194 #endif
00195 }
00196
00197 int setupStreamSocket(UsageEnvironment& env,
00198 Port port, Boolean makeNonBlocking) {
00199 if (!initializeWinsockIfNecessary()) {
00200 socketErr(env, "Failed to initialize 'winsock': ");
00201 return -1;
00202 }
00203
00204 int newSocket = createSocket(SOCK_STREAM);
00205 if (newSocket < 0) {
00206 socketErr(env, "unable to create stream socket: ");
00207 return newSocket;
00208 }
00209
00210 int reuseFlag = groupsockPriv(env)->reuseFlag;
00211 reclaimGroupsockPriv(env);
00212 if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEADDR,
00213 (const char*)&reuseFlag, sizeof reuseFlag) < 0) {
00214 socketErr(env, "setsockopt(SO_REUSEADDR) error: ");
00215 closeSocket(newSocket);
00216 return -1;
00217 }
00218
00219
00220
00221
00222 #ifdef REUSE_FOR_TCP
00223 #if defined(__WIN32__) || defined(_WIN32)
00224
00225 #else
00226 #ifdef SO_REUSEPORT
00227 if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEPORT,
00228 (const char*)&reuseFlag, sizeof reuseFlag) < 0) {
00229 socketErr(env, "setsockopt(SO_REUSEPORT) error: ");
00230 closeSocket(newSocket);
00231 return -1;
00232 }
00233 #endif
00234 #endif
00235 #endif
00236
00237
00238 #if defined(__WIN32__) || defined(_WIN32)
00239 #else
00240 if (port.num() != 0 || ReceivingInterfaceAddr != INADDR_ANY) {
00241 #endif
00242 MAKE_SOCKADDR_IN(name, ReceivingInterfaceAddr, port.num());
00243 if (bind(newSocket, (struct sockaddr*)&name, sizeof name) != 0) {
00244 char tmpBuffer[100];
00245 sprintf(tmpBuffer, "bind() error (port number: %d): ",
00246 ntohs(port.num()));
00247 socketErr(env, tmpBuffer);
00248 closeSocket(newSocket);
00249 return -1;
00250 }
00251 #if defined(__WIN32__) || defined(_WIN32)
00252 #else
00253 }
00254 #endif
00255
00256 if (makeNonBlocking) {
00257 if (!makeSocketNonBlocking(newSocket)) {
00258 socketErr(env, "failed to make non-blocking: ");
00259 closeSocket(newSocket);
00260 return -1;
00261 }
00262 }
00263
00264 return newSocket;
00265 }
00266
00267 int readSocket(UsageEnvironment& env,
00268 int socket, unsigned char* buffer, unsigned bufferSize,
00269 struct sockaddr_in& fromAddress) {
00270 SOCKLEN_T addressSize = sizeof fromAddress;
00271 int bytesRead = recvfrom(socket, (char*)buffer, bufferSize, 0,
00272 (struct sockaddr*)&fromAddress,
00273 &addressSize);
00274 if (bytesRead < 0) {
00275
00276 int err = env.getErrno();
00277 if (err == 111
00278 #if defined(__WIN32__) || defined(_WIN32)
00279
00280
00281
00282
00283
00284
00285 || err == 0 || err == EWOULDBLOCK
00286 #else
00287 || err == EAGAIN
00288 #endif
00289 || err == 113 ) {
00290 fromAddress.sin_addr.s_addr = 0;
00291 return 0;
00292 }
00293
00294 socketErr(env, "recvfrom() error: ");
00295 } else if (bytesRead == 0) {
00296
00297 return -1;
00298 }
00299
00300 return bytesRead;
00301 }
00302
00303 Boolean writeSocket(UsageEnvironment& env,
00304 int socket, struct in_addr address, Port port,
00305 u_int8_t ttlArg,
00306 unsigned char* buffer, unsigned bufferSize) {
00307 do {
00308 if (ttlArg != 0) {
00309
00310 #if defined(__WIN32__) || defined(_WIN32)
00311 #define TTL_TYPE int
00312 #else
00313 #define TTL_TYPE u_int8_t
00314 #endif
00315 TTL_TYPE ttl = (TTL_TYPE)ttlArg;
00316 if (setsockopt(socket, IPPROTO_IP, IP_MULTICAST_TTL,
00317 (const char*)&ttl, sizeof ttl) < 0) {
00318 socketErr(env, "setsockopt(IP_MULTICAST_TTL) error: ");
00319 break;
00320 }
00321 }
00322
00323 MAKE_SOCKADDR_IN(dest, address.s_addr, port.num());
00324 int bytesSent = sendto(socket, (char*)buffer, bufferSize, 0,
00325 (struct sockaddr*)&dest, sizeof dest);
00326 if (bytesSent != (int)bufferSize) {
00327 char tmpBuf[100];
00328 sprintf(tmpBuf, "writeSocket(%d), sendTo() error: wrote %d bytes instead of %u: ", socket, bytesSent, bufferSize);
00329 socketErr(env, tmpBuf);
00330 break;
00331 }
00332
00333 return True;
00334 } while (0);
00335
00336 return False;
00337 }
00338
00339 static unsigned getBufferSize(UsageEnvironment& env, int bufOptName,
00340 int socket) {
00341 unsigned curSize;
00342 SOCKLEN_T sizeSize = sizeof curSize;
00343 if (getsockopt(socket, SOL_SOCKET, bufOptName,
00344 (char*)&curSize, &sizeSize) < 0) {
00345 socketErr(env, "getBufferSize() error: ");
00346 return 0;
00347 }
00348
00349 return curSize;
00350 }
00351 unsigned getSendBufferSize(UsageEnvironment& env, int socket) {
00352 return getBufferSize(env, SO_SNDBUF, socket);
00353 }
00354 unsigned getReceiveBufferSize(UsageEnvironment& env, int socket) {
00355 return getBufferSize(env, SO_RCVBUF, socket);
00356 }
00357
00358 static unsigned setBufferTo(UsageEnvironment& env, int bufOptName,
00359 int socket, unsigned requestedSize) {
00360 SOCKLEN_T sizeSize = sizeof requestedSize;
00361 setsockopt(socket, SOL_SOCKET, bufOptName, (char*)&requestedSize, sizeSize);
00362
00363
00364 return getBufferSize(env, bufOptName, socket);
00365 }
00366 unsigned setSendBufferTo(UsageEnvironment& env,
00367 int socket, unsigned requestedSize) {
00368 return setBufferTo(env, SO_SNDBUF, socket, requestedSize);
00369 }
00370 unsigned setReceiveBufferTo(UsageEnvironment& env,
00371 int socket, unsigned requestedSize) {
00372 return setBufferTo(env, SO_RCVBUF, socket, requestedSize);
00373 }
00374
00375 static unsigned increaseBufferTo(UsageEnvironment& env, int bufOptName,
00376 int socket, unsigned requestedSize) {
00377
00378
00379 unsigned curSize = getBufferSize(env, bufOptName, socket);
00380
00381
00382
00383 while (requestedSize > curSize) {
00384 SOCKLEN_T sizeSize = sizeof requestedSize;
00385 if (setsockopt(socket, SOL_SOCKET, bufOptName,
00386 (char*)&requestedSize, sizeSize) >= 0) {
00387
00388 return requestedSize;
00389 }
00390 requestedSize = (requestedSize+curSize)/2;
00391 }
00392
00393 return getBufferSize(env, bufOptName, socket);
00394 }
00395 unsigned increaseSendBufferTo(UsageEnvironment& env,
00396 int socket, unsigned requestedSize) {
00397 return increaseBufferTo(env, SO_SNDBUF, socket, requestedSize);
00398 }
00399 unsigned increaseReceiveBufferTo(UsageEnvironment& env,
00400 int socket, unsigned requestedSize) {
00401 return increaseBufferTo(env, SO_RCVBUF, socket, requestedSize);
00402 }
00403
00404 Boolean socketJoinGroup(UsageEnvironment& env, int socket,
00405 netAddressBits groupAddress){
00406 if (!IsMulticastAddress(groupAddress)) return True;
00407
00408 struct ip_mreq imr;
00409 imr.imr_multiaddr.s_addr = groupAddress;
00410 imr.imr_interface.s_addr = ReceivingInterfaceAddr;
00411 if (setsockopt(socket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
00412 (const char*)&imr, sizeof (struct ip_mreq)) < 0) {
00413 #if defined(__WIN32__) || defined(_WIN32)
00414 if (env.getErrno() != 0) {
00415
00416
00417 #endif
00418 socketErr(env, "setsockopt(IP_ADD_MEMBERSHIP) error: ");
00419 return False;
00420 #if defined(__WIN32__) || defined(_WIN32)
00421 }
00422 #endif
00423 }
00424
00425 return True;
00426 }
00427
00428 Boolean socketLeaveGroup(UsageEnvironment&, int socket,
00429 netAddressBits groupAddress) {
00430 if (!IsMulticastAddress(groupAddress)) return True;
00431
00432 struct ip_mreq imr;
00433 imr.imr_multiaddr.s_addr = groupAddress;
00434 imr.imr_interface.s_addr = ReceivingInterfaceAddr;
00435 if (setsockopt(socket, IPPROTO_IP, IP_DROP_MEMBERSHIP,
00436 (const char*)&imr, sizeof (struct ip_mreq)) < 0) {
00437 return False;
00438 }
00439
00440 return True;
00441 }
00442
00443
00444
00445
00446 #if !defined(IP_ADD_SOURCE_MEMBERSHIP)
00447 struct ip_mreq_source {
00448 struct in_addr imr_multiaddr;
00449 struct in_addr imr_sourceaddr;
00450 struct in_addr imr_interface;
00451 };
00452 #endif
00453
00454 #ifndef IP_ADD_SOURCE_MEMBERSHIP
00455
00456 #ifdef LINUX
00457 #define IP_ADD_SOURCE_MEMBERSHIP 39
00458 #define IP_DROP_SOURCE_MEMBERSHIP 40
00459 #else
00460 #define IP_ADD_SOURCE_MEMBERSHIP 25
00461 #define IP_DROP_SOURCE_MEMBERSHIP 26
00462 #endif
00463
00464 #endif
00465
00466 Boolean socketJoinGroupSSM(UsageEnvironment& env, int socket,
00467 netAddressBits groupAddress,
00468 netAddressBits sourceFilterAddr) {
00469 if (!IsMulticastAddress(groupAddress)) return True;
00470
00471 struct ip_mreq_source imr;
00472 #ifdef ANDROID
00473 imr.imr_multiaddr = groupAddress;
00474 imr.imr_sourceaddr = sourceFilterAddr;
00475 imr.imr_interface = ReceivingInterfaceAddr;
00476 #else
00477 imr.imr_multiaddr.s_addr = groupAddress;
00478 imr.imr_sourceaddr.s_addr = sourceFilterAddr;
00479 imr.imr_interface.s_addr = ReceivingInterfaceAddr;
00480 #endif
00481 if (setsockopt(socket, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP,
00482 (const char*)&imr, sizeof (struct ip_mreq_source)) < 0) {
00483 socketErr(env, "setsockopt(IP_ADD_SOURCE_MEMBERSHIP) error: ");
00484 return False;
00485 }
00486
00487 return True;
00488 }
00489
00490 Boolean socketLeaveGroupSSM(UsageEnvironment& , int socket,
00491 netAddressBits groupAddress,
00492 netAddressBits sourceFilterAddr) {
00493 if (!IsMulticastAddress(groupAddress)) return True;
00494
00495 struct ip_mreq_source imr;
00496 #ifdef ANDROID
00497 imr.imr_multiaddr = groupAddress;
00498 imr.imr_sourceaddr = sourceFilterAddr;
00499 imr.imr_interface = ReceivingInterfaceAddr;
00500 #else
00501 imr.imr_multiaddr.s_addr = groupAddress;
00502 imr.imr_sourceaddr.s_addr = sourceFilterAddr;
00503 imr.imr_interface.s_addr = ReceivingInterfaceAddr;
00504 #endif
00505 if (setsockopt(socket, IPPROTO_IP, IP_DROP_SOURCE_MEMBERSHIP,
00506 (const char*)&imr, sizeof (struct ip_mreq_source)) < 0) {
00507 return False;
00508 }
00509
00510 return True;
00511 }
00512
00513 static Boolean getSourcePort0(int socket, portNumBits& resultPortNum) {
00514 sockaddr_in test; test.sin_port = 0;
00515 SOCKLEN_T len = sizeof test;
00516 if (getsockname(socket, (struct sockaddr*)&test, &len) < 0) return False;
00517
00518 resultPortNum = ntohs(test.sin_port);
00519 return True;
00520 }
00521
00522 Boolean getSourcePort(UsageEnvironment& env, int socket, Port& port) {
00523 portNumBits portNum = 0;
00524 if (!getSourcePort0(socket, portNum) || portNum == 0) {
00525
00526 MAKE_SOCKADDR_IN(name, INADDR_ANY, 0);
00527 bind(socket, (struct sockaddr*)&name, sizeof name);
00528
00529 if (!getSourcePort0(socket, portNum) || portNum == 0) {
00530 socketErr(env, "getsockname() error: ");
00531 return False;
00532 }
00533 }
00534
00535 port = Port(portNum);
00536 return True;
00537 }
00538
00539 static Boolean badAddressForUs(netAddressBits addr) {
00540
00541 netAddressBits nAddr = htonl(addr);
00542 return (nAddr == 0x7F000001
00543 || nAddr == 0
00544 || nAddr == (netAddressBits)(~0));
00545 }
00546
00547 Boolean loopbackWorks = 1;
00548
00549 netAddressBits ourIPAddress(UsageEnvironment& env) {
00550 static netAddressBits ourAddress = 0;
00551 int sock = -1;
00552 struct in_addr testAddr;
00553
00554 if (ourAddress == 0) {
00555
00556 struct sockaddr_in fromAddr;
00557 fromAddr.sin_addr.s_addr = 0;
00558
00559
00560
00561
00562
00563 do {
00564 loopbackWorks = 0;
00565
00566 testAddr.s_addr = our_inet_addr("228.67.43.91");
00567 Port testPort(15947);
00568
00569 sock = setupDatagramSocket(env, testPort);
00570 if (sock < 0) break;
00571
00572 if (!socketJoinGroup(env, sock, testAddr.s_addr)) break;
00573
00574 unsigned char testString[] = "hostIdTest";
00575 unsigned testStringLength = sizeof testString;
00576
00577 if (!writeSocket(env, sock, testAddr, testPort, 0,
00578 testString, testStringLength)) break;
00579
00580
00581 fd_set rd_set;
00582 FD_ZERO(&rd_set);
00583 FD_SET((unsigned)sock, &rd_set);
00584 const unsigned numFds = sock+1;
00585 struct timeval timeout;
00586 timeout.tv_sec = 5;
00587 timeout.tv_usec = 0;
00588 int result = select(numFds, &rd_set, NULL, NULL, &timeout);
00589 if (result <= 0) break;
00590
00591 unsigned char readBuffer[20];
00592 int bytesRead = readSocket(env, sock,
00593 readBuffer, sizeof readBuffer,
00594 fromAddr);
00595 if (bytesRead != (int)testStringLength
00596 || strncmp((char*)readBuffer, (char*)testString, testStringLength) != 0) {
00597 break;
00598 }
00599
00600
00601 loopbackWorks = !badAddressForUs(fromAddr.sin_addr.s_addr);
00602 } while (0);
00603
00604 if (sock >= 0) {
00605 socketLeaveGroup(env, sock, testAddr.s_addr);
00606 closeSocket(sock);
00607 }
00608
00609 if (!loopbackWorks) do {
00610
00611
00612 char hostname[100];
00613 hostname[0] = '\0';
00614 int result = gethostname(hostname, sizeof hostname);
00615 if (result != 0 || hostname[0] == '\0') {
00616 env.setResultErrMsg("initial gethostname() failed");
00617 break;
00618 }
00619
00620
00621 NetAddressList addresses(hostname);
00622 NetAddressList::Iterator iter(addresses);
00623 NetAddress const* address;
00624
00625
00626 netAddressBits addr = 0;
00627 while ((address = iter.nextAddress()) != NULL) {
00628 netAddressBits a = *(netAddressBits*)(address->data());
00629 if (!badAddressForUs(a)) {
00630 addr = a;
00631 break;
00632 }
00633 }
00634
00635
00636 fromAddr.sin_addr.s_addr = addr;
00637 } while (0);
00638
00639
00640 netAddressBits from = fromAddr.sin_addr.s_addr;
00641 if (badAddressForUs(from)) {
00642 char tmp[100];
00643 sprintf(tmp, "This computer has an invalid IP address: %s", AddressString(from).val());
00644 env.setResultMsg(tmp);
00645 from = 0;
00646 }
00647
00648 ourAddress = from;
00649
00650
00651
00652 struct timeval timeNow;
00653 gettimeofday(&timeNow, NULL);
00654 unsigned seed = ourAddress^timeNow.tv_sec^timeNow.tv_usec;
00655 our_srandom(seed);
00656 }
00657 return ourAddress;
00658 }
00659
00660 netAddressBits chooseRandomIPv4SSMAddress(UsageEnvironment& env) {
00661
00662 (void) ourIPAddress(env);
00663
00664
00665
00666 netAddressBits const first = 0xE8000100, lastPlus1 = 0xE8FFFFFF;
00667 netAddressBits const range = lastPlus1 - first;
00668
00669 return ntohl(first + ((netAddressBits)our_random())%range);
00670 }
00671
00672 char const* timestampString() {
00673 struct timeval tvNow;
00674 gettimeofday(&tvNow, NULL);
00675
00676 #if !defined(_WIN32_WCE)
00677 static char timeString[9];
00678 char const* ctimeResult = ctime((time_t*)&tvNow.tv_sec);
00679 if (ctimeResult == NULL) {
00680 sprintf(timeString, "??:??:??");
00681 } else {
00682 char const* from = &ctimeResult[11];
00683 int i;
00684 for (i = 0; i < 8; ++i) {
00685 timeString[i] = from[i];
00686 }
00687 timeString[i] = '\0';
00688 }
00689 #else
00690
00691
00692
00693 static char timeString[50];
00694 sprintf(timeString, "%lu.%06ld", tvNow.tv_sec, tvNow.tv_usec);
00695 #endif
00696
00697 return (char const*)&timeString;
00698 }
00699
00700 #if defined(__WIN32__) || defined(_WIN32)
00701
00702
00703
00704 static LONG initializeLock_gettimeofday = 0;
00705
00706 #if !defined(_WIN32_WCE)
00707 #include <sys/timeb.h>
00708 #endif
00709
00710 int gettimeofday(struct timeval* tp, int* ) {
00711 static LARGE_INTEGER tickFrequency, epochOffset;
00712
00713 static Boolean isInitialized = False;
00714
00715 LARGE_INTEGER tickNow;
00716
00717 #if !defined(_WIN32_WCE)
00718 QueryPerformanceCounter(&tickNow);
00719 #else
00720 tickNow.QuadPart = GetTickCount();
00721 #endif
00722
00723 if (!isInitialized) {
00724 if(1 == InterlockedIncrement(&initializeLock_gettimeofday)) {
00725 #if !defined(_WIN32_WCE)
00726
00727
00728 struct timeb tb;
00729 ftime(&tb);
00730 tp->tv_sec = tb.time;
00731 tp->tv_usec = 1000*tb.millitm;
00732
00733
00734 QueryPerformanceFrequency(&tickFrequency);
00735 #else
00736
00737 const LONGLONG epoch = 116444736000000000LL;
00738 FILETIME fileTime;
00739 LARGE_INTEGER time;
00740 GetSystemTimeAsFileTime(&fileTime);
00741
00742 time.HighPart = fileTime.dwHighDateTime;
00743 time.LowPart = fileTime.dwLowDateTime;
00744
00745
00746 tp->tv_sec = (long)((time.QuadPart - epoch) / 10000000L);
00747
00748
00749
00750
00751
00752
00753
00754 tp->tv_usec = 0;
00755
00756
00757 tickFrequency.QuadPart = 1000;
00758 #endif
00759
00760 epochOffset.QuadPart
00761 = tp->tv_sec * tickFrequency.QuadPart + (tp->tv_usec * tickFrequency.QuadPart) / 1000000L - tickNow.QuadPart;
00762
00763
00764 isInitialized = True;
00765 return 0;
00766 } else {
00767 InterlockedDecrement(&initializeLock_gettimeofday);
00768
00769 while(!isInitialized){
00770 Sleep(1);
00771 }
00772 }
00773 }
00774
00775
00776 tickNow.QuadPart += epochOffset.QuadPart;
00777
00778 tp->tv_sec = (long)(tickNow.QuadPart / tickFrequency.QuadPart);
00779 tp->tv_usec = (long)(((tickNow.QuadPart % tickFrequency.QuadPart) * 1000000L) / tickFrequency.QuadPart);
00780
00781 return 0;
00782 }
00783 #endif