Kaynağa Gözat

Protect all public functions against invalid context

- change return argument from void to int
- update documentation
Stéphane Raimbault 12 yıl önce
ebeveyn
işleme
55d9a371f1

+ 2 - 2
doc/modbus_get_byte_timeout.txt

@@ -9,7 +9,7 @@ modbus_get_byte_timeout - get timeout between bytes
 
 SYNOPSIS
 --------
-*void modbus_get_byte_timeout(modbus_t *'ctx', struct timeval *'timeout');*
+*int modbus_get_byte_timeout(modbus_t *'ctx', struct timeval *'timeout');*
 
 
 DESCRIPTION
@@ -20,7 +20,7 @@ between two consecutive bytes of the same message in the 'timeout' argument.
 
 RETURN VALUE
 ------------
-There is no return values.
+The function shall return 0 if successful. Otherwise it shall return -1 and set errno.
 
 
 EXAMPLE

+ 2 - 2
doc/modbus_get_response_timeout.txt

@@ -9,7 +9,7 @@ modbus_get_response_timeout - get timeout for response
 
 SYNOPSIS
 --------
-*void modbus_get_response_timeout(modbus_t *'ctx', struct timeval *'timeout');*
+*int modbus_get_response_timeout(modbus_t *'ctx', struct timeval *'timeout');*
 
 
 DESCRIPTION
@@ -20,7 +20,7 @@ used to wait for a response in the 'timeout' argument.
 
 RETURN VALUE
 ------------
-There is no return values.
+The function shall return 0 if successful. Otherwise it shall return -1 and set errno.
 
 
 EXAMPLE

+ 2 - 1
doc/modbus_get_socket.txt

@@ -20,7 +20,8 @@ descriptor of the libmodbus context.
 
 RETURN VALUE
 ------------
-The current socket or file descriptor of the context.
+The function returns the current socket or file descriptor of the context if
+successful. Otherwise it shall return -1 and set errno.
 
 
 SEE ALSO

+ 2 - 1
doc/modbus_set_byte_timeout.txt

@@ -22,9 +22,10 @@ If the timeout value has a tv_sec of -1 then this timeout will not be used at
 all. This results in modbus_set_response_timeout governing the entire timeout
 duration of an operation.
 
+
 RETURN VALUE
 ------------
-There is no return values.
+The function shall return 0 if successful. Otherwise it shall return -1 and set errno.
 
 
 SEE ALSO

+ 2 - 2
doc/modbus_set_debug.txt

@@ -8,7 +8,7 @@ modbus_set_debug - set debug flag of the context
 
 SYNOPSIS
 --------
-*void modbus_set_debug(modbus_t *'ctx', int 'boolean');*
+*int modbus_set_debug(modbus_t *'ctx', int 'boolean');*
 
 
 DESCRIPTION
@@ -28,7 +28,7 @@ ___________________
 
 RETURN VALUE
 ------------
-There is no return values.
+The function shall return 0 if successful. Otherwise it shall return -1 and set errno.
 
 
 AUTHORS

+ 2 - 2
doc/modbus_set_response_timeout.txt

@@ -9,7 +9,7 @@ modbus_set_response_timeout - set timeout for response
 
 SYNOPSIS
 --------
-*void modbus_set_response_timeout(modbus_t *'ctx', struct timeval *'timeout');*
+*int modbus_set_response_timeout(modbus_t *'ctx', struct timeval *'timeout');*
 
 
 DESCRIPTION
@@ -21,7 +21,7 @@ the given timeout, an error will be raised.
 
 RETURN VALUE
 ------------
-There is no return values.
+The function shall return 0 if successful. Otherwise it shall return -1 and set errno.
 
 
 EXAMPLE

+ 2 - 2
doc/modbus_set_socket.txt

@@ -9,7 +9,7 @@ modbus_set_socket - set socket of the context
 
 SYNOPSIS
 --------
-*void modbus_set_socket(modbus_t *'ctx', int 'socket');*
+*int modbus_set_socket(modbus_t *'ctx', int 'socket');*
 
 
 DESCRIPTION
@@ -21,7 +21,7 @@ connections to the same server.
 
 RETURN VALUE
 ------------
-There is no return values.
+The function shall return 0 if successful. Otherwise it shall return -1 and set errno.
 
 
 EXAMPLE

+ 24 - 4
src/modbus-rtu.c

