From willi@REDACTED Sat May 3 20:53:48 2008 From: willi@REDACTED (willi) Date: Sat, 03 May 2008 21:53:48 +0300 Subject: [erlang-patches] [PATCH] ODBC server segfaults on 64-bit platform Message-ID: <1209840828.5859.1.camel@void.local.talk24.com> Hi, Please, consider this patch for inclusion. I've replaced SQLINTEGER with SQLLEN where it is mandated by ODBC specification. Without this modifications, ODBC driver segfaults on functions with SQLLEN type parameters on 64bit platforms. Tested on linux (both AMD64 and 32-bit). --- lib/odbc/c_src/odbcserver.c | 60 ++++++++++-------------------------------- lib/odbc/c_src/odbcserver.h | 6 ++-- 2 files changed, 18 insertions(+), 48 deletions(-) diff --git a/lib/odbc/c_src/odbcserver.c b/lib/odbc/c_src/odbcserver.c index a5d10ab..168f09f 100644 --- a/lib/odbc/c_src/odbcserver.c +++ b/lib/odbc/c_src/odbcserver.c @@ -154,8 +154,6 @@ static db_result_msg encode_value_list_scroll(SQLSMALLINT num_of_columns, db_state *state); static db_result_msg encode_row_count(SQLINTEGER num_of_rows, db_state *state); -static int encode_column(byte *buffer, int index, db_column column, - int column_nr, db_state *state); static void encode_column_dyn(db_column column, int column_nr, db_state *state); static void encode_data_type(SQLINTEGER sql_type, SQLINTEGER size, @@ -590,7 +588,7 @@ static db_result_msg db_query(byte *sql, db_state *state) static db_result_msg db_select_count(byte *sql, db_state *state) { SQLSMALLINT num_of_columns, intresult; - SQLINTEGER num_of_rows; + SQLLEN num_of_rows; SQLRETURN result; diagnos diagnos; db_result_msg msg; @@ -760,6 +758,7 @@ static db_result_msg db_param_query(byte *buffer, db_state *state) switch (param_status.param_status_array[i]) { case SQL_PARAM_SUCCESS: case SQL_PARAM_SUCCESS_WITH_INFO: + case SQL_PARAM_DIAG_UNAVAILABLE: break; default: diagnos = @@ -812,7 +811,7 @@ static db_result_msg db_describe_table(byte *sql, db_state *state) SQLSMALLINT num_of_columns; SQLCHAR name[MAX_NAME]; SQLSMALLINT name_len, sql_type, dec_digits, nullable; - SQLINTEGER size; + SQLLEN size; diagnos diagnos; int i; @@ -851,7 +850,7 @@ static db_result_msg db_describe_table(byte *sql, db_state *state) for (i = 0; i < num_of_columns; ++i) { if(!sql_success(SQLDescribeCol(statement_handle(state), - (SQLSMALLINT)(i+1), + (SQLUSMALLINT)(i+1), name, sizeof(name), &name_len, &sql_type, &size, &dec_digits, &nullable))) @@ -938,7 +937,8 @@ static db_result_msg encode_atom_message(char* atom) static db_result_msg encode_result(db_state *state) { SQLSMALLINT num_of_columns = 0; - SQLINTEGER RowCountPtr = 0, paramBatch = 0; + SQLLEN RowCountPtr = 0; + SQLINTEGER paramBatch = 0; db_result_msg msg; int elements, update, num_of_rows = 0; char *atom; @@ -1039,7 +1039,7 @@ static db_result_msg encode_column_name_list(SQLSMALLINT num_of_columns, db_result_msg msg; SQLCHAR name[MAX_NAME]; SQLSMALLINT name_len, sql_type, dec_digits, nullable; - SQLUINTEGER size; + SQLLEN size; SQLRETURN result; msg = encode_empty_message(); @@ -1224,48 +1224,11 @@ static db_result_msg encode_row_count(SQLINTEGER num_of_rows, return msg; } -/* Description: Encodes a column value into the buffer .*/ -static int encode_column(byte *buffer, int index, db_column column, - int column_nr, db_state *state) -{ - if(column.type.len == 0 || - column.type.strlen_or_indptr == SQL_NULL_DATA) - ei_encode_atom((char *)buffer, &index, "null"); - else { - switch(column.type.c) { - case SQL_C_CHAR: - ei_encode_string((char *)buffer, &index, column.buffer); - break; - case SQL_C_DOUBLE: - ei_encode_double((char *)buffer, &index, *(double *)column.buffer); - break; - case SQL_C_SLONG: - ei_encode_long((char *)buffer, &index, *(long *)column.buffer); - break; - case SQL_C_BIT: - ei_encode_atom((char *)buffer, &index, - column.buffer[0]?"true":"false"); - break; - case SQL_C_BINARY: - if (buffer == NULL) { - column = retrive_binary_data(column, column_nr, state); - } - ei_encode_string((char *)buffer, &index, (void *)column.buffer); - break; - default: - ei_encode_atom((char *)buffer, &index, "error"); - break; - } - } - return index; -} - /* Description: Encodes the a column value into the "ei_x" - dynamic_buffer held by the state variable */ static void encode_column_dyn(db_column column, int column_nr, db_state *state) { - if (column.type.len == 0 || column.type.strlen_or_indptr == SQL_NULL_DATA) { ei_x_encode_atom(&dynamic_buffer(state), "null"); @@ -1930,7 +1893,7 @@ static void init_param_column(param_array *params, byte *buffer, int *index, params->type.c = SQL_C_CHAR; params->type.col_size = (SQLUINTEGER)length; params->type.strlen_or_indptr_array = - (SQLUINTEGER*)safe_malloc(num_param_values + (SQLLEN*)safe_malloc(num_param_values * sizeof(SQL_NTS)); params->values.string = (byte *)safe_malloc((num_param_values + 1) * @@ -1977,8 +1940,15 @@ static void init_param_column(param_array *params, byte *buffer, int *index, static void init_param_statement(int cols, int num_param_values, db_state *state, param_status *status) { + int i; + status -> param_status_array = (SQLUSMALLINT *)safe_malloc(num_param_values * sizeof(SQLUSMALLINT)); + + for(i=0; i param_status_array[i] = SQL_PARAM_PROCEED; + } + status -> params_processed = 0; if(!sql_success(SQLAllocHandle(SQL_HANDLE_STMT, diff --git a/lib/odbc/c_src/odbcserver.h b/lib/odbc/c_src/odbcserver.h index 2e6146a..fb74bf8 100644 --- a/lib/odbc/c_src/odbcserver.h +++ b/lib/odbc/c_src/odbcserver.h @@ -118,9 +118,9 @@ typedef struct { SQLSMALLINT sql; SQLUINTEGER col_size; SQLSMALLINT decimal_digits; - SQLUINTEGER len; - SQLINTEGER strlen_or_indptr; - SQLINTEGER *strlen_or_indptr_array; + SQLLEN len; + SQLLEN strlen_or_indptr; + SQLLEN *strlen_or_indptr_array; } col_type; typedef struct { -- 1.5.4.3 From ingela@REDACTED Mon May 5 10:16:39 2008 From: ingela@REDACTED (Ingela Anderton Andin) Date: Mon, 05 May 2008 10:16:39 +0200 Subject: [erlang-patches] [PATCH] ODBC server segfaults on 64-bit platform In-Reply-To: <1209840828.5859.1.camel@void.local.talk24.com> References: <1209840828.5859.1.camel@void.local.talk24.com> Message-ID: <481EC267.6070008@erix.ericsson.se> Thank you for your patch. I have included it in our daily build. Hopefully it is just what we where wishing for :) We just currently tested odbc on a 64-bit platform and noticed problems related to SQLINTEGER, but as we have no actual demand for odbc on 64-bits form our financiers, this has very low priority. If all goes well it will be included in the next OTP-release. Regards Ingela - OTP team willi wrote: > Hi, > > Please, consider this patch for inclusion. I've replaced SQLINTEGER with SQLLEN where it is mandated by ODBC specification. > Without this modifications, ODBC driver segfaults on functions with SQLLEN type parameters on 64bit platforms. > Tested on linux (both AMD64 and 32-bit). > > --- > lib/odbc/c_src/odbcserver.c | 60 ++++++++++-------------------------------- > lib/odbc/c_src/odbcserver.h | 6 ++-- > 2 files changed, 18 insertions(+), 48 deletions(-) > > diff --git a/lib/odbc/c_src/odbcserver.c b/lib/odbc/c_src/odbcserver.c > index a5d10ab..168f09f 100644 > --- a/lib/odbc/c_src/odbcserver.c > +++ b/lib/odbc/c_src/odbcserver.c > @@ -154,8 +154,6 @@ static db_result_msg encode_value_list_scroll(SQLSMALLINT num_of_columns, > db_state *state); > static db_result_msg encode_row_count(SQLINTEGER num_of_rows, > db_state *state); > -static int encode_column(byte *buffer, int index, db_column column, > - int column_nr, db_state *state); > static void encode_column_dyn(db_column column, int column_nr, > db_state *state); > static void encode_data_type(SQLINTEGER sql_type, SQLINTEGER size, > @@ -590,7 +588,7 @@ static db_result_msg db_query(byte *sql, db_state *state) > static db_result_msg db_select_count(byte *sql, db_state *state) > { > SQLSMALLINT num_of_columns, intresult; > - SQLINTEGER num_of_rows; > + SQLLEN num_of_rows; > SQLRETURN result; > diagnos diagnos; > db_result_msg msg; > @@ -760,6 +758,7 @@ static db_result_msg db_param_query(byte *buffer, db_state *state) > switch (param_status.param_status_array[i]) { > case SQL_PARAM_SUCCESS: > case SQL_PARAM_SUCCESS_WITH_INFO: > + case SQL_PARAM_DIAG_UNAVAILABLE: > break; > default: > diagnos = > @@ -812,7 +811,7 @@ static db_result_msg db_describe_table(byte *sql, db_state *state) > SQLSMALLINT num_of_columns; > SQLCHAR name[MAX_NAME]; > SQLSMALLINT name_len, sql_type, dec_digits, nullable; > - SQLINTEGER size; > + SQLLEN size; > diagnos diagnos; > int i; > > @@ -851,7 +850,7 @@ static db_result_msg db_describe_table(byte *sql, db_state *state) > for (i = 0; i < num_of_columns; ++i) { > > if(!sql_success(SQLDescribeCol(statement_handle(state), > - (SQLSMALLINT)(i+1), > + (SQLUSMALLINT)(i+1), > name, sizeof(name), &name_len, > &sql_type, &size, &dec_digits, > &nullable))) > @@ -938,7 +937,8 @@ static db_result_msg encode_atom_message(char* atom) > static db_result_msg encode_result(db_state *state) > { > SQLSMALLINT num_of_columns = 0; > - SQLINTEGER RowCountPtr = 0, paramBatch = 0; > + SQLLEN RowCountPtr = 0; > + SQLINTEGER paramBatch = 0; > db_result_msg msg; > int elements, update, num_of_rows = 0; > char *atom; > @@ -1039,7 +1039,7 @@ static db_result_msg encode_column_name_list(SQLSMALLINT num_of_columns, > db_result_msg msg; > SQLCHAR name[MAX_NAME]; > SQLSMALLINT name_len, sql_type, dec_digits, nullable; > - SQLUINTEGER size; > + SQLLEN size; > SQLRETURN result; > > msg = encode_empty_message(); > @@ -1224,48 +1224,11 @@ static db_result_msg encode_row_count(SQLINTEGER num_of_rows, > return msg; > } > > -/* Description: Encodes a column value into the buffer .*/ > -static int encode_column(byte *buffer, int index, db_column column, > - int column_nr, db_state *state) > -{ > - if(column.type.len == 0 || > - column.type.strlen_or_indptr == SQL_NULL_DATA) > - ei_encode_atom((char *)buffer, &index, "null"); > - else { > - switch(column.type.c) { > - case SQL_C_CHAR: > - ei_encode_string((char *)buffer, &index, column.buffer); > - break; > - case SQL_C_DOUBLE: > - ei_encode_double((char *)buffer, &index, *(double *)column.buffer); > - break; > - case SQL_C_SLONG: > - ei_encode_long((char *)buffer, &index, *(long *)column.buffer); > - break; > - case SQL_C_BIT: > - ei_encode_atom((char *)buffer, &index, > - column.buffer[0]?"true":"false"); > - break; > - case SQL_C_BINARY: > - if (buffer == NULL) { > - column = retrive_binary_data(column, column_nr, state); > - } > - ei_encode_string((char *)buffer, &index, (void *)column.buffer); > - break; > - default: > - ei_encode_atom((char *)buffer, &index, "error"); > - break; > - } > - } > - return index; > -} > - > /* Description: Encodes the a column value into the "ei_x" - dynamic_buffer > held by the state variable */ > static void encode_column_dyn(db_column column, int column_nr, > db_state *state) > { > - > if (column.type.len == 0 || > column.type.strlen_or_indptr == SQL_NULL_DATA) { > ei_x_encode_atom(&dynamic_buffer(state), "null"); > @@ -1930,7 +1893,7 @@ static void init_param_column(param_array *params, byte *buffer, int *index, > params->type.c = SQL_C_CHAR; > params->type.col_size = (SQLUINTEGER)length; > params->type.strlen_or_indptr_array = > - (SQLUINTEGER*)safe_malloc(num_param_values > + (SQLLEN*)safe_malloc(num_param_values > * sizeof(SQL_NTS)); > params->values.string = > (byte *)safe_malloc((num_param_values + 1) * > @@ -1977,8 +1940,15 @@ static void init_param_column(param_array *params, byte *buffer, int *index, > static void init_param_statement(int cols, int num_param_values, > db_state *state, param_status *status) > { > + int i; > + > status -> param_status_array = > (SQLUSMALLINT *)safe_malloc(num_param_values * sizeof(SQLUSMALLINT)); > + > + for(i=0; i + status -> param_status_array[i] = SQL_PARAM_PROCEED; > + } > + > status -> params_processed = 0; > > if(!sql_success(SQLAllocHandle(SQL_HANDLE_STMT, > diff --git a/lib/odbc/c_src/odbcserver.h b/lib/odbc/c_src/odbcserver.h > index 2e6146a..fb74bf8 100644 > --- a/lib/odbc/c_src/odbcserver.h > +++ b/lib/odbc/c_src/odbcserver.h > @@ -118,9 +118,9 @@ typedef struct { > SQLSMALLINT sql; > SQLUINTEGER col_size; > SQLSMALLINT decimal_digits; > - SQLUINTEGER len; > - SQLINTEGER strlen_or_indptr; > - SQLINTEGER *strlen_or_indptr_array; > + SQLLEN len; > + SQLLEN strlen_or_indptr; > + SQLLEN *strlen_or_indptr_array; > } col_type; > > typedef struct { > From bjorn@REDACTED Tue May 6 11:54:46 2008 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 06 May 2008 11:54:46 +0200 Subject: [erlang-patches] init:stop/1 In-Reply-To: References: Message-ID: Magnus Froberg writes: > a patch that makes it possible to terminate an erlang system using > init:stop with a specified Status code (ala erlang:halt/1). > > Handy if one need to terminate the system cleanly but want an > exit code that can be checked. > > The patch is for R11B-2. Thanks! We will include it in R12B-3. /Bjorn -- Bj?rn Gustavsson, Erlang/OTP, Ericsson AB From zl9d97p02@REDACTED Wed May 7 01:15:32 2008 From: zl9d97p02@REDACTED (Simon Cornish) Date: Tue, 6 May 2008 16:15:32 -0700 Subject: [erlang-patches] erl_interface bugs Message-ID: <23446-20457@sneakemail.com> Hi, The attached patch for R12B-2 fixes some long-standing (since R9C-0) bugs in erl_interface. Also added is the ability to compare terms of type ERL_STRING_EXT and ERL_LIST_EXT. Regards, Simon -------------- next part -------------- A non-text attachment was scrubbed... Name: erl_interface.patch Type: application/octet-stream Size: 4092 bytes Desc: not available URL: From per@REDACTED Sun May 11 22:08:43 2008 From: per@REDACTED (Per Hedeland) Date: Sun, 11 May 2008 22:08:43 +0200 (CEST) Subject: [erlang-patches] Changing time Message-ID: <200805112008.m4BK8hCZ074013@pluto.hedeland.org> Hi, The Erlang emulator includes some sophisticated code to deal with sudden changes to the system time, which tries to maintain "delta" timers such as 'receive ... after' while gradually adapting time-of-day as seen by the emulator to agree with with the new system time. Unfortunately this code works only on Linux and Solaris (maybe on Windows too, I wouldn't know) - on other systems, e.g. *BSD, you can play this game: 1. Start erlang. 2. Set the system time back by, say, 5 minutes. 3. Invoke timer:sleep(1). 4. Watch the call take 5 minutes to complete. Now, system time "shouldn't" move backwards, but in real life it sometimes does, and "don't do that" isn't always a viable response. And while "weird" things may happen to timers that are running across the time change, I think it definitely violates the POLA that timers started *after* the time change are completely broken. A suggested fix is below (diff against R12B-2) - as far as I can see, it will work pretty well both for timers running across the time change and for timers started after it - worst case it will cause one timer to have double the requested timeout, but once the new system time has been discovered, it should Do the Right Thing, and it's independent of the magnitude of the time change. By the way, the discussion about the +c option in the erl(1) man page is wrong - Erlang timers are not based on erlang:now/0. Timers and erlang:now/0 use the same underlying timing mechanism, which may or may not have compensation for "sudden changes of system time" depending on the OS and the usage of +c, but erlang:now/0 fulfills its promise of delivering monotonously increasing numbers regardless - also with the patch below. --Per Hedeland --- erts/emulator/beam/erl_time_sup.c.orig 2008-04-07 15:58:13.000000000 +0200 +++ erts/emulator/beam/erl_time_sup.c 2008-05-09 23:15:39.000000000 +0200 @@ -383,13 +383,12 @@ CLOCK_RESOLUTION; /* Sometimes the time jump backwards, - resulting in a negative elapsed time. We compensate for - this by simply pretend as if the time stood still. :) */ + resulting in a negative elapsed time. */ if (elapsed > 0) { do_time_add(elapsed); - last_delivered = cur_time; } + last_delivered = cur_time; } #endif