xref: /aosp_15_r20/external/curl/tests/server/util.c (revision 6236dae45794135f37c4eb022389c904c8b0090d)
1*6236dae4SAndroid Build Coastguard Worker /***************************************************************************
2*6236dae4SAndroid Build Coastguard Worker  *                                  _   _ ____  _
3*6236dae4SAndroid Build Coastguard Worker  *  Project                     ___| | | |  _ \| |
4*6236dae4SAndroid Build Coastguard Worker  *                             / __| | | | |_) | |
5*6236dae4SAndroid Build Coastguard Worker  *                            | (__| |_| |  _ <| |___
6*6236dae4SAndroid Build Coastguard Worker  *                             \___|\___/|_| \_\_____|
7*6236dae4SAndroid Build Coastguard Worker  *
8*6236dae4SAndroid Build Coastguard Worker  * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
9*6236dae4SAndroid Build Coastguard Worker  *
10*6236dae4SAndroid Build Coastguard Worker  * This software is licensed as described in the file COPYING, which
11*6236dae4SAndroid Build Coastguard Worker  * you should have received as part of this distribution. The terms
12*6236dae4SAndroid Build Coastguard Worker  * are also available at https://curl.se/docs/copyright.html.
13*6236dae4SAndroid Build Coastguard Worker  *
14*6236dae4SAndroid Build Coastguard Worker  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15*6236dae4SAndroid Build Coastguard Worker  * copies of the Software, and permit persons to whom the Software is
16*6236dae4SAndroid Build Coastguard Worker  * furnished to do so, under the terms of the COPYING file.
17*6236dae4SAndroid Build Coastguard Worker  *
18*6236dae4SAndroid Build Coastguard Worker  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19*6236dae4SAndroid Build Coastguard Worker  * KIND, either express or implied.
20*6236dae4SAndroid Build Coastguard Worker  *
21*6236dae4SAndroid Build Coastguard Worker  * SPDX-License-Identifier: curl
22*6236dae4SAndroid Build Coastguard Worker  *
23*6236dae4SAndroid Build Coastguard Worker  ***************************************************************************/
24*6236dae4SAndroid Build Coastguard Worker #include "server_setup.h"
25*6236dae4SAndroid Build Coastguard Worker 
26*6236dae4SAndroid Build Coastguard Worker #include <signal.h>
27*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_NETINET_IN_H
28*6236dae4SAndroid Build Coastguard Worker #include <netinet/in.h>
29*6236dae4SAndroid Build Coastguard Worker #endif
30*6236dae4SAndroid Build Coastguard Worker #ifdef _XOPEN_SOURCE_EXTENDED
31*6236dae4SAndroid Build Coastguard Worker /* This define is "almost" required to build on HP-UX 11 */
32*6236dae4SAndroid Build Coastguard Worker #include <arpa/inet.h>
33*6236dae4SAndroid Build Coastguard Worker #endif
34*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_NETDB_H
35*6236dae4SAndroid Build Coastguard Worker #include <netdb.h>
36*6236dae4SAndroid Build Coastguard Worker #endif
37*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_POLL_H
38*6236dae4SAndroid Build Coastguard Worker #include <poll.h>
39*6236dae4SAndroid Build Coastguard Worker #elif defined(HAVE_SYS_POLL_H)
40*6236dae4SAndroid Build Coastguard Worker #include <sys/poll.h>
41*6236dae4SAndroid Build Coastguard Worker #endif
42*6236dae4SAndroid Build Coastguard Worker 
43*6236dae4SAndroid Build Coastguard Worker #include "curlx.h" /* from the private lib dir */
44*6236dae4SAndroid Build Coastguard Worker #include "getpart.h"
45*6236dae4SAndroid Build Coastguard Worker #include "util.h"
46*6236dae4SAndroid Build Coastguard Worker #include "timeval.h"
47*6236dae4SAndroid Build Coastguard Worker 
48*6236dae4SAndroid Build Coastguard Worker #ifdef USE_WINSOCK
49*6236dae4SAndroid Build Coastguard Worker #undef  EINTR
50*6236dae4SAndroid Build Coastguard Worker #define EINTR    4 /* errno.h value */
51*6236dae4SAndroid Build Coastguard Worker #undef  EINVAL
52*6236dae4SAndroid Build Coastguard Worker #define EINVAL  22 /* errno.h value */
53*6236dae4SAndroid Build Coastguard Worker #endif
54*6236dae4SAndroid Build Coastguard Worker 
55*6236dae4SAndroid Build Coastguard Worker static struct timeval tvnow(void);
56*6236dae4SAndroid Build Coastguard Worker 
57*6236dae4SAndroid Build Coastguard Worker /* This function returns a pointer to STATIC memory. It converts the given
58*6236dae4SAndroid Build Coastguard Worker  * binary lump to a hex formatted string usable for output in logs or
59*6236dae4SAndroid Build Coastguard Worker  * whatever.
60*6236dae4SAndroid Build Coastguard Worker  */
data_to_hex(char * data,size_t len)61*6236dae4SAndroid Build Coastguard Worker char *data_to_hex(char *data, size_t len)
62*6236dae4SAndroid Build Coastguard Worker {
63*6236dae4SAndroid Build Coastguard Worker   static char buf[256*3];
64*6236dae4SAndroid Build Coastguard Worker   size_t i;
65*6236dae4SAndroid Build Coastguard Worker   char *optr = buf;
66*6236dae4SAndroid Build Coastguard Worker   char *iptr = data;
67*6236dae4SAndroid Build Coastguard Worker 
68*6236dae4SAndroid Build Coastguard Worker   if(len > 255)
69*6236dae4SAndroid Build Coastguard Worker     len = 255;
70*6236dae4SAndroid Build Coastguard Worker 
71*6236dae4SAndroid Build Coastguard Worker   for(i = 0; i < len; i++) {
72*6236dae4SAndroid Build Coastguard Worker     if((data[i] >= 0x20) && (data[i] < 0x7f))
73*6236dae4SAndroid Build Coastguard Worker       *optr++ = *iptr++;
74*6236dae4SAndroid Build Coastguard Worker     else {
75*6236dae4SAndroid Build Coastguard Worker       msnprintf(optr, 4, "%%%02x", *iptr++);
76*6236dae4SAndroid Build Coastguard Worker       optr += 3;
77*6236dae4SAndroid Build Coastguard Worker     }
78*6236dae4SAndroid Build Coastguard Worker   }
79*6236dae4SAndroid Build Coastguard Worker   *optr = 0; /* in case no sprintf was used */
80*6236dae4SAndroid Build Coastguard Worker 
81*6236dae4SAndroid Build Coastguard Worker   return buf;
82*6236dae4SAndroid Build Coastguard Worker }
83*6236dae4SAndroid Build Coastguard Worker 
logmsg(const char * msg,...)84*6236dae4SAndroid Build Coastguard Worker void logmsg(const char *msg, ...)
85*6236dae4SAndroid Build Coastguard Worker {
86*6236dae4SAndroid Build Coastguard Worker   va_list ap;
87*6236dae4SAndroid Build Coastguard Worker   char buffer[2048 + 1];
88*6236dae4SAndroid Build Coastguard Worker   FILE *logfp;
89*6236dae4SAndroid Build Coastguard Worker   struct timeval tv;
90*6236dae4SAndroid Build Coastguard Worker   time_t sec;
91*6236dae4SAndroid Build Coastguard Worker   struct tm *now;
92*6236dae4SAndroid Build Coastguard Worker   char timebuf[20];
93*6236dae4SAndroid Build Coastguard Worker   static time_t epoch_offset;
94*6236dae4SAndroid Build Coastguard Worker   static int    known_offset;
95*6236dae4SAndroid Build Coastguard Worker 
96*6236dae4SAndroid Build Coastguard Worker   if(!serverlogfile) {
97*6236dae4SAndroid Build Coastguard Worker     fprintf(stderr, "Error: serverlogfile not set\n");
98*6236dae4SAndroid Build Coastguard Worker     return;
99*6236dae4SAndroid Build Coastguard Worker   }
100*6236dae4SAndroid Build Coastguard Worker 
101*6236dae4SAndroid Build Coastguard Worker   tv = tvnow();
102*6236dae4SAndroid Build Coastguard Worker   if(!known_offset) {
103*6236dae4SAndroid Build Coastguard Worker     epoch_offset = time(NULL) - tv.tv_sec;
104*6236dae4SAndroid Build Coastguard Worker     known_offset = 1;
105*6236dae4SAndroid Build Coastguard Worker   }
106*6236dae4SAndroid Build Coastguard Worker   sec = epoch_offset + tv.tv_sec;
107*6236dae4SAndroid Build Coastguard Worker   /* !checksrc! disable BANNEDFUNC 1 */
108*6236dae4SAndroid Build Coastguard Worker   now = localtime(&sec); /* not thread safe but we don't care */
109*6236dae4SAndroid Build Coastguard Worker 
110*6236dae4SAndroid Build Coastguard Worker   msnprintf(timebuf, sizeof(timebuf), "%02d:%02d:%02d.%06ld",
111*6236dae4SAndroid Build Coastguard Worker             (int)now->tm_hour, (int)now->tm_min, (int)now->tm_sec,
112*6236dae4SAndroid Build Coastguard Worker             (long)tv.tv_usec);
113*6236dae4SAndroid Build Coastguard Worker 
114*6236dae4SAndroid Build Coastguard Worker   va_start(ap, msg);
115*6236dae4SAndroid Build Coastguard Worker   mvsnprintf(buffer, sizeof(buffer), msg, ap);
116*6236dae4SAndroid Build Coastguard Worker   va_end(ap);
117*6236dae4SAndroid Build Coastguard Worker 
118*6236dae4SAndroid Build Coastguard Worker   do {
119*6236dae4SAndroid Build Coastguard Worker     logfp = fopen(serverlogfile, "ab");
120*6236dae4SAndroid Build Coastguard Worker   } while(!logfp && (errno == EINTR));
121*6236dae4SAndroid Build Coastguard Worker   if(logfp) {
122*6236dae4SAndroid Build Coastguard Worker     fprintf(logfp, "%s %s\n", timebuf, buffer);
123*6236dae4SAndroid Build Coastguard Worker     fclose(logfp);
124*6236dae4SAndroid Build Coastguard Worker   }
125*6236dae4SAndroid Build Coastguard Worker   else {
126*6236dae4SAndroid Build Coastguard Worker     int error = errno;
127*6236dae4SAndroid Build Coastguard Worker     fprintf(stderr, "fopen() failed with error: %d %s\n",
128*6236dae4SAndroid Build Coastguard Worker             error, strerror(error));
129*6236dae4SAndroid Build Coastguard Worker     fprintf(stderr, "Error opening file: %s\n", serverlogfile);
130*6236dae4SAndroid Build Coastguard Worker     fprintf(stderr, "Msg not logged: %s %s\n", timebuf, buffer);
131*6236dae4SAndroid Build Coastguard Worker   }
132*6236dae4SAndroid Build Coastguard Worker }
133*6236dae4SAndroid Build Coastguard Worker 
134*6236dae4SAndroid Build Coastguard Worker #ifdef _WIN32
135*6236dae4SAndroid Build Coastguard Worker /* use instead of strerror() on generic Windows */
win32_strerror(int err,char * buf,size_t buflen)136*6236dae4SAndroid Build Coastguard Worker static const char *win32_strerror(int err, char *buf, size_t buflen)
137*6236dae4SAndroid Build Coastguard Worker {
138*6236dae4SAndroid Build Coastguard Worker   if(!FormatMessageA((FORMAT_MESSAGE_FROM_SYSTEM |
139*6236dae4SAndroid Build Coastguard Worker                       FORMAT_MESSAGE_IGNORE_INSERTS), NULL, (DWORD)err,
140*6236dae4SAndroid Build Coastguard Worker                      LANG_NEUTRAL, buf, (DWORD)buflen, NULL))
141*6236dae4SAndroid Build Coastguard Worker     msnprintf(buf, buflen, "Unknown error %d (%#x)", err, err);
142*6236dae4SAndroid Build Coastguard Worker   return buf;
143*6236dae4SAndroid Build Coastguard Worker }
144*6236dae4SAndroid Build Coastguard Worker 
145*6236dae4SAndroid Build Coastguard Worker /* use instead of perror() on generic Windows */
win32_perror(const char * msg)146*6236dae4SAndroid Build Coastguard Worker void win32_perror(const char *msg)
147*6236dae4SAndroid Build Coastguard Worker {
148*6236dae4SAndroid Build Coastguard Worker   char buf[512];
149*6236dae4SAndroid Build Coastguard Worker   int err = SOCKERRNO;
150*6236dae4SAndroid Build Coastguard Worker   win32_strerror(err, buf, sizeof(buf));
151*6236dae4SAndroid Build Coastguard Worker   if(msg)
152*6236dae4SAndroid Build Coastguard Worker     fprintf(stderr, "%s: ", msg);
153*6236dae4SAndroid Build Coastguard Worker   fprintf(stderr, "%s\n", buf);
154*6236dae4SAndroid Build Coastguard Worker }
155*6236dae4SAndroid Build Coastguard Worker 
win32_init(void)156*6236dae4SAndroid Build Coastguard Worker void win32_init(void)
157*6236dae4SAndroid Build Coastguard Worker {
158*6236dae4SAndroid Build Coastguard Worker #ifdef USE_WINSOCK
159*6236dae4SAndroid Build Coastguard Worker   WORD wVersionRequested;
160*6236dae4SAndroid Build Coastguard Worker   WSADATA wsaData;
161*6236dae4SAndroid Build Coastguard Worker   int err;
162*6236dae4SAndroid Build Coastguard Worker 
163*6236dae4SAndroid Build Coastguard Worker   wVersionRequested = MAKEWORD(2, 2);
164*6236dae4SAndroid Build Coastguard Worker   err = WSAStartup(wVersionRequested, &wsaData);
165*6236dae4SAndroid Build Coastguard Worker 
166*6236dae4SAndroid Build Coastguard Worker   if(err) {
167*6236dae4SAndroid Build Coastguard Worker     perror("Winsock init failed");
168*6236dae4SAndroid Build Coastguard Worker     logmsg("Error initialising Winsock -- aborting");
169*6236dae4SAndroid Build Coastguard Worker     exit(1);
170*6236dae4SAndroid Build Coastguard Worker   }
171*6236dae4SAndroid Build Coastguard Worker 
172*6236dae4SAndroid Build Coastguard Worker   if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) ||
173*6236dae4SAndroid Build Coastguard Worker      HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested) ) {
174*6236dae4SAndroid Build Coastguard Worker     WSACleanup();
175*6236dae4SAndroid Build Coastguard Worker     perror("Winsock init failed");
176*6236dae4SAndroid Build Coastguard Worker     logmsg("No suitable winsock.dll found -- aborting");
177*6236dae4SAndroid Build Coastguard Worker     exit(1);
178*6236dae4SAndroid Build Coastguard Worker   }
179*6236dae4SAndroid Build Coastguard Worker #endif  /* USE_WINSOCK */
180*6236dae4SAndroid Build Coastguard Worker }
181*6236dae4SAndroid Build Coastguard Worker 
win32_cleanup(void)182*6236dae4SAndroid Build Coastguard Worker void win32_cleanup(void)
183*6236dae4SAndroid Build Coastguard Worker {
184*6236dae4SAndroid Build Coastguard Worker #ifdef USE_WINSOCK
185*6236dae4SAndroid Build Coastguard Worker   WSACleanup();
186*6236dae4SAndroid Build Coastguard Worker #endif  /* USE_WINSOCK */
187*6236dae4SAndroid Build Coastguard Worker 
188*6236dae4SAndroid Build Coastguard Worker   /* flush buffers of all streams regardless of their mode */
189*6236dae4SAndroid Build Coastguard Worker   _flushall();
190*6236dae4SAndroid Build Coastguard Worker }
191*6236dae4SAndroid Build Coastguard Worker 
192*6236dae4SAndroid Build Coastguard Worker /* socket-safe strerror (works on Winsock errors, too */
sstrerror(int err)193*6236dae4SAndroid Build Coastguard Worker const char *sstrerror(int err)
194*6236dae4SAndroid Build Coastguard Worker {
195*6236dae4SAndroid Build Coastguard Worker   static char buf[512];
196*6236dae4SAndroid Build Coastguard Worker   return win32_strerror(err, buf, sizeof(buf));
197*6236dae4SAndroid Build Coastguard Worker }
198*6236dae4SAndroid Build Coastguard Worker #endif  /* _WIN32 */
199*6236dae4SAndroid Build Coastguard Worker 
200*6236dae4SAndroid Build Coastguard Worker /* set by the main code to point to where the test dir is */
201*6236dae4SAndroid Build Coastguard Worker const char *path = ".";
202*6236dae4SAndroid Build Coastguard Worker 
test2fopen(long testno,const char * logdir)203*6236dae4SAndroid Build Coastguard Worker FILE *test2fopen(long testno, const char *logdir)
204*6236dae4SAndroid Build Coastguard Worker {
205*6236dae4SAndroid Build Coastguard Worker   FILE *stream;
206*6236dae4SAndroid Build Coastguard Worker   char filename[256];
207*6236dae4SAndroid Build Coastguard Worker   /* first try the alternative, preprocessed, file */
208*6236dae4SAndroid Build Coastguard Worker   msnprintf(filename, sizeof(filename), ALTTEST_DATA_PATH, logdir, testno);
209*6236dae4SAndroid Build Coastguard Worker   stream = fopen(filename, "rb");
210*6236dae4SAndroid Build Coastguard Worker   if(stream)
211*6236dae4SAndroid Build Coastguard Worker     return stream;
212*6236dae4SAndroid Build Coastguard Worker 
213*6236dae4SAndroid Build Coastguard Worker   /* then try the source version */
214*6236dae4SAndroid Build Coastguard Worker   msnprintf(filename, sizeof(filename), TEST_DATA_PATH, path, testno);
215*6236dae4SAndroid Build Coastguard Worker   stream = fopen(filename, "rb");
216*6236dae4SAndroid Build Coastguard Worker 
217*6236dae4SAndroid Build Coastguard Worker   return stream;
218*6236dae4SAndroid Build Coastguard Worker }
219*6236dae4SAndroid Build Coastguard Worker 
220*6236dae4SAndroid Build Coastguard Worker /*
221*6236dae4SAndroid Build Coastguard Worker  * Portable function used for waiting a specific amount of ms.
222*6236dae4SAndroid Build Coastguard Worker  * Waiting indefinitely with this function is not allowed, a
223*6236dae4SAndroid Build Coastguard Worker  * zero or negative timeout value will return immediately.
224*6236dae4SAndroid Build Coastguard Worker  *
225*6236dae4SAndroid Build Coastguard Worker  * Return values:
226*6236dae4SAndroid Build Coastguard Worker  *   -1 = system call error, or invalid timeout value
227*6236dae4SAndroid Build Coastguard Worker  *    0 = specified timeout has elapsed
228*6236dae4SAndroid Build Coastguard Worker  */
wait_ms(int timeout_ms)229*6236dae4SAndroid Build Coastguard Worker int wait_ms(int timeout_ms)
230*6236dae4SAndroid Build Coastguard Worker {
231*6236dae4SAndroid Build Coastguard Worker #if !defined(MSDOS) && !defined(USE_WINSOCK)
232*6236dae4SAndroid Build Coastguard Worker #ifndef HAVE_POLL
233*6236dae4SAndroid Build Coastguard Worker   struct timeval pending_tv;
234*6236dae4SAndroid Build Coastguard Worker #endif
235*6236dae4SAndroid Build Coastguard Worker   struct timeval initial_tv;
236*6236dae4SAndroid Build Coastguard Worker   int pending_ms;
237*6236dae4SAndroid Build Coastguard Worker #endif
238*6236dae4SAndroid Build Coastguard Worker   int r = 0;
239*6236dae4SAndroid Build Coastguard Worker 
240*6236dae4SAndroid Build Coastguard Worker   if(!timeout_ms)
241*6236dae4SAndroid Build Coastguard Worker     return 0;
242*6236dae4SAndroid Build Coastguard Worker   if(timeout_ms < 0) {
243*6236dae4SAndroid Build Coastguard Worker     errno = EINVAL;
244*6236dae4SAndroid Build Coastguard Worker     return -1;
245*6236dae4SAndroid Build Coastguard Worker   }
246*6236dae4SAndroid Build Coastguard Worker #if defined(MSDOS)
247*6236dae4SAndroid Build Coastguard Worker   delay(timeout_ms);
248*6236dae4SAndroid Build Coastguard Worker #elif defined(USE_WINSOCK)
249*6236dae4SAndroid Build Coastguard Worker   Sleep((DWORD)timeout_ms);
250*6236dae4SAndroid Build Coastguard Worker #else
251*6236dae4SAndroid Build Coastguard Worker   pending_ms = timeout_ms;
252*6236dae4SAndroid Build Coastguard Worker   initial_tv = tvnow();
253*6236dae4SAndroid Build Coastguard Worker   do {
254*6236dae4SAndroid Build Coastguard Worker     int error;
255*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_POLL
256*6236dae4SAndroid Build Coastguard Worker     r = poll(NULL, 0, pending_ms);
257*6236dae4SAndroid Build Coastguard Worker #else
258*6236dae4SAndroid Build Coastguard Worker     pending_tv.tv_sec = pending_ms / 1000;
259*6236dae4SAndroid Build Coastguard Worker     pending_tv.tv_usec = (pending_ms % 1000) * 1000;
260*6236dae4SAndroid Build Coastguard Worker     r = select(0, NULL, NULL, NULL, &pending_tv);
261*6236dae4SAndroid Build Coastguard Worker #endif /* HAVE_POLL */
262*6236dae4SAndroid Build Coastguard Worker     if(r != -1)
263*6236dae4SAndroid Build Coastguard Worker       break;
264*6236dae4SAndroid Build Coastguard Worker     error = errno;
265*6236dae4SAndroid Build Coastguard Worker     if(error && (error != EINTR))
266*6236dae4SAndroid Build Coastguard Worker       break;
267*6236dae4SAndroid Build Coastguard Worker     pending_ms = timeout_ms - (int)timediff(tvnow(), initial_tv);
268*6236dae4SAndroid Build Coastguard Worker     if(pending_ms <= 0)
269*6236dae4SAndroid Build Coastguard Worker       break;
270*6236dae4SAndroid Build Coastguard Worker   } while(r == -1);
271*6236dae4SAndroid Build Coastguard Worker #endif /* USE_WINSOCK */
272*6236dae4SAndroid Build Coastguard Worker   if(r)
273*6236dae4SAndroid Build Coastguard Worker     r = -1;
274*6236dae4SAndroid Build Coastguard Worker   return r;
275*6236dae4SAndroid Build Coastguard Worker }
276*6236dae4SAndroid Build Coastguard Worker 
our_getpid(void)277*6236dae4SAndroid Build Coastguard Worker curl_off_t our_getpid(void)
278*6236dae4SAndroid Build Coastguard Worker {
279*6236dae4SAndroid Build Coastguard Worker   curl_off_t pid;
280*6236dae4SAndroid Build Coastguard Worker 
281*6236dae4SAndroid Build Coastguard Worker   pid = (curl_off_t)getpid();
282*6236dae4SAndroid Build Coastguard Worker #if defined(_WIN32)
283*6236dae4SAndroid Build Coastguard Worker   /* store pid + 65536 to avoid conflict with Cygwin/msys PIDs, see also:
284*6236dae4SAndroid Build Coastguard Worker    * - https://cygwin.com/git/?p=newlib-cygwin.git;a=commit;285*6236dae4SAndroid Build Coastguard Worker    *   h=b5e1003722cb14235c4f166be72c09acdffc62ea
286*6236dae4SAndroid Build Coastguard Worker    * - https://cygwin.com/git/?p=newlib-cygwin.git;a=commit;287*6236dae4SAndroid Build Coastguard Worker    *   h=448cf5aa4b429d5a9cebf92a0da4ab4b5b6d23fe
288*6236dae4SAndroid Build Coastguard Worker    */
289*6236dae4SAndroid Build Coastguard Worker   pid += 65536;
290*6236dae4SAndroid Build Coastguard Worker #endif
291*6236dae4SAndroid Build Coastguard Worker   return pid;
292*6236dae4SAndroid Build Coastguard Worker }
293*6236dae4SAndroid Build Coastguard Worker 
write_pidfile(const char * filename)294*6236dae4SAndroid Build Coastguard Worker int write_pidfile(const char *filename)
295*6236dae4SAndroid Build Coastguard Worker {
296*6236dae4SAndroid Build Coastguard Worker   FILE *pidfile;
297*6236dae4SAndroid Build Coastguard Worker   curl_off_t pid;
298*6236dae4SAndroid Build Coastguard Worker 
299*6236dae4SAndroid Build Coastguard Worker   pid = our_getpid();
300*6236dae4SAndroid Build Coastguard Worker   pidfile = fopen(filename, "wb");
301*6236dae4SAndroid Build Coastguard Worker   if(!pidfile) {
302*6236dae4SAndroid Build Coastguard Worker     logmsg("Couldn't write pid file: %s %s", filename, strerror(errno));
303*6236dae4SAndroid Build Coastguard Worker     return 0; /* fail */
304*6236dae4SAndroid Build Coastguard Worker   }
305*6236dae4SAndroid Build Coastguard Worker   fprintf(pidfile, "%" CURL_FORMAT_CURL_OFF_T "\n", pid);
306*6236dae4SAndroid Build Coastguard Worker   fclose(pidfile);
307*6236dae4SAndroid Build Coastguard Worker   logmsg("Wrote pid %" CURL_FORMAT_CURL_OFF_T " to %s", pid, filename);
308*6236dae4SAndroid Build Coastguard Worker   return 1; /* success */
309*6236dae4SAndroid Build Coastguard Worker }
310*6236dae4SAndroid Build Coastguard Worker 
311*6236dae4SAndroid Build Coastguard Worker /* store the used port number in a file */
write_portfile(const char * filename,int port)312*6236dae4SAndroid Build Coastguard Worker int write_portfile(const char *filename, int port)
313*6236dae4SAndroid Build Coastguard Worker {
314*6236dae4SAndroid Build Coastguard Worker   FILE *portfile = fopen(filename, "wb");
315*6236dae4SAndroid Build Coastguard Worker   if(!portfile) {
316*6236dae4SAndroid Build Coastguard Worker     logmsg("Couldn't write port file: %s %s", filename, strerror(errno));
317*6236dae4SAndroid Build Coastguard Worker     return 0; /* fail */
318*6236dae4SAndroid Build Coastguard Worker   }
319*6236dae4SAndroid Build Coastguard Worker   fprintf(portfile, "%d\n", port);
320*6236dae4SAndroid Build Coastguard Worker   fclose(portfile);
321*6236dae4SAndroid Build Coastguard Worker   logmsg("Wrote port %d to %s", port, filename);
322*6236dae4SAndroid Build Coastguard Worker   return 1; /* success */
323*6236dae4SAndroid Build Coastguard Worker }
324*6236dae4SAndroid Build Coastguard Worker 
set_advisor_read_lock(const char * filename)325*6236dae4SAndroid Build Coastguard Worker void set_advisor_read_lock(const char *filename)
326*6236dae4SAndroid Build Coastguard Worker {
327*6236dae4SAndroid Build Coastguard Worker   FILE *lockfile;
328*6236dae4SAndroid Build Coastguard Worker   int error = 0;
329*6236dae4SAndroid Build Coastguard Worker   int res;
330*6236dae4SAndroid Build Coastguard Worker 
331*6236dae4SAndroid Build Coastguard Worker   do {
332*6236dae4SAndroid Build Coastguard Worker     lockfile = fopen(filename, "wb");
333*6236dae4SAndroid Build Coastguard Worker   } while(!lockfile && ((error = errno) == EINTR));
334*6236dae4SAndroid Build Coastguard Worker   if(!lockfile) {
335*6236dae4SAndroid Build Coastguard Worker     logmsg("Error creating lock file %s error: %d %s",
336*6236dae4SAndroid Build Coastguard Worker            filename, error, strerror(error));
337*6236dae4SAndroid Build Coastguard Worker     return;
338*6236dae4SAndroid Build Coastguard Worker   }
339*6236dae4SAndroid Build Coastguard Worker 
340*6236dae4SAndroid Build Coastguard Worker   do {
341*6236dae4SAndroid Build Coastguard Worker     res = fclose(lockfile);
342*6236dae4SAndroid Build Coastguard Worker   } while(res && ((error = errno) == EINTR));
343*6236dae4SAndroid Build Coastguard Worker   if(res)
344*6236dae4SAndroid Build Coastguard Worker     logmsg("Error closing lock file %s error: %d %s",
345*6236dae4SAndroid Build Coastguard Worker            filename, error, strerror(error));
346*6236dae4SAndroid Build Coastguard Worker }
347*6236dae4SAndroid Build Coastguard Worker 
clear_advisor_read_lock(const char * filename)348*6236dae4SAndroid Build Coastguard Worker void clear_advisor_read_lock(const char *filename)
349*6236dae4SAndroid Build Coastguard Worker {
350*6236dae4SAndroid Build Coastguard Worker   int error = 0;
351*6236dae4SAndroid Build Coastguard Worker   int res;
352*6236dae4SAndroid Build Coastguard Worker 
353*6236dae4SAndroid Build Coastguard Worker   /*
354*6236dae4SAndroid Build Coastguard Worker   ** Log all removal failures. Even those due to file not existing.
355*6236dae4SAndroid Build Coastguard Worker   ** This allows to detect if unexpectedly the file has already been
356*6236dae4SAndroid Build Coastguard Worker   ** removed by a process different than the one that should do this.
357*6236dae4SAndroid Build Coastguard Worker   */
358*6236dae4SAndroid Build Coastguard Worker 
359*6236dae4SAndroid Build Coastguard Worker   do {
360*6236dae4SAndroid Build Coastguard Worker     res = unlink(filename);
361*6236dae4SAndroid Build Coastguard Worker   } while(res && ((error = errno) == EINTR));
362*6236dae4SAndroid Build Coastguard Worker   if(res)
363*6236dae4SAndroid Build Coastguard Worker     logmsg("Error removing lock file %s error: %d %s",
364*6236dae4SAndroid Build Coastguard Worker            filename, error, strerror(error));
365*6236dae4SAndroid Build Coastguard Worker }
366*6236dae4SAndroid Build Coastguard Worker 
367*6236dae4SAndroid Build Coastguard Worker 
368*6236dae4SAndroid Build Coastguard Worker #if defined(_WIN32)
369*6236dae4SAndroid Build Coastguard Worker 
tvnow(void)370*6236dae4SAndroid Build Coastguard Worker static struct timeval tvnow(void)
371*6236dae4SAndroid Build Coastguard Worker {
372*6236dae4SAndroid Build Coastguard Worker   /*
373*6236dae4SAndroid Build Coastguard Worker   ** GetTickCount() is available on _all_ Windows versions from W95 up
374*6236dae4SAndroid Build Coastguard Worker   ** to nowadays. Returns milliseconds elapsed since last system boot,
375*6236dae4SAndroid Build Coastguard Worker   ** increases monotonically and wraps once 49.7 days have elapsed.
376*6236dae4SAndroid Build Coastguard Worker   **
377*6236dae4SAndroid Build Coastguard Worker   ** GetTickCount64() is available on Windows version from Windows Vista
378*6236dae4SAndroid Build Coastguard Worker   ** and Windows Server 2008 up to nowadays. The resolution of the
379*6236dae4SAndroid Build Coastguard Worker   ** function is limited to the resolution of the system timer, which
380*6236dae4SAndroid Build Coastguard Worker   ** is typically in the range of 10 milliseconds to 16 milliseconds.
381*6236dae4SAndroid Build Coastguard Worker   */
382*6236dae4SAndroid Build Coastguard Worker   struct timeval now;
383*6236dae4SAndroid Build Coastguard Worker #if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)
384*6236dae4SAndroid Build Coastguard Worker   ULONGLONG milliseconds = GetTickCount64();
385*6236dae4SAndroid Build Coastguard Worker #else
386*6236dae4SAndroid Build Coastguard Worker   DWORD milliseconds = GetTickCount();
387*6236dae4SAndroid Build Coastguard Worker #endif
388*6236dae4SAndroid Build Coastguard Worker   now.tv_sec = (long)(milliseconds / 1000);
389*6236dae4SAndroid Build Coastguard Worker   now.tv_usec = (long)((milliseconds % 1000) * 1000);
390*6236dae4SAndroid Build Coastguard Worker   return now;
391*6236dae4SAndroid Build Coastguard Worker }
392*6236dae4SAndroid Build Coastguard Worker 
393*6236dae4SAndroid Build Coastguard Worker #elif defined(HAVE_CLOCK_GETTIME_MONOTONIC)
394*6236dae4SAndroid Build Coastguard Worker 
tvnow(void)395*6236dae4SAndroid Build Coastguard Worker static struct timeval tvnow(void)
396*6236dae4SAndroid Build Coastguard Worker {
397*6236dae4SAndroid Build Coastguard Worker   /*
398*6236dae4SAndroid Build Coastguard Worker   ** clock_gettime() is granted to be increased monotonically when the
399*6236dae4SAndroid Build Coastguard Worker   ** monotonic clock is queried. Time starting point is unspecified, it
400*6236dae4SAndroid Build Coastguard Worker   ** could be the system start-up time, the Epoch, or something else,
401*6236dae4SAndroid Build Coastguard Worker   ** in any case the time starting point does not change once that the
402*6236dae4SAndroid Build Coastguard Worker   ** system has started up.
403*6236dae4SAndroid Build Coastguard Worker   */
404*6236dae4SAndroid Build Coastguard Worker   struct timeval now;
405*6236dae4SAndroid Build Coastguard Worker   struct timespec tsnow;
406*6236dae4SAndroid Build Coastguard Worker   if(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) {
407*6236dae4SAndroid Build Coastguard Worker     now.tv_sec = tsnow.tv_sec;
408*6236dae4SAndroid Build Coastguard Worker     now.tv_usec = (int)(tsnow.tv_nsec / 1000);
409*6236dae4SAndroid Build Coastguard Worker   }
410*6236dae4SAndroid Build Coastguard Worker   /*
411*6236dae4SAndroid Build Coastguard Worker   ** Even when the configure process has truly detected monotonic clock
412*6236dae4SAndroid Build Coastguard Worker   ** availability, it might happen that it is not actually available at
413*6236dae4SAndroid Build Coastguard Worker   ** run-time. When this occurs simply fallback to other time source.
414*6236dae4SAndroid Build Coastguard Worker   */
415*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_GETTIMEOFDAY
416*6236dae4SAndroid Build Coastguard Worker   else
417*6236dae4SAndroid Build Coastguard Worker     (void)gettimeofday(&now, NULL);
418*6236dae4SAndroid Build Coastguard Worker #else
419*6236dae4SAndroid Build Coastguard Worker   else {
420*6236dae4SAndroid Build Coastguard Worker     now.tv_sec = time(NULL);
421*6236dae4SAndroid Build Coastguard Worker     now.tv_usec = 0;
422*6236dae4SAndroid Build Coastguard Worker   }
423*6236dae4SAndroid Build Coastguard Worker #endif
424*6236dae4SAndroid Build Coastguard Worker   return now;
425*6236dae4SAndroid Build Coastguard Worker }
426*6236dae4SAndroid Build Coastguard Worker 
427*6236dae4SAndroid Build Coastguard Worker #elif defined(HAVE_GETTIMEOFDAY)
428*6236dae4SAndroid Build Coastguard Worker 
tvnow(void)429*6236dae4SAndroid Build Coastguard Worker static struct timeval tvnow(void)
430*6236dae4SAndroid Build Coastguard Worker {
431*6236dae4SAndroid Build Coastguard Worker   /*
432*6236dae4SAndroid Build Coastguard Worker   ** gettimeofday() is not granted to be increased monotonically, due to
433*6236dae4SAndroid Build Coastguard Worker   ** clock drifting and external source time synchronization it can jump
434*6236dae4SAndroid Build Coastguard Worker   ** forward or backward in time.
435*6236dae4SAndroid Build Coastguard Worker   */
436*6236dae4SAndroid Build Coastguard Worker   struct timeval now;
437*6236dae4SAndroid Build Coastguard Worker   (void)gettimeofday(&now, NULL);
438*6236dae4SAndroid Build Coastguard Worker   return now;
439*6236dae4SAndroid Build Coastguard Worker }
440*6236dae4SAndroid Build Coastguard Worker 
441*6236dae4SAndroid Build Coastguard Worker #else
442*6236dae4SAndroid Build Coastguard Worker 
tvnow(void)443*6236dae4SAndroid Build Coastguard Worker static struct timeval tvnow(void)
444*6236dae4SAndroid Build Coastguard Worker {
445*6236dae4SAndroid Build Coastguard Worker   /*
446*6236dae4SAndroid Build Coastguard Worker   ** time() returns the value of time in seconds since the Epoch.
447*6236dae4SAndroid Build Coastguard Worker   */
448*6236dae4SAndroid Build Coastguard Worker   struct timeval now;
449*6236dae4SAndroid Build Coastguard Worker   now.tv_sec = time(NULL);
450*6236dae4SAndroid Build Coastguard Worker   now.tv_usec = 0;
451*6236dae4SAndroid Build Coastguard Worker   return now;
452*6236dae4SAndroid Build Coastguard Worker }
453*6236dae4SAndroid Build Coastguard Worker 
454*6236dae4SAndroid Build Coastguard Worker #endif
455*6236dae4SAndroid Build Coastguard Worker 
timediff(struct timeval newer,struct timeval older)456*6236dae4SAndroid Build Coastguard Worker long timediff(struct timeval newer, struct timeval older)
457*6236dae4SAndroid Build Coastguard Worker {
458*6236dae4SAndroid Build Coastguard Worker   timediff_t diff = newer.tv_sec-older.tv_sec;
459*6236dae4SAndroid Build Coastguard Worker   if(diff >= (LONG_MAX/1000))
460*6236dae4SAndroid Build Coastguard Worker     return LONG_MAX;
461*6236dae4SAndroid Build Coastguard Worker   else if(diff <= (LONG_MIN/1000))
462*6236dae4SAndroid Build Coastguard Worker     return LONG_MIN;
463*6236dae4SAndroid Build Coastguard Worker   return (long)(newer.tv_sec-older.tv_sec)*1000+
464*6236dae4SAndroid Build Coastguard Worker     (long)(newer.tv_usec-older.tv_usec)/1000;
465*6236dae4SAndroid Build Coastguard Worker }
466*6236dae4SAndroid Build Coastguard Worker 
467*6236dae4SAndroid Build Coastguard Worker /* vars used to keep around previous signal handlers */
468*6236dae4SAndroid Build Coastguard Worker 
469*6236dae4SAndroid Build Coastguard Worker typedef void (*SIGHANDLER_T)(int);
470*6236dae4SAndroid Build Coastguard Worker 
471*6236dae4SAndroid Build Coastguard Worker #if defined(_MSC_VER) && _MSC_VER == 1600
472*6236dae4SAndroid Build Coastguard Worker /* Workaround for warning C4306:
473*6236dae4SAndroid Build Coastguard Worker    'type cast' : conversion from 'int' to 'void (__cdecl *)(int)' */
474*6236dae4SAndroid Build Coastguard Worker #undef SIG_ERR
475*6236dae4SAndroid Build Coastguard Worker #define SIG_ERR  ((SIGHANDLER_T)(size_t)-1)
476*6236dae4SAndroid Build Coastguard Worker #endif
477*6236dae4SAndroid Build Coastguard Worker 
478*6236dae4SAndroid Build Coastguard Worker #ifdef SIGHUP
479*6236dae4SAndroid Build Coastguard Worker static SIGHANDLER_T old_sighup_handler  = SIG_ERR;
480*6236dae4SAndroid Build Coastguard Worker #endif
481*6236dae4SAndroid Build Coastguard Worker 
482*6236dae4SAndroid Build Coastguard Worker #ifdef SIGPIPE
483*6236dae4SAndroid Build Coastguard Worker static SIGHANDLER_T old_sigpipe_handler = SIG_ERR;
484*6236dae4SAndroid Build Coastguard Worker #endif
485*6236dae4SAndroid Build Coastguard Worker 
486*6236dae4SAndroid Build Coastguard Worker #ifdef SIGALRM
487*6236dae4SAndroid Build Coastguard Worker static SIGHANDLER_T old_sigalrm_handler = SIG_ERR;
488*6236dae4SAndroid Build Coastguard Worker #endif
489*6236dae4SAndroid Build Coastguard Worker 
490*6236dae4SAndroid Build Coastguard Worker #ifdef SIGINT
491*6236dae4SAndroid Build Coastguard Worker static SIGHANDLER_T old_sigint_handler  = SIG_ERR;
492*6236dae4SAndroid Build Coastguard Worker #endif
493*6236dae4SAndroid Build Coastguard Worker 
494*6236dae4SAndroid Build Coastguard Worker #ifdef SIGTERM
495*6236dae4SAndroid Build Coastguard Worker static SIGHANDLER_T old_sigterm_handler = SIG_ERR;
496*6236dae4SAndroid Build Coastguard Worker #endif
497*6236dae4SAndroid Build Coastguard Worker 
498*6236dae4SAndroid Build Coastguard Worker #if defined(SIGBREAK) && defined(_WIN32)
499*6236dae4SAndroid Build Coastguard Worker static SIGHANDLER_T old_sigbreak_handler = SIG_ERR;
500*6236dae4SAndroid Build Coastguard Worker #endif
501*6236dae4SAndroid Build Coastguard Worker 
502*6236dae4SAndroid Build Coastguard Worker #if defined(_WIN32) && !defined(CURL_WINDOWS_UWP)
503*6236dae4SAndroid Build Coastguard Worker #ifdef _WIN32_WCE
504*6236dae4SAndroid Build Coastguard Worker static DWORD thread_main_id = 0;
505*6236dae4SAndroid Build Coastguard Worker #else
506*6236dae4SAndroid Build Coastguard Worker static unsigned int thread_main_id = 0;
507*6236dae4SAndroid Build Coastguard Worker #endif
508*6236dae4SAndroid Build Coastguard Worker static HANDLE thread_main_window = NULL;
509*6236dae4SAndroid Build Coastguard Worker static HWND hidden_main_window = NULL;
510*6236dae4SAndroid Build Coastguard Worker #endif
511*6236dae4SAndroid Build Coastguard Worker 
512*6236dae4SAndroid Build Coastguard Worker /* var which if set indicates that the program should finish execution */
513*6236dae4SAndroid Build Coastguard Worker volatile int got_exit_signal = 0;
514*6236dae4SAndroid Build Coastguard Worker 
515*6236dae4SAndroid Build Coastguard Worker /* if next is set indicates the first signal handled in exit_signal_handler */
516*6236dae4SAndroid Build Coastguard Worker volatile int exit_signal = 0;
517*6236dae4SAndroid Build Coastguard Worker 
518*6236dae4SAndroid Build Coastguard Worker #ifdef _WIN32
519*6236dae4SAndroid Build Coastguard Worker /* event which if set indicates that the program should finish */
520*6236dae4SAndroid Build Coastguard Worker HANDLE exit_event = NULL;
521*6236dae4SAndroid Build Coastguard Worker #endif
522*6236dae4SAndroid Build Coastguard Worker 
523*6236dae4SAndroid Build Coastguard Worker /* signal handler that will be triggered to indicate that the program
524*6236dae4SAndroid Build Coastguard Worker  * should finish its execution in a controlled manner as soon as possible.
525*6236dae4SAndroid Build Coastguard Worker  * The first time this is called it will set got_exit_signal to one and
526*6236dae4SAndroid Build Coastguard Worker  * store in exit_signal the signal that triggered its execution.
527*6236dae4SAndroid Build Coastguard Worker  */
exit_signal_handler(int signum)528*6236dae4SAndroid Build Coastguard Worker static void exit_signal_handler(int signum)
529*6236dae4SAndroid Build Coastguard Worker {
530*6236dae4SAndroid Build Coastguard Worker   int old_errno = errno;
531*6236dae4SAndroid Build Coastguard Worker   logmsg("exit_signal_handler: %d", signum);
532*6236dae4SAndroid Build Coastguard Worker   if(got_exit_signal == 0) {
533*6236dae4SAndroid Build Coastguard Worker     got_exit_signal = 1;
534*6236dae4SAndroid Build Coastguard Worker     exit_signal = signum;
535*6236dae4SAndroid Build Coastguard Worker #ifdef _WIN32
536*6236dae4SAndroid Build Coastguard Worker     if(exit_event)
537*6236dae4SAndroid Build Coastguard Worker       (void)SetEvent(exit_event);
538*6236dae4SAndroid Build Coastguard Worker #endif
539*6236dae4SAndroid Build Coastguard Worker   }
540*6236dae4SAndroid Build Coastguard Worker   (void)signal(signum, exit_signal_handler);
541*6236dae4SAndroid Build Coastguard Worker   errno = old_errno;
542*6236dae4SAndroid Build Coastguard Worker }
543*6236dae4SAndroid Build Coastguard Worker 
544*6236dae4SAndroid Build Coastguard Worker #ifdef _WIN32
545*6236dae4SAndroid Build Coastguard Worker /* CTRL event handler for Windows Console applications to simulate
546*6236dae4SAndroid Build Coastguard Worker  * SIGINT, SIGTERM and SIGBREAK on CTRL events and trigger signal handler.
547*6236dae4SAndroid Build Coastguard Worker  *
548*6236dae4SAndroid Build Coastguard Worker  * Background information from MSDN:
549*6236dae4SAndroid Build Coastguard Worker  * SIGINT is not supported for any Win32 application. When a CTRL+C
550*6236dae4SAndroid Build Coastguard Worker  * interrupt occurs, Win32 operating systems generate a new thread
551*6236dae4SAndroid Build Coastguard Worker  * to specifically handle that interrupt. This can cause a single-thread
552*6236dae4SAndroid Build Coastguard Worker  * application, such as one in UNIX, to become multithreaded and cause
553*6236dae4SAndroid Build Coastguard Worker  * unexpected behavior.
554*6236dae4SAndroid Build Coastguard Worker  * [...]
555*6236dae4SAndroid Build Coastguard Worker  * The SIGILL and SIGTERM signals are not generated under Windows.
556*6236dae4SAndroid Build Coastguard Worker  * They are included for ANSI compatibility. Therefore, you can set
557*6236dae4SAndroid Build Coastguard Worker  * signal handlers for these signals by using signal, and you can also
558*6236dae4SAndroid Build Coastguard Worker  * explicitly generate these signals by calling raise. Source:
559*6236dae4SAndroid Build Coastguard Worker  * https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/signal
560*6236dae4SAndroid Build Coastguard Worker  */
ctrl_event_handler(DWORD dwCtrlType)561*6236dae4SAndroid Build Coastguard Worker static BOOL WINAPI ctrl_event_handler(DWORD dwCtrlType)
562*6236dae4SAndroid Build Coastguard Worker {
563*6236dae4SAndroid Build Coastguard Worker   int signum = 0;
564*6236dae4SAndroid Build Coastguard Worker   logmsg("ctrl_event_handler: %lu", dwCtrlType);
565*6236dae4SAndroid Build Coastguard Worker   switch(dwCtrlType) {
566*6236dae4SAndroid Build Coastguard Worker #ifdef SIGINT
567*6236dae4SAndroid Build Coastguard Worker   case CTRL_C_EVENT:
568*6236dae4SAndroid Build Coastguard Worker     signum = SIGINT;
569*6236dae4SAndroid Build Coastguard Worker     break;
570*6236dae4SAndroid Build Coastguard Worker #endif
571*6236dae4SAndroid Build Coastguard Worker #ifdef SIGTERM
572*6236dae4SAndroid Build Coastguard Worker   case CTRL_CLOSE_EVENT:
573*6236dae4SAndroid Build Coastguard Worker     signum = SIGTERM;
574*6236dae4SAndroid Build Coastguard Worker     break;
575*6236dae4SAndroid Build Coastguard Worker #endif
576*6236dae4SAndroid Build Coastguard Worker #ifdef SIGBREAK
577*6236dae4SAndroid Build Coastguard Worker   case CTRL_BREAK_EVENT:
578*6236dae4SAndroid Build Coastguard Worker     signum = SIGBREAK;
579*6236dae4SAndroid Build Coastguard Worker     break;
580*6236dae4SAndroid Build Coastguard Worker #endif
581*6236dae4SAndroid Build Coastguard Worker   default:
582*6236dae4SAndroid Build Coastguard Worker     return FALSE;
583*6236dae4SAndroid Build Coastguard Worker   }
584*6236dae4SAndroid Build Coastguard Worker   if(signum) {
585*6236dae4SAndroid Build Coastguard Worker     logmsg("ctrl_event_handler: %lu -> %d", dwCtrlType, signum);
586*6236dae4SAndroid Build Coastguard Worker     raise(signum);
587*6236dae4SAndroid Build Coastguard Worker   }
588*6236dae4SAndroid Build Coastguard Worker   return TRUE;
589*6236dae4SAndroid Build Coastguard Worker }
590*6236dae4SAndroid Build Coastguard Worker #endif
591*6236dae4SAndroid Build Coastguard Worker 
592*6236dae4SAndroid Build Coastguard Worker #if defined(_WIN32) && !defined(CURL_WINDOWS_UWP)
593*6236dae4SAndroid Build Coastguard Worker /* Window message handler for Windows applications to add support
594*6236dae4SAndroid Build Coastguard Worker  * for graceful process termination via taskkill (without /f) which
595*6236dae4SAndroid Build Coastguard Worker  * sends WM_CLOSE to all Windows of a process (even hidden ones).
596*6236dae4SAndroid Build Coastguard Worker  *
597*6236dae4SAndroid Build Coastguard Worker  * Therefore we create and run a hidden Window in a separate thread
598*6236dae4SAndroid Build Coastguard Worker  * to receive and handle the WM_CLOSE message as SIGTERM signal.
599*6236dae4SAndroid Build Coastguard Worker  */
main_window_proc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)600*6236dae4SAndroid Build Coastguard Worker static LRESULT CALLBACK main_window_proc(HWND hwnd, UINT uMsg,
601*6236dae4SAndroid Build Coastguard Worker                                          WPARAM wParam, LPARAM lParam)
602*6236dae4SAndroid Build Coastguard Worker {
603*6236dae4SAndroid Build Coastguard Worker   int signum = 0;
604*6236dae4SAndroid Build Coastguard Worker   if(hwnd == hidden_main_window) {
605*6236dae4SAndroid Build Coastguard Worker     switch(uMsg) {
606*6236dae4SAndroid Build Coastguard Worker #ifdef SIGTERM
607*6236dae4SAndroid Build Coastguard Worker       case WM_CLOSE:
608*6236dae4SAndroid Build Coastguard Worker         signum = SIGTERM;
609*6236dae4SAndroid Build Coastguard Worker         break;
610*6236dae4SAndroid Build Coastguard Worker #endif
611*6236dae4SAndroid Build Coastguard Worker     case WM_DESTROY:
612*6236dae4SAndroid Build Coastguard Worker       PostQuitMessage(0);
613*6236dae4SAndroid Build Coastguard Worker       break;
614*6236dae4SAndroid Build Coastguard Worker     }
615*6236dae4SAndroid Build Coastguard Worker     if(signum) {
616*6236dae4SAndroid Build Coastguard Worker       logmsg("main_window_proc: %d -> %d", uMsg, signum);
617*6236dae4SAndroid Build Coastguard Worker       raise(signum);
618*6236dae4SAndroid Build Coastguard Worker     }
619*6236dae4SAndroid Build Coastguard Worker   }
620*6236dae4SAndroid Build Coastguard Worker   return DefWindowProc(hwnd, uMsg, wParam, lParam);
621*6236dae4SAndroid Build Coastguard Worker }
622*6236dae4SAndroid Build Coastguard Worker /* Window message queue loop for hidden main window, details see above.
623*6236dae4SAndroid Build Coastguard Worker  */
624*6236dae4SAndroid Build Coastguard Worker #ifdef _WIN32_WCE
main_window_loop(LPVOID lpParameter)625*6236dae4SAndroid Build Coastguard Worker static DWORD WINAPI main_window_loop(LPVOID lpParameter)
626*6236dae4SAndroid Build Coastguard Worker #else
627*6236dae4SAndroid Build Coastguard Worker #include <process.h>
628*6236dae4SAndroid Build Coastguard Worker static unsigned int WINAPI main_window_loop(void *lpParameter)
629*6236dae4SAndroid Build Coastguard Worker #endif
630*6236dae4SAndroid Build Coastguard Worker {
631*6236dae4SAndroid Build Coastguard Worker   WNDCLASS wc;
632*6236dae4SAndroid Build Coastguard Worker   BOOL ret;
633*6236dae4SAndroid Build Coastguard Worker   MSG msg;
634*6236dae4SAndroid Build Coastguard Worker 
635*6236dae4SAndroid Build Coastguard Worker   ZeroMemory(&wc, sizeof(wc));
636*6236dae4SAndroid Build Coastguard Worker   wc.lpfnWndProc = (WNDPROC)main_window_proc;
637*6236dae4SAndroid Build Coastguard Worker   wc.hInstance = (HINSTANCE)lpParameter;
638*6236dae4SAndroid Build Coastguard Worker   wc.lpszClassName = TEXT("MainWClass");
639*6236dae4SAndroid Build Coastguard Worker   if(!RegisterClass(&wc)) {
640*6236dae4SAndroid Build Coastguard Worker     perror("RegisterClass failed");
641*6236dae4SAndroid Build Coastguard Worker     return (DWORD)-1;
642*6236dae4SAndroid Build Coastguard Worker   }
643*6236dae4SAndroid Build Coastguard Worker 
644*6236dae4SAndroid Build Coastguard Worker   hidden_main_window = CreateWindowEx(0, TEXT("MainWClass"),
645*6236dae4SAndroid Build Coastguard Worker                                       TEXT("Recv WM_CLOSE msg"),
646*6236dae4SAndroid Build Coastguard Worker                                       WS_OVERLAPPEDWINDOW,
647*6236dae4SAndroid Build Coastguard Worker                                       CW_USEDEFAULT, CW_USEDEFAULT,
648*6236dae4SAndroid Build Coastguard Worker                                       CW_USEDEFAULT, CW_USEDEFAULT,
649*6236dae4SAndroid Build Coastguard Worker                                       (HWND)NULL, (HMENU)NULL,
650*6236dae4SAndroid Build Coastguard Worker                                       wc.hInstance, (LPVOID)NULL);
651*6236dae4SAndroid Build Coastguard Worker   if(!hidden_main_window) {
652*6236dae4SAndroid Build Coastguard Worker     perror("CreateWindowEx failed");
653*6236dae4SAndroid Build Coastguard Worker     return (DWORD)-1;
654*6236dae4SAndroid Build Coastguard Worker   }
655*6236dae4SAndroid Build Coastguard Worker 
656*6236dae4SAndroid Build Coastguard Worker   do {
657*6236dae4SAndroid Build Coastguard Worker     ret = GetMessage(&msg, NULL, 0, 0);
658*6236dae4SAndroid Build Coastguard Worker     if(ret == -1) {
659*6236dae4SAndroid Build Coastguard Worker       perror("GetMessage failed");
660*6236dae4SAndroid Build Coastguard Worker       return (DWORD)-1;
661*6236dae4SAndroid Build Coastguard Worker     }
662*6236dae4SAndroid Build Coastguard Worker     else if(ret) {
663*6236dae4SAndroid Build Coastguard Worker       if(msg.message == WM_APP) {
664*6236dae4SAndroid Build Coastguard Worker         DestroyWindow(hidden_main_window);
665*6236dae4SAndroid Build Coastguard Worker       }
666*6236dae4SAndroid Build Coastguard Worker       else if(msg.hwnd && !TranslateMessage(&msg)) {
667*6236dae4SAndroid Build Coastguard Worker         DispatchMessage(&msg);
668*6236dae4SAndroid Build Coastguard Worker       }
669*6236dae4SAndroid Build Coastguard Worker     }
670*6236dae4SAndroid Build Coastguard Worker   } while(ret);
671*6236dae4SAndroid Build Coastguard Worker 
672*6236dae4SAndroid Build Coastguard Worker   hidden_main_window = NULL;
673*6236dae4SAndroid Build Coastguard Worker   return (DWORD)msg.wParam;
674*6236dae4SAndroid Build Coastguard Worker }
675*6236dae4SAndroid Build Coastguard Worker #endif
676*6236dae4SAndroid Build Coastguard Worker 
set_signal(int signum,SIGHANDLER_T handler,bool restartable)677*6236dae4SAndroid Build Coastguard Worker static SIGHANDLER_T set_signal(int signum, SIGHANDLER_T handler,
678*6236dae4SAndroid Build Coastguard Worker                                bool restartable)
679*6236dae4SAndroid Build Coastguard Worker {
680*6236dae4SAndroid Build Coastguard Worker #if defined(HAVE_SIGACTION) && defined(SA_RESTART)
681*6236dae4SAndroid Build Coastguard Worker   struct sigaction sa, oldsa;
682*6236dae4SAndroid Build Coastguard Worker 
683*6236dae4SAndroid Build Coastguard Worker   memset(&sa, 0, sizeof(sa));
684*6236dae4SAndroid Build Coastguard Worker   sa.sa_handler = handler;
685*6236dae4SAndroid Build Coastguard Worker   sigemptyset(&sa.sa_mask);
686*6236dae4SAndroid Build Coastguard Worker   sigaddset(&sa.sa_mask, signum);
687*6236dae4SAndroid Build Coastguard Worker   sa.sa_flags = restartable ? SA_RESTART : 0;
688*6236dae4SAndroid Build Coastguard Worker 
689*6236dae4SAndroid Build Coastguard Worker   if(sigaction(signum, &sa, &oldsa))
690*6236dae4SAndroid Build Coastguard Worker     return SIG_ERR;
691*6236dae4SAndroid Build Coastguard Worker 
692*6236dae4SAndroid Build Coastguard Worker   return oldsa.sa_handler;
693*6236dae4SAndroid Build Coastguard Worker #else
694*6236dae4SAndroid Build Coastguard Worker   SIGHANDLER_T oldhdlr = signal(signum, handler);
695*6236dae4SAndroid Build Coastguard Worker 
696*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_SIGINTERRUPT
697*6236dae4SAndroid Build Coastguard Worker   if(oldhdlr != SIG_ERR)
698*6236dae4SAndroid Build Coastguard Worker     siginterrupt(signum, (int) restartable);
699*6236dae4SAndroid Build Coastguard Worker #else
700*6236dae4SAndroid Build Coastguard Worker   (void) restartable;
701*6236dae4SAndroid Build Coastguard Worker #endif
702*6236dae4SAndroid Build Coastguard Worker 
703*6236dae4SAndroid Build Coastguard Worker   return oldhdlr;
704*6236dae4SAndroid Build Coastguard Worker #endif
705*6236dae4SAndroid Build Coastguard Worker }
706*6236dae4SAndroid Build Coastguard Worker 
install_signal_handlers(bool keep_sigalrm)707*6236dae4SAndroid Build Coastguard Worker void install_signal_handlers(bool keep_sigalrm)
708*6236dae4SAndroid Build Coastguard Worker {
709*6236dae4SAndroid Build Coastguard Worker #ifdef _WIN32
710*6236dae4SAndroid Build Coastguard Worker   /* setup Windows exit event before any signal can trigger */
711*6236dae4SAndroid Build Coastguard Worker   exit_event = CreateEvent(NULL, TRUE, FALSE, NULL);
712*6236dae4SAndroid Build Coastguard Worker   if(!exit_event)
713*6236dae4SAndroid Build Coastguard Worker     logmsg("cannot create exit event");
714*6236dae4SAndroid Build Coastguard Worker #endif
715*6236dae4SAndroid Build Coastguard Worker #ifdef SIGHUP
716*6236dae4SAndroid Build Coastguard Worker   /* ignore SIGHUP signal */
717*6236dae4SAndroid Build Coastguard Worker   old_sighup_handler = set_signal(SIGHUP, SIG_IGN, FALSE);
718*6236dae4SAndroid Build Coastguard Worker   if(old_sighup_handler == SIG_ERR)
719*6236dae4SAndroid Build Coastguard Worker     logmsg("cannot install SIGHUP handler: %s", strerror(errno));
720*6236dae4SAndroid Build Coastguard Worker #endif
721*6236dae4SAndroid Build Coastguard Worker #ifdef SIGPIPE
722*6236dae4SAndroid Build Coastguard Worker   /* ignore SIGPIPE signal */
723*6236dae4SAndroid Build Coastguard Worker   old_sigpipe_handler = set_signal(SIGPIPE, SIG_IGN, FALSE);
724*6236dae4SAndroid Build Coastguard Worker   if(old_sigpipe_handler == SIG_ERR)
725*6236dae4SAndroid Build Coastguard Worker     logmsg("cannot install SIGPIPE handler: %s", strerror(errno));
726*6236dae4SAndroid Build Coastguard Worker #endif
727*6236dae4SAndroid Build Coastguard Worker #ifdef SIGALRM
728*6236dae4SAndroid Build Coastguard Worker   if(!keep_sigalrm) {
729*6236dae4SAndroid Build Coastguard Worker     /* ignore SIGALRM signal */
730*6236dae4SAndroid Build Coastguard Worker     old_sigalrm_handler = set_signal(SIGALRM, SIG_IGN, FALSE);
731*6236dae4SAndroid Build Coastguard Worker     if(old_sigalrm_handler == SIG_ERR)
732*6236dae4SAndroid Build Coastguard Worker       logmsg("cannot install SIGALRM handler: %s", strerror(errno));
733*6236dae4SAndroid Build Coastguard Worker   }
734*6236dae4SAndroid Build Coastguard Worker #else
735*6236dae4SAndroid Build Coastguard Worker   (void)keep_sigalrm;
736*6236dae4SAndroid Build Coastguard Worker #endif
737*6236dae4SAndroid Build Coastguard Worker #ifdef SIGINT
738*6236dae4SAndroid Build Coastguard Worker   /* handle SIGINT signal with our exit_signal_handler */
739*6236dae4SAndroid Build Coastguard Worker   old_sigint_handler = set_signal(SIGINT, exit_signal_handler, TRUE);
740*6236dae4SAndroid Build Coastguard Worker   if(old_sigint_handler == SIG_ERR)
741*6236dae4SAndroid Build Coastguard Worker     logmsg("cannot install SIGINT handler: %s", strerror(errno));
742*6236dae4SAndroid Build Coastguard Worker #endif
743*6236dae4SAndroid Build Coastguard Worker #ifdef SIGTERM
744*6236dae4SAndroid Build Coastguard Worker   /* handle SIGTERM signal with our exit_signal_handler */
745*6236dae4SAndroid Build Coastguard Worker   old_sigterm_handler = set_signal(SIGTERM, exit_signal_handler, TRUE);
746*6236dae4SAndroid Build Coastguard Worker   if(old_sigterm_handler == SIG_ERR)
747*6236dae4SAndroid Build Coastguard Worker     logmsg("cannot install SIGTERM handler: %s", strerror(errno));
748*6236dae4SAndroid Build Coastguard Worker #endif
749*6236dae4SAndroid Build Coastguard Worker #if defined(SIGBREAK) && defined(_WIN32)
750*6236dae4SAndroid Build Coastguard Worker   /* handle SIGBREAK signal with our exit_signal_handler */
751*6236dae4SAndroid Build Coastguard Worker   old_sigbreak_handler = set_signal(SIGBREAK, exit_signal_handler, TRUE);
752*6236dae4SAndroid Build Coastguard Worker   if(old_sigbreak_handler == SIG_ERR)
753*6236dae4SAndroid Build Coastguard Worker     logmsg("cannot install SIGBREAK handler: %s", strerror(errno));
754*6236dae4SAndroid Build Coastguard Worker #endif
755*6236dae4SAndroid Build Coastguard Worker #ifdef _WIN32
756*6236dae4SAndroid Build Coastguard Worker   if(!SetConsoleCtrlHandler(ctrl_event_handler, TRUE))
757*6236dae4SAndroid Build Coastguard Worker     logmsg("cannot install CTRL event handler");
758*6236dae4SAndroid Build Coastguard Worker 
759*6236dae4SAndroid Build Coastguard Worker #ifndef CURL_WINDOWS_UWP
760*6236dae4SAndroid Build Coastguard Worker   {
761*6236dae4SAndroid Build Coastguard Worker #ifdef _WIN32_WCE
762*6236dae4SAndroid Build Coastguard Worker     typedef HANDLE curl_win_thread_handle_t;
763*6236dae4SAndroid Build Coastguard Worker #else
764*6236dae4SAndroid Build Coastguard Worker     typedef uintptr_t curl_win_thread_handle_t;
765*6236dae4SAndroid Build Coastguard Worker #endif
766*6236dae4SAndroid Build Coastguard Worker     curl_win_thread_handle_t thread;
767*6236dae4SAndroid Build Coastguard Worker #ifdef _WIN32_WCE
768*6236dae4SAndroid Build Coastguard Worker     thread = CreateThread(NULL, 0, &main_window_loop,
769*6236dae4SAndroid Build Coastguard Worker                           (LPVOID)GetModuleHandle(NULL), 0, &thread_main_id);
770*6236dae4SAndroid Build Coastguard Worker #else
771*6236dae4SAndroid Build Coastguard Worker     thread = _beginthreadex(NULL, 0, &main_window_loop,
772*6236dae4SAndroid Build Coastguard Worker                             (void *)GetModuleHandle(NULL), 0, &thread_main_id);
773*6236dae4SAndroid Build Coastguard Worker #endif
774*6236dae4SAndroid Build Coastguard Worker     thread_main_window = (HANDLE)thread;
775*6236dae4SAndroid Build Coastguard Worker     if(!thread_main_window || !thread_main_id)
776*6236dae4SAndroid Build Coastguard Worker       logmsg("cannot start main window loop");
777*6236dae4SAndroid Build Coastguard Worker   }
778*6236dae4SAndroid Build Coastguard Worker #endif
779*6236dae4SAndroid Build Coastguard Worker #endif
780*6236dae4SAndroid Build Coastguard Worker }
781*6236dae4SAndroid Build Coastguard Worker 
restore_signal_handlers(bool keep_sigalrm)782*6236dae4SAndroid Build Coastguard Worker void restore_signal_handlers(bool keep_sigalrm)
783*6236dae4SAndroid Build Coastguard Worker {
784*6236dae4SAndroid Build Coastguard Worker #ifdef SIGHUP
785*6236dae4SAndroid Build Coastguard Worker   if(SIG_ERR != old_sighup_handler)
786*6236dae4SAndroid Build Coastguard Worker     (void) set_signal(SIGHUP, old_sighup_handler, FALSE);
787*6236dae4SAndroid Build Coastguard Worker #endif
788*6236dae4SAndroid Build Coastguard Worker #ifdef SIGPIPE
789*6236dae4SAndroid Build Coastguard Worker   if(SIG_ERR != old_sigpipe_handler)
790*6236dae4SAndroid Build Coastguard Worker     (void) set_signal(SIGPIPE, old_sigpipe_handler, FALSE);
791*6236dae4SAndroid Build Coastguard Worker #endif
792*6236dae4SAndroid Build Coastguard Worker #ifdef SIGALRM
793*6236dae4SAndroid Build Coastguard Worker   if(!keep_sigalrm) {
794*6236dae4SAndroid Build Coastguard Worker     if(SIG_ERR != old_sigalrm_handler)
795*6236dae4SAndroid Build Coastguard Worker       (void) set_signal(SIGALRM, old_sigalrm_handler, FALSE);
796*6236dae4SAndroid Build Coastguard Worker   }
797*6236dae4SAndroid Build Coastguard Worker #else
798*6236dae4SAndroid Build Coastguard Worker   (void)keep_sigalrm;
799*6236dae4SAndroid Build Coastguard Worker #endif
800*6236dae4SAndroid Build Coastguard Worker #ifdef SIGINT
801*6236dae4SAndroid Build Coastguard Worker   if(SIG_ERR != old_sigint_handler)
802*6236dae4SAndroid Build Coastguard Worker     (void) set_signal(SIGINT, old_sigint_handler, FALSE);
803*6236dae4SAndroid Build Coastguard Worker #endif
804*6236dae4SAndroid Build Coastguard Worker #ifdef SIGTERM
805*6236dae4SAndroid Build Coastguard Worker   if(SIG_ERR != old_sigterm_handler)
806*6236dae4SAndroid Build Coastguard Worker     (void) set_signal(SIGTERM, old_sigterm_handler, FALSE);
807*6236dae4SAndroid Build Coastguard Worker #endif
808*6236dae4SAndroid Build Coastguard Worker #if defined(SIGBREAK) && defined(_WIN32)
809*6236dae4SAndroid Build Coastguard Worker   if(SIG_ERR != old_sigbreak_handler)
810*6236dae4SAndroid Build Coastguard Worker     (void) set_signal(SIGBREAK, old_sigbreak_handler, FALSE);
811*6236dae4SAndroid Build Coastguard Worker #endif
812*6236dae4SAndroid Build Coastguard Worker #ifdef _WIN32
813*6236dae4SAndroid Build Coastguard Worker   (void)SetConsoleCtrlHandler(ctrl_event_handler, FALSE);
814*6236dae4SAndroid Build Coastguard Worker #ifndef CURL_WINDOWS_UWP
815*6236dae4SAndroid Build Coastguard Worker   if(thread_main_window && thread_main_id) {
816*6236dae4SAndroid Build Coastguard Worker     if(PostThreadMessage(thread_main_id, WM_APP, 0, 0)) {
817*6236dae4SAndroid Build Coastguard Worker       if(WaitForSingleObjectEx(thread_main_window, INFINITE, TRUE)) {
818*6236dae4SAndroid Build Coastguard Worker         if(CloseHandle(thread_main_window)) {
819*6236dae4SAndroid Build Coastguard Worker           thread_main_window = NULL;
820*6236dae4SAndroid Build Coastguard Worker           thread_main_id = 0;
821*6236dae4SAndroid Build Coastguard Worker         }
822*6236dae4SAndroid Build Coastguard Worker       }
823*6236dae4SAndroid Build Coastguard Worker     }
824*6236dae4SAndroid Build Coastguard Worker   }
825*6236dae4SAndroid Build Coastguard Worker   if(exit_event) {
826*6236dae4SAndroid Build Coastguard Worker     if(CloseHandle(exit_event)) {
827*6236dae4SAndroid Build Coastguard Worker       exit_event = NULL;
828*6236dae4SAndroid Build Coastguard Worker     }
829*6236dae4SAndroid Build Coastguard Worker   }
830*6236dae4SAndroid Build Coastguard Worker #endif
831*6236dae4SAndroid Build Coastguard Worker #endif
832*6236dae4SAndroid Build Coastguard Worker }
833*6236dae4SAndroid Build Coastguard Worker 
834*6236dae4SAndroid Build Coastguard Worker #ifdef USE_UNIX_SOCKETS
835*6236dae4SAndroid Build Coastguard Worker 
bind_unix_socket(curl_socket_t sock,const char * unix_socket,struct sockaddr_un * sau)836*6236dae4SAndroid Build Coastguard Worker int bind_unix_socket(curl_socket_t sock, const char *unix_socket,
837*6236dae4SAndroid Build Coastguard Worker                      struct sockaddr_un *sau)
838*6236dae4SAndroid Build Coastguard Worker {
839*6236dae4SAndroid Build Coastguard Worker   int error;
840*6236dae4SAndroid Build Coastguard Worker   int rc;
841*6236dae4SAndroid Build Coastguard Worker   size_t len = strlen(unix_socket);
842*6236dae4SAndroid Build Coastguard Worker 
843*6236dae4SAndroid Build Coastguard Worker   memset(sau, 0, sizeof(struct sockaddr_un));
844*6236dae4SAndroid Build Coastguard Worker   sau->sun_family = AF_UNIX;
845*6236dae4SAndroid Build Coastguard Worker   if(len >= sizeof(sau->sun_path) - 1) {
846*6236dae4SAndroid Build Coastguard Worker     logmsg("Too long unix socket domain path (%zd)", len);
847*6236dae4SAndroid Build Coastguard Worker     return -1;
848*6236dae4SAndroid Build Coastguard Worker   }
849*6236dae4SAndroid Build Coastguard Worker   strcpy(sau->sun_path, unix_socket);
850*6236dae4SAndroid Build Coastguard Worker   rc = bind(sock, (struct sockaddr*)sau, sizeof(struct sockaddr_un));
851*6236dae4SAndroid Build Coastguard Worker   if(0 != rc && SOCKERRNO == EADDRINUSE) {
852*6236dae4SAndroid Build Coastguard Worker     struct_stat statbuf;
853*6236dae4SAndroid Build Coastguard Worker     /* socket already exists. Perhaps it is stale? */
854*6236dae4SAndroid Build Coastguard Worker     curl_socket_t unixfd = socket(AF_UNIX, SOCK_STREAM, 0);
855*6236dae4SAndroid Build Coastguard Worker     if(CURL_SOCKET_BAD == unixfd) {
856*6236dae4SAndroid Build Coastguard Worker       logmsg("Failed to create socket at %s: (%d) %s",
857*6236dae4SAndroid Build Coastguard Worker              unix_socket, SOCKERRNO, sstrerror(SOCKERRNO));
858*6236dae4SAndroid Build Coastguard Worker       return -1;
859*6236dae4SAndroid Build Coastguard Worker     }
860*6236dae4SAndroid Build Coastguard Worker     /* check whether the server is alive */
861*6236dae4SAndroid Build Coastguard Worker     rc = connect(unixfd, (struct sockaddr*)sau, sizeof(struct sockaddr_un));
862*6236dae4SAndroid Build Coastguard Worker     error = SOCKERRNO;
863*6236dae4SAndroid Build Coastguard Worker     sclose(unixfd);
864*6236dae4SAndroid Build Coastguard Worker     if(0 != rc && ECONNREFUSED != error) {
865*6236dae4SAndroid Build Coastguard Worker       logmsg("Failed to connect to %s: (%d) %s",
866*6236dae4SAndroid Build Coastguard Worker              unix_socket, error, sstrerror(error));
867*6236dae4SAndroid Build Coastguard Worker       return rc;
868*6236dae4SAndroid Build Coastguard Worker     }
869*6236dae4SAndroid Build Coastguard Worker     /* socket server is not alive, now check if it was actually a socket. */
870*6236dae4SAndroid Build Coastguard Worker #ifdef _WIN32
871*6236dae4SAndroid Build Coastguard Worker     /* Windows does not have lstat function. */
872*6236dae4SAndroid Build Coastguard Worker     rc = curlx_win32_stat(unix_socket, &statbuf);
873*6236dae4SAndroid Build Coastguard Worker #else
874*6236dae4SAndroid Build Coastguard Worker     rc = lstat(unix_socket, &statbuf);
875*6236dae4SAndroid Build Coastguard Worker #endif
876*6236dae4SAndroid Build Coastguard Worker     if(0 != rc) {
877*6236dae4SAndroid Build Coastguard Worker       logmsg("Error binding socket, failed to stat %s: (%d) %s",
878*6236dae4SAndroid Build Coastguard Worker              unix_socket, errno, strerror(errno));
879*6236dae4SAndroid Build Coastguard Worker       return rc;
880*6236dae4SAndroid Build Coastguard Worker     }
881*6236dae4SAndroid Build Coastguard Worker #ifdef S_IFSOCK
882*6236dae4SAndroid Build Coastguard Worker     if((statbuf.st_mode & S_IFSOCK) != S_IFSOCK) {
883*6236dae4SAndroid Build Coastguard Worker       logmsg("Error binding socket, failed to stat %s", unix_socket);
884*6236dae4SAndroid Build Coastguard Worker       return -1;
885*6236dae4SAndroid Build Coastguard Worker     }
886*6236dae4SAndroid Build Coastguard Worker #endif
887*6236dae4SAndroid Build Coastguard Worker     /* dead socket, cleanup and retry bind */
888*6236dae4SAndroid Build Coastguard Worker     rc = unlink(unix_socket);
889*6236dae4SAndroid Build Coastguard Worker     if(0 != rc) {
890*6236dae4SAndroid Build Coastguard Worker       logmsg("Error binding socket, failed to unlink %s: (%d) %s",
891*6236dae4SAndroid Build Coastguard Worker              unix_socket, errno, strerror(errno));
892*6236dae4SAndroid Build Coastguard Worker       return rc;
893*6236dae4SAndroid Build Coastguard Worker     }
894*6236dae4SAndroid Build Coastguard Worker     /* stale socket is gone, retry bind */
895*6236dae4SAndroid Build Coastguard Worker     rc = bind(sock, (struct sockaddr*)sau, sizeof(struct sockaddr_un));
896*6236dae4SAndroid Build Coastguard Worker   }
897*6236dae4SAndroid Build Coastguard Worker   return rc;
898*6236dae4SAndroid Build Coastguard Worker }
899*6236dae4SAndroid Build Coastguard Worker #endif
900