@@ -567,8 +567,6 @@ static int _modbus_rtu_connect(modbus_t *ctx)
     /* Don't want errors to be blocking */
     dcb.fAbortOnError = FALSE;
 
-    /* TODO: any other flags!? */
-
     /* Setup port */
     if (!SetCommState(ctx_rtu->w_ser.fd, &dcb)) {
         fprintf(stderr, "ERROR Error setting new configuration (LastError %d)\n",
@@ -900,6 +898,11 @@ static int _modbus_rtu_connect(modbus_t *ctx)
 
 int modbus_rtu_set_serial_mode(modbus_t *ctx, int mode)
 {
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) {
 #if HAVE_DECL_TIOCSRS485
         modbus_rtu_t *ctx_rtu = ctx->backend_data;
@@ -939,7 +942,13 @@ int modbus_rtu_set_serial_mode(modbus_t *ctx, int mode)
     return -1;
 }
 
-int modbus_rtu_get_serial_mode(modbus_t *ctx) {
+int modbus_rtu_get_serial_mode(modbus_t *ctx)
+{
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) {
 #if HAVE_DECL_TIOCSRS485
         modbus_rtu_t *ctx_rtu = ctx->backend_data;
@@ -959,6 +968,11 @@ int modbus_rtu_get_serial_mode(modbus_t *ctx) {
 
 int modbus_rtu_set_rts(modbus_t *ctx, int mode)
 {
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) {
 #if HAVE_DECL_TIOCM_RTS
         modbus_rtu_t *ctx_rtu = ctx->backend_data;
@@ -985,7 +999,13 @@ int modbus_rtu_set_rts(modbus_t *ctx, int mode)
     return -1;
 }
 
-int modbus_rtu_get_rts(modbus_t *ctx) {
+int modbus_rtu_get_rts(modbus_t *ctx)
+{
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) {
 #if HAVE_DECL_TIOCM_RTS
         modbus_rtu_t *ctx_rtu = ctx->backend_data;

+ 26 - 2
src/modbus-tcp.c

@@ -467,7 +467,14 @@ int modbus_tcp_listen(modbus_t *ctx, int nb_connection)
     int new_socket;
     int yes;
     struct sockaddr_in addr;
-    modbus_tcp_t *ctx_tcp = ctx->backend_data;
+    modbus_tcp_t *ctx_tcp;
+
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    ctx_tcp = ctx->backend_data;
 
 #ifdef OS_WIN32
     if (_modbus_tcp_init_win32() == -1) {
@@ -514,7 +521,14 @@ int modbus_tcp_pi_listen(modbus_t *ctx, int nb_connection)
     const char *node;
     const char *service;
     int new_socket;
-    modbus_tcp_pi_t *ctx_tcp_pi = ctx->backend_data;
+    modbus_tcp_pi_t *ctx_tcp_pi;
+
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    ctx_tcp_pi = ctx->backend_data;
 
     if (ctx_tcp_pi->node[0] == 0)
         node = NULL; /* == any */
@@ -609,6 +623,11 @@ int modbus_tcp_accept(modbus_t *ctx, int *socket)
     struct sockaddr_in addr;
     socklen_t addrlen;
 
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     addrlen = sizeof(addr);
 #ifdef HAVE_ACCEPT4
     /* Inherit socket flags and use accept4 call */
@@ -636,6 +655,11 @@ int modbus_tcp_pi_accept(modbus_t *ctx, int *socket)
     struct sockaddr_storage addr;
     socklen_t addrlen;
 
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     addrlen = sizeof(addr);
     ctx->s = accept(*socket, (void *)&addr, &addrlen);
     if (ctx->s == -1) {

+ 152 - 8
src/modbus.c

@@ -121,6 +121,11 @@ static void _sleep_response_timeout(modbus_t *ctx)
 
 int modbus_flush(modbus_t *ctx)
 {
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     int rc = ctx->backend->flush(ctx);
     if (rc != -1 && ctx->debug) {
         /* Not all backends are able to return the number of bytes flushed */
@@ -217,6 +222,11 @@ int modbus_send_raw_request(modbus_t *ctx, uint8_t *raw_req, int raw_req_length)
     uint8_t req[MAX_MESSAGE_LENGTH];
     int req_length;
 
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     if (raw_req_length < 2) {
         /* The raw request must contain function and slave at least */
         errno = EINVAL;
@@ -468,6 +478,11 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
 /* Receive the request from a modbus master */
 int modbus_receive(modbus_t *ctx, uint8_t *req)
 {
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     return ctx->backend->receive(ctx, req);
 }
 
@@ -481,6 +496,11 @@ int modbus_receive(modbus_t *ctx, uint8_t *req)
 */
 int modbus_receive_confirmation(modbus_t *ctx, uint8_t *rsp)
 {
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     return _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
 }
 
@@ -672,6 +692,11 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
     int rsp_length = 0;
     sft_t sft;
 
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     sft.slave = slave;
     sft.function = function;
     sft.t_id = ctx->backend->prepare_response_tid(req, &req_length);
@@ -960,6 +985,11 @@ int modbus_reply_exception(modbus_t *ctx, const uint8_t *req,
     int dummy_length = 99;
     sft_t sft;
 
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     sft.slave = slave;
     sft.function = function + 0x80;;
     sft.t_id = ctx->backend->prepare_response_tid(req, &dummy_length);
@@ -1025,6 +1055,11 @@ int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest)
 {
     int rc;
 
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     if (nb > MODBUS_MAX_READ_BITS) {
         if (ctx->debug) {
             fprintf(stderr,
@@ -1049,6 +1084,11 @@ int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest)
 {
     int rc;
 
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     if (nb > MODBUS_MAX_READ_BITS) {
         if (ctx->debug) {
             fprintf(stderr,
@@ -1119,6 +1159,11 @@ int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest)
 {
     int status;
 
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     if (nb > MODBUS_MAX_READ_REGISTERS) {
         if (ctx->debug) {
             fprintf(stderr,
@@ -1140,6 +1185,11 @@ int modbus_read_input_registers(modbus_t *ctx, int addr, int nb,
 {
     int status;
 
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     if (nb > MODBUS_MAX_READ_REGISTERS) {
         fprintf(stderr,
                 "ERROR Too many input registers requested (%d > %d)\n",
@@ -1162,6 +1212,11 @@ static int write_single(modbus_t *ctx, int function, int addr, int value)
     int req_length;
     uint8_t req[_MIN_REQ_LENGTH];
 
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     req_length = ctx->backend->build_request_basis(ctx, function, addr, value, req);
 
     rc = send_msg(ctx, req, req_length);
@@ -1182,6 +1237,11 @@ static int write_single(modbus_t *ctx, int function, int addr, int value)
 /* Turns ON or OFF a single bit of the remote device */
 int modbus_write_bit(modbus_t *ctx, int addr, int status)
 {
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     return write_single(ctx, _FC_WRITE_SINGLE_COIL, addr,
                         status ? 0xFF00 : 0);
 }
@@ -1189,6 +1249,11 @@ int modbus_write_bit(modbus_t *ctx, int addr, int status)
 /* Writes a value in one register of the remote device */
 int modbus_write_register(modbus_t *ctx, int addr, int value)
 {
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     return write_single(ctx, _FC_WRITE_SINGLE_REGISTER, addr, value);
 }
 
@@ -1201,9 +1266,13 @@ int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src)
     int req_length;
     int bit_check = 0;
     int pos = 0;
-
     uint8_t req[MAX_MESSAGE_LENGTH];
 
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     if (nb > MODBUS_MAX_WRITE_BITS) {
         if (ctx->debug) {
             fprintf(stderr, "ERROR Writing too many bits (%d > %d)\n",
@@ -1258,9 +1327,13 @@ int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src)
     int i;
     int req_length;
     int byte_count;
-
     uint8_t req[MAX_MESSAGE_LENGTH];
 
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     if (nb > MODBUS_MAX_WRITE_REGISTERS) {
         if (ctx->debug) {
             fprintf(stderr,
@@ -1341,6 +1414,11 @@ int modbus_write_and_read_registers(modbus_t *ctx,
     uint8_t req[MAX_MESSAGE_LENGTH];
     uint8_t rsp[MAX_MESSAGE_LENGTH];
 
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     if (write_nb > MODBUS_MAX_RW_WRITE_REGISTERS) {
         if (ctx->debug) {
             fprintf(stderr,
@@ -1409,6 +1487,11 @@ int modbus_report_slave_id(modbus_t *ctx, uint8_t *dest)
     int req_length;
     uint8_t req[_MIN_REQ_LENGTH];
 
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     req_length = ctx->backend->build_request_basis(ctx, _FC_REPORT_SLAVE_ID,
                                                    0, 0, req);
 
@@ -1460,56 +1543,111 @@ void _modbus_init_common(modbus_t *ctx)
 /* Define the slave number */
 int modbus_set_slave(modbus_t *ctx, int slave)
 {
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     return ctx->backend->set_slave(ctx, slave);
 }
 
 int modbus_set_error_recovery(modbus_t *ctx,
                               modbus_error_recovery_mode error_recovery)
 {
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     /* The type of modbus_error_recovery_mode is unsigned enum */
     ctx->error_recovery = (uint8_t) error_recovery;
     return 0;
 }
 
-void modbus_set_socket(modbus_t *ctx, int socket)
+int modbus_set_socket(modbus_t *ctx, int socket)
 {
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     ctx->s = socket;
+    return 0;
 }
 
 int modbus_get_socket(modbus_t *ctx)
 {
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     return ctx->s;
 }
 
 /* Get the timeout interval used to wait for a response */
-void modbus_get_response_timeout(modbus_t *ctx, struct timeval *timeout)
+int modbus_get_response_timeout(modbus_t *ctx, struct timeval *timeout)
 {
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     *timeout = ctx->response_timeout;
+    return 0;
 }
 
-void modbus_set_response_timeout(modbus_t *ctx, const struct timeval *timeout)
+int modbus_set_response_timeout(modbus_t *ctx, const struct timeval *timeout)
 {
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     ctx->response_timeout = *timeout;
+    return 0;
 }
 
 /* Get the timeout interval between two consecutive bytes of a message */
-void modbus_get_byte_timeout(modbus_t *ctx, struct timeval *timeout)
+int modbus_get_byte_timeout(modbus_t *ctx, struct timeval *timeout)
 {
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     *timeout = ctx->byte_timeout;
+    return 0;
 }
 
-void modbus_set_byte_timeout(modbus_t *ctx, const struct timeval *timeout)
+int modbus_set_byte_timeout(modbus_t *ctx, const struct timeval *timeout)
 {
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     ctx->byte_timeout = *timeout;
+    return 0;
 }
 
 int modbus_get_header_length(modbus_t *ctx)
 {
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     return ctx->backend->header_length;
 }
 
 int modbus_connect(modbus_t *ctx)
 {
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     return ctx->backend->connect(ctx);
 }
 
@@ -1529,9 +1667,15 @@ void modbus_free(modbus_t *ctx)
     ctx->backend->free(ctx);
 }
 
-void modbus_set_debug(modbus_t *ctx, int boolean)
+int modbus_set_debug(modbus_t *ctx, int boolean)
 {
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
     ctx->debug = boolean;
+    return 0;
 }
 
 /* Allocates 4 arrays to store bits, input bits, registers and inputs

+ 6 - 6
src/modbus.h

@@ -156,14 +156,14 @@ typedef enum
 
 EXPORT int modbus_set_slave(modbus_t* ctx, int slave);
 EXPORT int modbus_set_error_recovery(modbus_t *ctx, modbus_error_recovery_mode error_recovery);
-EXPORT void modbus_set_socket(modbus_t *ctx, int socket);
+EXPORT int modbus_set_socket(modbus_t *ctx, int socket);
 EXPORT int modbus_get_socket(modbus_t *ctx);
 
-EXPORT void modbus_get_response_timeout(modbus_t *ctx, struct timeval *timeout);
-EXPORT void modbus_set_response_timeout(modbus_t *ctx, const struct timeval *timeout);
+EXPORT int modbus_get_response_timeout(modbus_t *ctx, struct timeval *timeout);
+EXPORT int modbus_set_response_timeout(modbus_t *ctx, const struct timeval *timeout);
 
-EXPORT void modbus_get_byte_timeout(modbus_t *ctx, struct timeval *timeout);
-EXPORT void modbus_set_byte_timeout(modbus_t *ctx, const struct timeval *timeout);
+EXPORT int modbus_get_byte_timeout(modbus_t *ctx, struct timeval *timeout);
+EXPORT int modbus_set_byte_timeout(modbus_t *ctx, const struct timeval *timeout);
 
 EXPORT int modbus_get_header_length(modbus_t *ctx);
 
@@ -173,7 +173,7 @@ EXPORT void modbus_close(modbus_t *ctx);
 EXPORT void modbus_free(modbus_t *ctx);
 
 EXPORT int modbus_flush(modbus_t *ctx);
-EXPORT void modbus_set_debug(modbus_t *ctx, int boolean);
+EXPORT int modbus_set_debug(modbus_t *ctx, int boolean);
 
 EXPORT const char *modbus_strerror(int errnum);