Changeset: d947ddc7c002 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/d947ddc7c002 Modified Files: sql/server/rel_select.c Branch: label Log Message:
merged with default diffs (truncated from 4080 to 300 lines): diff --git a/clients/Tests/exports.stable.out b/clients/Tests/exports.stable.out --- a/clients/Tests/exports.stable.out +++ b/clients/Tests/exports.stable.out @@ -745,12 +745,23 @@ const char *mo_find_option(opt *set, int void mo_free_options(opt *set, int setlen); void mo_print_options(opt *set, int setlen); int mo_system_config(opt **Set, int setlen); +mparm mparm_enumerate(int i); +bool mparm_is_core(mparm parm); +const char *mparm_name(mparm parm); mparm mparm_parse(const char *name); +char *msetting_as_string(const msettings *mp, mparm parm); bool msetting_bool(const msettings *mp, mparm parm); long msetting_long(const msettings *mp, mparm parm); +const char *msetting_parm_name(const msettings *mp, mparm parm); +msettings_error msetting_parse(msettings *mp, mparm parm, const char *text); int msetting_parse_bool(const char *text); +msettings_error msetting_set_bool(msettings *mp, mparm parm, bool value); +msettings_error msetting_set_ignored(msettings *mp, const char *key, const char *value); +msettings_error msetting_set_long(msettings *mp, mparm parm, long value); msettings_error msetting_set_named(msettings *mp, bool allow_core, const char *key, const char *value); +msettings_error msetting_set_string(msettings *mp, mparm parm, const char *value) __attribute__((__nonnull__(3))); const char *msetting_string(const msettings *mp, mparm parm); +msettings *msettings_clone(const msettings *mp); long msettings_connect_binary(const msettings *mp); const char *msettings_connect_certhash_digits(const msettings *mp); const char *msettings_connect_clientcert(const msettings *mp); @@ -761,8 +772,12 @@ const char *msettings_connect_tcp(const enum msetting_tls_verify msettings_connect_tls_verify(const msettings *mp); const char *msettings_connect_unix(const msettings *mp); msettings *msettings_create(void); +const msettings *msettings_default; msettings *msettings_destroy(msettings *mp); +bool msettings_malloc_failed(msettings_error err); bool msettings_parse_url(msettings *mp, const char *url, char **error_buffer); +void msettings_reset(msettings *mp); +void msettings_set_localizer(msettings *mp, const char *(*localizer)(const void *data, mparm parm), void *data); bool msettings_validate(msettings *mp, char **errmsg); const char *wsaerror(int); diff --git a/clients/examples/C/testsfile.c b/clients/examples/C/testsfile.c --- a/clients/examples/C/testsfile.c +++ b/clients/examples/C/testsfile.c @@ -85,7 +85,7 @@ handle_set_command(const char *location, { msettings_error msg = msetting_set_named(mp, true, key, value); if (msg) { - fprintf(stderr, "%s: cannot set '%s': %s\n", location, key, msg); + fprintf(stderr, "%s: %s\n", location, msg); return false; } return true; diff --git a/clients/mapiclient/mclient.c b/clients/mapiclient/mclient.c --- a/clients/mapiclient/mclient.c +++ b/clients/mapiclient/mclient.c @@ -174,7 +174,7 @@ static char *nullstring = default_nullst static timertype gettime(void) { - /* Return the time in milliseconds since an epoch. The epoch + /* Return the time in microseconds since an epoch. The epoch is roughly the time this program started. */ #ifdef _MSC_VER static LARGE_INTEGER freq, start; /* automatically initialized to 0 */ diff --git a/clients/mapilib/connect.c b/clients/mapilib/connect.c --- a/clients/mapilib/connect.c +++ b/clients/mapilib/connect.c @@ -144,6 +144,17 @@ establish_connection(Mapi mid) msg = mapi_handshake(mid); } + // Switch from MP_CONNECT_TIMEOUT to MP_REPLY_TIMEOUT + if (msg == MOK) { + long connect_timeout = msetting_long(mid->settings, MP_CONNECT_TIMEOUT); + long reply_timeout = msetting_long(mid->settings, MP_REPLY_TIMEOUT); + if (connect_timeout > 0 || reply_timeout > 0) { + if (reply_timeout < 0) + reply_timeout = 0; + msg = mapi_timeout(mid, reply_timeout); + } + } + return msg; } @@ -153,6 +164,7 @@ connect_socket(Mapi mid) assert(!mid->connected); const char *sockname = msettings_connect_unix(mid->settings); const char *tcp_host = msettings_connect_tcp(mid->settings); + long timeout = msetting_long(mid->settings, MP_CONNECT_TIMEOUT); assert(*sockname || *tcp_host); do { @@ -165,6 +177,11 @@ connect_socket(Mapi mid) return mid->error; } while (0); + // the socket code may have set SO_SNDTIMEO and SO_RCVTIMEO but + // the mapi layer doesn't know this yet. + if (timeout > 0) + mapi_timeout(mid, timeout); + mid->connected = true; return MOK; } @@ -293,6 +310,8 @@ connect_socket_tcp(Mapi mid) static SOCKET connect_socket_tcp_addr(Mapi mid, struct addrinfo *info) { + long timeout = msetting_long(mid->settings, MP_CONNECT_TIMEOUT); + if (mid->tracelog) { char addrbuf[100] = {0}; const char *addrtext; @@ -311,7 +330,7 @@ connect_socket_tcp_addr(Mapi mid, struct port = -1; addrtext = NULL; } - mapi_log_record(mid, "CONN", "Trying IP %s port %d", addrtext ? addrtext : "<UNKNOWN>", port); + mapi_log_record(mid, "CONN", "Trying IP %s port %d wih timeout %ld", addrtext ? addrtext : "<UNKNOWN>", port, timeout); } @@ -332,6 +351,23 @@ connect_socket_tcp_addr(Mapi mid, struct (void) fcntl(s, F_SETFD, FD_CLOEXEC); #endif + if (timeout > 0) { + struct timeval tv = { + .tv_sec = timeout / 1000, + .tv_usec = timeout % 1000, + }; + /* cast to char * for Windows, no harm on "normal" systems */ + if ( + setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char*)&tv, sizeof(tv)) == SOCKET_ERROR + || setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(tv)) == SOCKET_ERROR + ) { + closesocket(s); + return mapi_printError( + mid, __func__, MERROR, + "could not set connect timeout: %s", strerror(errno)); + } + } + // cast addrlen to int to satisfy Windows. if (connect(s, info->ai_addr, (int)info->ai_addrlen) == SOCKET_ERROR) { mapi_printError( diff --git a/clients/mapilib/connect_unix.c b/clients/mapilib/connect_unix.c --- a/clients/mapilib/connect_unix.c +++ b/clients/mapilib/connect_unix.c @@ -130,15 +130,16 @@ connect_socket_unix(Mapi mid) { const char *sockname = msettings_connect_unix(mid->settings); assert (*sockname != '\0'); + long timeout = msetting_long(mid->settings, MP_CONNECT_TIMEOUT); - mapi_log_record(mid, "CONN", "Connecting to Unix domain socket %s", sockname); + mapi_log_record(mid, "CONN", "Connecting to Unix domain socket %s with timeout %ld", sockname, timeout); struct sockaddr_un userver; if (strlen(sockname) >= sizeof(userver.sun_path)) { return mapi_printError(mid, __func__, MERROR, "path name '%s' too long", sockname); } - // Create the socket, taking care of CLOEXEC + // Create the socket, taking care of CLOEXEC and SNDTIMEO #ifdef SOCK_CLOEXEC int s = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); @@ -154,6 +155,22 @@ connect_socket_unix(Mapi mid) (void) fcntl(s, F_SETFD, FD_CLOEXEC); #endif + if (timeout > 0) { + struct timeval tv = { + .tv_sec = timeout / 1000, + .tv_usec = timeout % 1000, + }; + if ( + setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) == SOCKET_ERROR + || setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == SOCKET_ERROR + ) { + closesocket(s); + return mapi_printError( + mid, __func__, MERROR, + "could not set connect timeout: %s", strerror(errno)); + } + } + // Attempt to connect userver = (struct sockaddr_un) { diff --git a/clients/mapilib/msettings.c b/clients/mapilib/msettings.c --- a/clients/mapilib/msettings.c +++ b/clients/mapilib/msettings.c @@ -13,6 +13,7 @@ #include "monetdb_config.h" #include "msettings.h" +#include "mstring.h" #include <assert.h> #include <ctype.h> @@ -25,7 +26,17 @@ #include <strings.h> #endif -#define FATAL() do { fprintf(stderr, "\n\n abort in params.c: %s\n\n", __func__); abort(); } while (0) +#define FATAL() do { fprintf(stderr, "\n\n abort in msettings.c: %s\n\n", __func__); abort(); } while (0) + +static const char * const MALLOC_FAILED = "malloc failed"; + +bool +msettings_malloc_failed(msettings_error err) +{ + return ((const char*)err == (const char*)MALLOC_FAILED); +} + + int msetting_parse_bool(const char *text) { @@ -49,22 +60,19 @@ char* allocprintf(const char *fmt, ...) char * allocprintf(const char *fmt, ...) { - size_t buflen = 80; - while (1) { - char *buf = malloc(buflen); - if (buf == NULL) - return NULL; - va_list ap; - va_start(ap, fmt); - int n = vsnprintf(buf, buflen, fmt, ap); - va_end(ap); - if (n >= 0 && (size_t)n < buflen) - return buf; - free(buf); - if (n < 0) - return NULL; - buflen = n + 1; - } + va_list ap; + char *buf = NULL; + size_t pos = 0, cap = 0; + int n; + + va_start(ap, fmt); + n = vreallocprintf(&buf, &pos, &cap, fmt, ap); + va_end(ap); + + if (n >= 0) + return buf; + free(buf); + return NULL; } @@ -78,12 +86,15 @@ by_name[] = { { .name="certhash", .parm=MP_CERTHASH }, { .name="clientcert", .parm=MP_CLIENTCERT }, { .name="clientkey", .parm=MP_CLIENTKEY }, + { .name="connect_timeout", .parm=MP_CONNECT_TIMEOUT }, { .name="database", .parm=MP_DATABASE }, { .name="host", .parm=MP_HOST }, { .name="language", .parm=MP_LANGUAGE }, + { .name="map_to_long_varchar", .parm=MP_MAPTOLONGVARCHAR }, { .name="password", .parm=MP_PASSWORD }, { .name="port", .parm=MP_PORT }, { .name="replysize", .parm=MP_REPLYSIZE }, + { .name="reply_timeout", .parm=MP_REPLY_TIMEOUT }, { .name="fetchsize", .parm=MP_REPLYSIZE }, { .name="schema", .parm=MP_SCHEMA }, { .name="sock", .parm=MP_SOCK }, @@ -94,9 +105,10 @@ by_name[] = { { .name="tls", .parm=MP_TLS }, { .name="user", .parm=MP_USER }, // + { .name="logfile", .parm=MP_LOGFILE }, + // { .name="hash", .parm=MP_IGNORE }, { .name="debug", .parm=MP_IGNORE }, - { .name="logfile", .parm=MP_IGNORE }, }; mparm @@ -111,6 +123,15 @@ mparm_parse(const char *name) return strchr(name, '_') ? MP_IGNORE : MP_UNKNOWN; } +mparm +mparm_enumerate(int i) +{ + int n = sizeof(by_name) / sizeof(by_name[0]); + if (i < 0 || i >= n) + return MP_UNKNOWN; + return by_name[i].parm; +} + const char * _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org