Blame src/rdwin32.h

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_ */