1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at http://curl.haxx.se/docs/copyright.html.
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
23 #define CURL_NO_OLDIES
25 #include "setup.h" /* portability help from the lib directory */
33 #ifdef HAVE_SYS_SOCKET_H
34 #include <sys/socket.h>
36 #ifdef HAVE_NETINET_IN_H
37 #include <netinet/in.h>
39 #ifdef _XOPEN_SOURCE_EXTENDED
40 /* This define is "almost" required to build on HPUX 11 */
41 #include <arpa/inet.h>
46 #ifdef HAVE_SYS_POLL_H
48 #elif defined(HAVE_POLL_H)
52 #define ENABLE_CURLX_PRINTF
53 /* make the curlx header define all printf() functions to use the curlx_*
55 #include "curlx.h" /* from the private lib dir */
60 #if defined(ENABLE_IPV6) && defined(__MINGW32__)
61 const struct in6_addr in6addr_any = {{ IN6ADDR_ANY_INIT }};
64 void logmsg(const char *msg, ...)
67 char buffer[2048 + 1];
74 static time_t epoch_offset;
75 static int known_offset;
78 fprintf(stderr, "Error: serverlogfile not set\n");
84 epoch_offset = time(NULL) - tv.tv_sec;
87 sec = epoch_offset + tv.tv_sec;
88 now = localtime(&sec); /* not thread safe but we don't care */
90 snprintf(timebuf, sizeof(timebuf), "%02d:%02d:%02d.%06ld",
91 (int)now->tm_hour, (int)now->tm_min, (int)now->tm_sec, (long)tv.tv_usec);
94 vsnprintf(buffer, sizeof(buffer), msg, ap);
97 logfp = fopen(serverlogfile, "ab");
99 fprintf(logfp, "%s %s\n", timebuf, buffer);
104 fprintf(stderr, "fopen() failed with error: %d %s\n",
105 error, strerror(error));
106 fprintf(stderr, "Error opening file: %s\n", serverlogfile);
107 fprintf(stderr, "Msg not logged: %s %s\n", timebuf, buffer);
112 /* use instead of perror() on generic windows */
113 void win32_perror (const char *msg)
116 DWORD err = SOCKERRNO;
118 if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
119 LANG_NEUTRAL, buf, sizeof(buf), NULL))
120 snprintf(buf, sizeof(buf), "Unknown error %lu (%#lx)", err, err);
122 fprintf(stderr, "%s: ", msg);
123 fprintf(stderr, "%s\n", buf);
128 void win32_init(void)
130 WORD wVersionRequested;
133 wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
135 err = WSAStartup(wVersionRequested, &wsaData);
138 perror("Winsock init failed");
139 logmsg("Error initialising winsock -- aborting");
143 if ( LOBYTE( wsaData.wVersion ) != USE_WINSOCK ||
144 HIBYTE( wsaData.wVersion ) != USE_WINSOCK ) {
147 perror("Winsock init failed");
148 logmsg("No suitable winsock.dll found -- aborting");
153 void win32_cleanup(void)
157 #endif /* USE_WINSOCK */
159 /* set by the main code to point to where the test dir is */
160 const char *path=".";
162 char *test2file(long testno)
164 static char filename[256];
165 snprintf(filename, sizeof(filename), TEST_DATA_PATH, path, testno);
170 * Portable function used for waiting a specific amount of ms.
171 * Waiting indefinitely with this function is not allowed, a
172 * zero or negative timeout value will return immediately.
175 * -1 = system call error, or invalid timeout value
176 * 0 = specified timeout has elapsed
178 int wait_ms(int timeout_ms)
180 #if !defined(MSDOS) && !defined(USE_WINSOCK)
181 #ifndef HAVE_POLL_FINE
182 struct timeval pending_tv;
184 struct timeval initial_tv;
193 SET_SOCKERRNO(EINVAL);
198 #elif defined(USE_WINSOCK)
201 pending_ms = timeout_ms;
202 initial_tv = curlx_tvnow();
204 #if defined(HAVE_POLL_FINE)
205 r = poll(NULL, 0, pending_ms);
207 pending_tv.tv_sec = pending_ms / 1000;
208 pending_tv.tv_usec = (pending_ms % 1000) * 1000;
209 r = select(0, NULL, NULL, NULL, &pending_tv);
210 #endif /* HAVE_POLL_FINE */
214 if(error && (error != EINTR))
216 pending_ms = timeout_ms - (int)curlx_tvdiff(curlx_tvnow(), initial_tv);
220 #endif /* USE_WINSOCK */
226 int write_pidfile(const char *filename)
231 pid = (long)getpid();
232 pidfile = fopen(filename, "wb");
234 logmsg("Couldn't write pid file: %s %s", filename, strerror(ERRNO));
237 fprintf(pidfile, "%ld\n", pid);
239 logmsg("Wrote pid %ld to %s", pid, filename);
240 return 1; /* success */
243 void set_advisor_read_lock(const char *filename)
250 lockfile = fopen(filename, "wb");
251 } while((lockfile == NULL) && ((error = ERRNO) == EINTR));
252 if(lockfile == NULL) {
253 logmsg("Error creating lock file %s error: %d %s",
254 filename, error, strerror(error));
259 res = fclose(lockfile);
260 } while(res && ((error = ERRNO) == EINTR));
262 logmsg("Error closing lock file %s error: %d %s",
263 filename, error, strerror(error));
266 void clear_advisor_read_lock(const char *filename)
272 ** Log all removal failures. Even those due to file not existing.
273 ** This allows to detect if unexpectedly the file has already been
274 ** removed by a process different than the one that should do this.
278 res = unlink(filename);
279 } while(res && ((error = ERRNO) == EINTR));
281 logmsg("Error removing lock file %s error: %d %s",
282 filename, error, strerror(error));