|
Packit |
2997f0 |
/*
|
|
Packit |
2997f0 |
* librdkafka - Apache Kafka C library
|
|
Packit |
2997f0 |
*
|
|
Packit |
2997f0 |
* Copyright (c) 2012-2015 Magnus Edenhill
|
|
Packit |
2997f0 |
* All rights reserved.
|
|
Packit |
2997f0 |
*
|
|
Packit |
2997f0 |
* Redistribution and use in source and binary forms, with or without
|
|
Packit |
2997f0 |
* modification, are permitted provided that the following conditions are met:
|
|
Packit |
2997f0 |
*
|
|
Packit |
2997f0 |
* 1. Redistributions of source code must retain the above copyright notice,
|
|
Packit |
2997f0 |
* this list of conditions and the following disclaimer.
|
|
Packit |
2997f0 |
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
Packit |
2997f0 |
* this list of conditions and the following disclaimer in the documentation
|
|
Packit |
2997f0 |
* and/or other materials provided with the distribution.
|
|
Packit |
2997f0 |
*
|
|
Packit |
2997f0 |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
Packit |
2997f0 |
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
Packit |
2997f0 |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
Packit |
2997f0 |
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
Packit |
2997f0 |
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
Packit |
2997f0 |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
Packit |
2997f0 |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
Packit |
2997f0 |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
Packit |
2997f0 |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
Packit |
2997f0 |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
Packit |
2997f0 |
* POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
2997f0 |
*/
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
/**
|
|
Packit |
2997f0 |
* Win32 (Visual Studio) support
|
|
Packit |
2997f0 |
*/
|
|
Packit |
2997f0 |
#ifndef _RDWIN32_H_
|
|
Packit |
2997f0 |
#define _RDWIN32_H_
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
#include <stdlib.h>
|
|
Packit |
2997f0 |
#include <inttypes.h>
|
|
Packit |
2997f0 |
#include <sys/types.h>
|
|
Packit |
2997f0 |
#include <time.h>
|
|
Packit |
2997f0 |
#include <assert.h>
|
|
Packit |
2997f0 |
#define WIN32_MEAN_AND_LEAN
|
|
Packit |
2997f0 |
#include <Winsock2.h> /* for struct timeval */
|
|
Packit |
2997f0 |
#include <io.h>
|
|
Packit |
2997f0 |
#include <fcntl.h>
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
/**
|
|
Packit |
2997f0 |
* Types
|
|
Packit |
2997f0 |
*/
|
|
Packit |
2997f0 |
typedef SSIZE_T ssize_t;
|
|
Packit |
2997f0 |
typedef int socklen_t;
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
struct iovec {
|
|
Packit |
2997f0 |
void *iov_base;
|
|
Packit |
2997f0 |
size_t iov_len;
|
|
Packit |
2997f0 |
};
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
struct msghdr {
|
|
Packit |
2997f0 |
struct iovec *msg_iov;
|
|
Packit |
2997f0 |
int msg_iovlen;
|
|
Packit |
2997f0 |
};
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
#define LOG_EMERG 0
|
|
Packit |
2997f0 |
#define LOG_ALERT 1
|
|
Packit |
2997f0 |
#define LOG_CRIT 2
|
|
Packit |
2997f0 |
#define LOG_ERR 3
|
|
Packit |
2997f0 |
#define LOG_WARNING 4
|
|
Packit |
2997f0 |
#define LOG_NOTICE 5
|
|
Packit |
2997f0 |
#define LOG_INFO 6
|
|
Packit |
2997f0 |
#define LOG_DEBUG 7
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
/**
|
|
Packit |
2997f0 |
* Annotations, attributes, optimizers
|
|
Packit |
2997f0 |
*/
|
|
Packit |
2997f0 |
#ifndef likely
|
|
Packit |
2997f0 |
#define likely(x) x
|
|
Packit |
2997f0 |
#endif
|
|
Packit |
2997f0 |
#ifndef unlikely
|
|
Packit |
2997f0 |
#define unlikely(x) x
|
|
Packit |
2997f0 |
#endif
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
#define RD_UNUSED
|
|
Packit |
2997f0 |
#define RD_INLINE __inline
|
|
Packit |
2997f0 |
#define RD_WARN_UNUSED_RESULT
|
|
Packit |
2997f0 |
#define RD_NORETURN __declspec(noreturn)
|
|
Packit |
2997f0 |
#define RD_IS_CONSTANT(p) (0)
|
|
Packit |
2997f0 |
#define RD_TLS __declspec(thread)
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
/**
|
|
Packit |
2997f0 |
* Allocation
|
|
Packit |
2997f0 |
*/
|
|
Packit |
2997f0 |
#define rd_alloca(N) _alloca(N)
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
/**
|
|
Packit |
2997f0 |
* Strings, formatting, printf, ..
|
|
Packit |
2997f0 |
*/
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
/* size_t and ssize_t format strings */
|
|
Packit |
2997f0 |
#define PRIusz "Iu"
|
|
Packit |
2997f0 |
#define PRIdsz "Id"
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
#define RD_FORMAT(...)
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
static RD_UNUSED RD_INLINE
|
|
Packit |
2997f0 |
int rd_vsnprintf (char *str, size_t size, const char *format, va_list ap) {
|
|
Packit |
2997f0 |
int cnt = -1;
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
if (size != 0)
|
|
Packit |
2997f0 |
cnt = _vsnprintf_s(str, size, _TRUNCATE, format, ap);
|
|
Packit |
2997f0 |
if (cnt == -1)
|
|
Packit |
2997f0 |
cnt = _vscprintf(format, ap);
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
return cnt;
|
|
Packit |
2997f0 |
}
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
static RD_UNUSED RD_INLINE
|
|
Packit |
2997f0 |
int rd_snprintf (char *str, size_t size, const char *format, ...) {
|
|
Packit |
2997f0 |
int cnt;
|
|
Packit |
2997f0 |
va_list ap;
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
va_start(ap, format);
|
|
Packit |
2997f0 |
cnt = rd_vsnprintf(str, size, format, ap);
|
|
Packit |
2997f0 |
va_end(ap);
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
return cnt;
|
|
Packit |
2997f0 |
}
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
#define rd_strcasecmp(A,B) _stricmp(A,B)
|
|
Packit |
2997f0 |
#define rd_strncasecmp(A,B,N) _strnicmp(A,B,N)
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
/**
|
|
Packit |
2997f0 |
* Errors
|
|
Packit |
2997f0 |
*/
|
|
Packit |
2997f0 |
static RD_INLINE RD_UNUSED const char *rd_strerror(int err) {
|
|
Packit |
2997f0 |
static RD_TLS char ret[128];
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
strerror_s(ret, sizeof(ret) - 1, err);
|
|
Packit |
2997f0 |
return ret;
|
|
Packit |
2997f0 |
}
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
/**
|
|
Packit |
2997f0 |
* Atomics
|
|
Packit |
2997f0 |
*/
|
|
Packit |
2997f0 |
#ifndef __cplusplus
|
|
Packit |
2997f0 |
#include "rdatomic.h"
|
|
Packit |
2997f0 |
#endif
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
/**
|
|
Packit |
2997f0 |
* Misc
|
|
Packit |
2997f0 |
*/
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
/**
|
|
Packit |
2997f0 |
* Microsecond sleep.
|
|
Packit |
2997f0 |
* 'retry': if true, retry if sleep is interrupted (because of signal)
|
|
Packit |
2997f0 |
*/
|
|
Packit |
2997f0 |
#define rd_usleep(usec,terminate) Sleep((usec) / 1000)
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
/**
|
|
Packit |
2997f0 |
* @brief gettimeofday() for win32
|
|
Packit |
2997f0 |
*/
|
|
Packit |
2997f0 |
static RD_UNUSED
|
|
Packit |
2997f0 |
int rd_gettimeofday (struct timeval *tv, struct timezone *tz) {
|
|
Packit |
2997f0 |
SYSTEMTIME st;
|
|
Packit |
2997f0 |
FILETIME ft;
|
|
Packit |
2997f0 |
ULARGE_INTEGER d;
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
GetSystemTime(&st);
|
|
Packit |
2997f0 |
SystemTimeToFileTime(&st, &ft;;
|
|
Packit |
2997f0 |
d.HighPart = ft.dwHighDateTime;
|
|
Packit |
2997f0 |
d.LowPart = ft.dwLowDateTime;
|
|
Packit |
2997f0 |
tv->tv_sec = (long)((d.QuadPart - 116444736000000000llu) / 10000000L);
|
|
Packit |
2997f0 |
tv->tv_usec = (long)(st.wMilliseconds * 1000);
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
return 0;
|
|
Packit |
2997f0 |
}
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
#define rd_assert(EXPR) assert(EXPR)
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
/**
|
|
Packit |
2997f0 |
* Empty struct initializer
|
|
Packit |
2997f0 |
*/
|
|
Packit |
2997f0 |
#define RD_ZERO_INIT {0}
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
#ifndef __cplusplus
|
|
Packit |
2997f0 |
/**
|
|
Packit |
2997f0 |
* Sockets, IO
|
|
Packit |
2997f0 |
*/
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
/**
|
|
Packit |
2997f0 |
* @brief Set socket to non-blocking
|
|
Packit |
2997f0 |
* @returns 0 on success or -1 on failure (see rd_kafka_socket_errno)
|
|
Packit |
2997f0 |
*/
|
|
Packit |
2997f0 |
static RD_UNUSED int rd_fd_set_nonblocking (int fd) {
|
|
Packit |
2997f0 |
int on = 1;
|
|
Packit |
2997f0 |
if (ioctlsocket(fd, FIONBIO, &on) == SOCKET_ERROR)
|
|
Packit |
2997f0 |
return (int)WSAGetLastError();
|
|
Packit |
2997f0 |
return 0;
|
|
Packit |
2997f0 |
}
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
/**
|
|
Packit |
2997f0 |
* @brief Create non-blocking pipe
|
|
Packit |
2997f0 |
* @returns 0 on success or errno on failure
|
|
Packit |
2997f0 |
*/
|
|
Packit |
2997f0 |
static RD_UNUSED int rd_pipe_nonblocking (int *fds) {
|
|
Packit |
2997f0 |
HANDLE h[2];
|
|
Packit |
2997f0 |
int i;
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
if (!CreatePipe(&h[0], &h[1], NULL, 0))
|
|
Packit |
2997f0 |
return (int)GetLastError();
|
|
Packit |
2997f0 |
for (i = 0 ; i < 2 ; i++) {
|
|
Packit |
2997f0 |
DWORD mode = PIPE_NOWAIT;
|
|
Packit |
2997f0 |
/* Set non-blocking */
|
|
Packit |
2997f0 |
if (!SetNamedPipeHandleState(h[i], &mode, NULL, NULL)) {
|
|
Packit |
2997f0 |
CloseHandle(h[0]);
|
|
Packit |
2997f0 |
CloseHandle(h[1]);
|
|
Packit |
2997f0 |
return (int)GetLastError();
|
|
Packit |
2997f0 |
}
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
/* Open file descriptor for handle */
|
|
Packit |
2997f0 |
fds[i] = _open_osfhandle((intptr_t)h[i],
|
|
Packit |
2997f0 |
i == 0 ?
|
|
Packit |
2997f0 |
O_RDONLY | O_BINARY :
|
|
Packit |
2997f0 |
O_WRONLY | O_BINARY);
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
if (fds[i] == -1) {
|
|
Packit |
2997f0 |
CloseHandle(h[0]);
|
|
Packit |
2997f0 |
CloseHandle(h[1]);
|
|
Packit |
2997f0 |
return (int)GetLastError();
|
|
Packit |
2997f0 |
}
|
|
Packit |
2997f0 |
}
|
|
Packit |
2997f0 |
return 0;
|
|
Packit |
2997f0 |
}
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
#define rd_read(fd,buf,sz) _read(fd,buf,sz)
|
|
Packit |
2997f0 |
#define rd_write(fd,buf,sz) _write(fd,buf,sz)
|
|
Packit |
2997f0 |
#define rd_close(fd) closesocket(fd)
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
static RD_UNUSED char *
|
|
Packit |
2997f0 |
rd_strerror_w32 (DWORD errcode, char *dst, size_t dstsize) {
|
|
Packit |
2997f0 |
char *t;
|
|
Packit |
2997f0 |
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
|
|
Packit |
2997f0 |
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
Packit |
2997f0 |
NULL, errcode,
|
|
Packit |
2997f0 |
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
Packit |
2997f0 |
(LPSTR)dst, (DWORD)dstsize - 1, NULL);
|
|
Packit |
2997f0 |
/* Remove newlines */
|
|
Packit |
2997f0 |
while ((t = strchr(dst, (int)'\r')) || (t = strchr(dst, (int)'\n')))
|
|
Packit |
2997f0 |
*t = (char)'.';
|
|
Packit |
2997f0 |
return dst;
|
|
Packit |
2997f0 |
}
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
#endif /* !__cplusplus*/
|
|
Packit |
2997f0 |
|
|
Packit |
2997f0 |
#endif /* _RDWIN32_H_ */
|