[Spice-devel] [PATCH 1/5] Make a set of changes to the parser code to enable it to compile inside the kernel tree.

Jeremy White jwhite at codeweavers.com
Tue Jun 30 13:57:38 PDT 2015


This would allow us to use the same code for the user
space tools as we use for the kernel module.

Signed-off-by: Jeremy White <jwhite at codeweavers.com>
---
 usbredirparser/strtok_r.c             |  4 ++
 usbredirparser/usbredirfilter.c       | 55 +++++++++++++++++++-----
 usbredirparser/usbredirfilter.h       |  4 ++
 usbredirparser/usbredirparser.c       | 80 ++++++++++++++++++++++-------------
 usbredirparser/usbredirproto-compat.h |  2 +
 usbredirparser/usbredirproto.h        |  2 +
 6 files changed, 107 insertions(+), 40 deletions(-)

diff --git a/usbredirparser/strtok_r.c b/usbredirparser/strtok_r.c
index 227d1ea..2c761e1 100644
--- a/usbredirparser/strtok_r.c
+++ b/usbredirparser/strtok_r.c
@@ -21,7 +21,11 @@
 # include <config.h>
 #endif
 
+#if defined(__KERNEL__)
+#include <linux/string.h>
+#else
 #include <string.h>
+#endif
 
 /* Parse S into tokens separated by characters in DELIM.
    If S is NULL, the saved pointer in SAVE_PTR is used as
diff --git a/usbredirparser/usbredirfilter.c b/usbredirparser/usbredirfilter.c
index ef9c63a..4e3655a 100644
--- a/usbredirparser/usbredirfilter.c
+++ b/usbredirparser/usbredirfilter.c
@@ -19,22 +19,56 @@
    License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */
 
+#if defined(__KERNEL__)
+#include <linux/string.h>
+#include <linux/slab.h>
+#else
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+#endif
 
-#ifdef WIN32
+#if defined(WIN32) || defined(__KERNEL__)
 #include "strtok_r.h"
 #define strtok_r  glibc_strtok_r
 #endif
 
+#if defined(__KERNEL__)
+#define CALLOC(a, b)    kcalloc((a), (b), GFP_KERNEL)
+#define MALLOC(a)       kmalloc((a), GFP_KERNEL)
+#define STRDUP(a)       kstrdup((a), GFP_KERNEL)
+#define FREE kfree
+#else
+#define CALLOC          calloc
+#define MALLOC          malloc
+#define STRDUP          strdup
+#define FREE            free
+#endif
 #include "usbredirfilter.h"
 
+int filter_strtoi(char *str, int *res)
+{
+    long l;
+    int rc = 0;
+#if defined(__KERNEL__)
+    rc = kstrtol(str, 0, &l);
+#else
+    char *ep;
+
+    l = strtol(str, &ep, 0);
+    if (*ep)
+        rc = -1;
+#endif
+    if (rc == 0)
+        *res = (int) l;
+    return rc;
+}
+
 int usbredirfilter_string_to_rules(
     const char *filter_str, const char *token_sep, const char *rule_sep,
     struct usbredirfilter_rule **rules_ret, int *rules_count_ret)
 {
-    char *rule, *rule_saveptr, *token, *token_saveptr, *ep;
+    char *rule, *rule_saveptr, *token, *token_saveptr;
     struct usbredirfilter_rule *rules = NULL;
     int i, rules_count, *values, ret = 0;
     char *buf = NULL;
@@ -56,12 +90,12 @@ int usbredirfilter_string_to_rules(
         rules_count++;
     }
 
-    rules = calloc(rules_count, sizeof(struct usbredirfilter_rule));
+    rules = CALLOC(rules_count, sizeof(struct usbredirfilter_rule));
     if (!rules)
         return -ENOMEM;
 
     /* Make a copy since strtok mangles the string */
-    buf = strdup(filter_str);
+    buf = STRDUP(filter_str);
     if (!buf) {
         ret = -ENOMEM;
         goto leave;
@@ -75,9 +109,8 @@ int usbredirfilter_string_to_rules(
         values = (int *)&rules[rules_count];
         token = strtok_r(rule, token_sep, &token_saveptr);
         for (i = 0; i < 5 && token; i++) {
-            values[i] = strtol(token, &ep, 0);
-            if (*ep)
-                break;
+	    if (filter_strtoi(token, &values[i]))
+	        break;
             token = strtok_r(NULL, token_sep, &token_saveptr);
         }
         if (i != 5 || token != NULL ||
@@ -94,8 +127,8 @@ int usbredirfilter_string_to_rules(
 
 leave:
     if (ret)
-        free(rules);
-    free(buf);
+        FREE(rules);
+    FREE(buf);
     return ret;
 }
 
@@ -109,7 +142,7 @@ char *usbredirfilter_rules_to_string(const struct usbredirfilter_rule *rules,
         return NULL;
 
     /* We need 28 bytes per rule in the worst case */
-    str = malloc(28 * rules_count + 1);
+    str = MALLOC(28 * rules_count + 1);
     if (!str)
         return NULL;
 
@@ -222,6 +255,7 @@ int usbredirfilter_verify(
     return 0;
 }
 
+#if ! defined(__KERNEL__)
 void usbredirfilter_print(
     const struct usbredirfilter_rule *rules, int rules_count, FILE *out)
 {
@@ -257,3 +291,4 @@ void usbredirfilter_print(
                 product, version, rules[i].allow ? "Allow":"Block");
     }
 }
+#endif
diff --git a/usbredirparser/usbredirfilter.h b/usbredirparser/usbredirfilter.h
index f03fa7e..42773a8 100644
--- a/usbredirparser/usbredirfilter.h
+++ b/usbredirparser/usbredirfilter.h
@@ -21,8 +21,10 @@
 #ifndef __USBREDIRFILTER_H
 #define __USBREDIRFILTER_H
 
+#if ! defined(__KERNEL__)
 #include <stdio.h>
 #include <stdint.h>
+#endif
 
 #ifdef __cplusplus
 extern "C" {
@@ -129,9 +131,11 @@ int usbredirfilter_check(
 int usbredirfilter_verify(
     const struct usbredirfilter_rule *rules, int rules_count);
 
+#if ! defined(__KERNEL__)
 /* Print the passed in rules to FILE out in human readable format */
 void usbredirfilter_print(
     const struct usbredirfilter_rule *rules, int rules_count, FILE *out);
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/usbredirparser/usbredirparser.c b/usbredirparser/usbredirparser.c
index 8076b72..889ba55 100644
--- a/usbredirparser/usbredirparser.c
+++ b/usbredirparser/usbredirparser.c
@@ -18,16 +18,36 @@
    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */
+#if defined(__KERNEL__)
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#else
 #include "config.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
 #include <string.h>
+#endif
+
 #include "usbredirproto-compat.h"
 #include "usbredirparser.h"
 #include "usbredirfilter.h"
 
+#if defined(__KERNEL__)
+#define CALLOC(a, b)    kcalloc((a), (b), GFP_KERNEL)
+#define MALLOC(a)       kmalloc((a), GFP_KERNEL)
+#define REALLOC(a, b)   krealloc((a), (b), GFP_KERNEL)
+#define FREE kfree
+#else
+#define CALLOC          calloc
+#define MALLOC          malloc
+#define REALLOC         realloc
+#define FREE            free
+#endif
+
 /* Put *some* upper limit on bulk transfer sizes */
 #define MAX_BULK_TRANSFER_SIZE (128u * 1024u * 1024u)
 
@@ -99,7 +119,7 @@ va_log(struct usbredirparser_priv *parser, int verbose, const char *fmt, ...)
 #define ERROR(...)   va_log(parser, usbredirparser_error, __VA_ARGS__)
 #define WARNING(...) va_log(parser, usbredirparser_warning, __VA_ARGS__)
 #define INFO(...)    va_log(parser, usbredirparser_info, __VA_ARGS__)
-#define DEBUG(...)    va_log(parser, usbredirparser_debug, __VA_ARGS__)
+#define DEBUGP(...)    va_log(parser, usbredirparser_debug, __VA_ARGS__)
 
 #if 0 /* Can be enabled and called from random place to test serialization */
 static void serialize_test(struct usbredirparser *parser_pub)
@@ -116,20 +136,20 @@ static void serialize_test(struct usbredirparser *parser_pub)
     wbuf = parser->write_buf;
     while (wbuf) {
         next_wbuf = wbuf->next;
-        free(wbuf->buf);
-        free(wbuf);
+        FREE(wbuf->buf);
+        FREE(wbuf);
         wbuf = next_wbuf;
     }
     parser->write_buf = NULL;
     parser->write_buf_count = 0;
 
-    free(parser->data);
+    FREE(parser->data);
     parser->data = NULL;
 
     parser->type_header_len = parser->data_len = parser->have_peer_caps = 0;
 
     usbredirparser_unserialize(parser_pub, data, len);
-    free(data);
+    FREE(data);
 }
 #endif
 
@@ -140,7 +160,7 @@ static int usbredirparser_caps_get_cap(struct usbredirparser_priv *parser,
 
 struct usbredirparser *usbredirparser_create(void)
 {
-    return calloc(1, sizeof(struct usbredirparser_priv));
+    return CALLOC(1, sizeof(struct usbredirparser_priv));
 }
 
 static void usbredirparser_verify_caps(struct usbredirparser_priv *parser,
@@ -193,15 +213,15 @@ void usbredirparser_destroy(struct usbredirparser *parser_pub)
     wbuf = parser->write_buf;
     while (wbuf) {
         next_wbuf = wbuf->next;
-        free(wbuf->buf);
-        free(wbuf);
+        FREE(wbuf->buf);
+        FREE(wbuf);
         wbuf = next_wbuf;
     }
 
     if (parser->lock)
         parser->callb.free_lock_func(parser->lock);
 
-    free(parser);
+    FREE(parser);
 }
 
 static int usbredirparser_caps_get_cap(struct usbredirparser_priv *parser,
@@ -278,7 +298,7 @@ static void usbredirparser_handle_hello(struct usbredirparser *parser_pub,
     }
     usbredirparser_verify_caps(parser, parser->peer_caps, "peer");
     parser->have_peer_caps = 1;
-    free(data);
+    FREE(data);
 
     INFO("Peer version: %s, using %d-bits ids", buf,
          usbredirparser_using_32bits_ids(parser_pub) ? 32 : 64);
@@ -1006,7 +1026,7 @@ int usbredirparser_do_read(struct usbredirparser *parser_pub)
                 }
                 data_len = parser->header.length - type_header_len;
                 if (data_len) {
-                    parser->data = malloc(data_len);
+                    parser->data = MALLOC(data_len);
                     if (!parser->data) {
                         ERROR("Out of memory allocating data buffer");
                         parser->to_skip = parser->header.length;
@@ -1079,8 +1099,8 @@ int usbredirparser_do_write(struct usbredirparser *parser_pub)
         if (wbuf->pos == wbuf->len) {
             parser->write_buf = wbuf->next;
             if (!(parser->flags & usbredirparser_fl_write_cb_owns_buffer))
-                free(wbuf->buf);
-            free(wbuf);
+                FREE(wbuf->buf);
+            FREE(wbuf);
             parser->write_buf_count--;
         }
     }
@@ -1091,13 +1111,13 @@ int usbredirparser_do_write(struct usbredirparser *parser_pub)
 void usbredirparser_free_write_buffer(struct usbredirparser *parser,
     uint8_t *data)
 {
-    free(data);
+    FREE(data);
 }
 
 void usbredirparser_free_packet_data(struct usbredirparser *parser,
     uint8_t *data)
 {
-    free(data);
+    FREE(data);
 }
 
 static void usbredirparser_queue(struct usbredirparser *parser_pub,
@@ -1124,11 +1144,11 @@ static void usbredirparser_queue(struct usbredirparser *parser_pub,
         return;
     }
 
-    new_wbuf = calloc(1, sizeof(*new_wbuf));
-    buf = malloc(header_len + type_header_len + data_len);
+    new_wbuf = CALLOC(1, sizeof(*new_wbuf));
+    buf = MALLOC(header_len + type_header_len + data_len);
     if (!new_wbuf || !buf) {
         ERROR("Out of memory allocating buffer to send packet, dropping!");
-        free(new_wbuf); free(buf);
+        FREE(new_wbuf); FREE(buf);
         return;
     }
 
@@ -1345,7 +1365,7 @@ void usbredirparser_send_filter_filter(struct usbredirparser *parser_pub,
     }
     usbredirparser_queue(parser_pub, usb_redir_filter_filter, 0, NULL,
                          (uint8_t *)str, strlen(str) + 1);
-    free(str);
+    FREE(str);
 }
 
 void usbredirparser_send_start_bulk_receiving(struct usbredirparser *parser,
@@ -1456,9 +1476,9 @@ static int serialize_alloc(struct usbredirparser_priv *parser,
     size = (used + needed + USBREDIRPARSER_SERIALIZE_BUF_SIZE - 1) &
            ~(USBREDIRPARSER_SERIALIZE_BUF_SIZE - 1);
 
-    *state = realloc(*state, size);
+    *state = REALLOC(*state, size);
     if (!*state) {
-        free(old_state);
+        FREE(old_state);
         ERROR("Out of memory allocating serialization buffer");
         return -1;
     }
@@ -1473,7 +1493,7 @@ static int serialize_int(struct usbredirparser_priv *parser,
                          uint8_t **state, uint8_t **pos, uint32_t *remain,
                          uint32_t val, const char *desc)
 {
-    DEBUG("serializing int %08x : %s", val, desc);
+    DEBUGP("serializing int %08x : %s", val, desc);
 
     if (serialize_alloc(parser, state, pos, remain, sizeof(uint32_t)))
         return -1;
@@ -1497,7 +1517,7 @@ static int unserialize_int(struct usbredirparser_priv *parser,
     *pos += sizeof(uint32_t);
     *remain -= sizeof(uint32_t);
 
-    DEBUG("unserialized int %08x : %s", *val, desc);
+    DEBUGP("unserialized int %08x : %s", *val, desc);
 
     return 0;
 }
@@ -1506,9 +1526,9 @@ static int serialize_data(struct usbredirparser_priv *parser,
                           uint8_t **state, uint8_t **pos, uint32_t *remain,
                           uint8_t *data, uint32_t len, const char *desc)
 {
-    DEBUG("serializing %d bytes of %s data", len, desc);
+    DEBUGP("serializing %d bytes of %s data", len, desc);
     if (len >= 8)
-        DEBUG("First 8 bytes of %s: %02x %02x %02x %02x %02x %02x %02x %02x",
+        DEBUGP("First 8 bytes of %s: %02x %02x %02x %02x %02x %02x %02x %02x",
               desc, data[0], data[1], data[2], data[3],
                     data[4], data[5], data[6], data[7]);
 
@@ -1548,7 +1568,7 @@ static int unserialize_data(struct usbredirparser_priv *parser,
         return -1;
     }
     if (*data == NULL && len > 0) {
-        *data = malloc(len);
+        *data = MALLOC(len);
         if (!*data) {
             ERROR("Out of memory allocating unserialize buffer");
             return -1;
@@ -1565,9 +1585,9 @@ static int unserialize_data(struct usbredirparser_priv *parser,
     *remain -= len;
     *len_in_out = len;
 
-    DEBUG("unserialized %d bytes of %s data", len, desc);
+    DEBUGP("unserialized %d bytes of %s data", len, desc);
     if (len >= 8)
-        DEBUG("First 8 bytes of %s: %02x %02x %02x %02x %02x %02x %02x %02x",
+        DEBUGP("First 8 bytes of %s: %02x %02x %02x %02x %02x %02x %02x %02x",
               desc, (*data)[0], (*data)[1], (*data)[2], (*data)[3],
               (*data)[4], (*data)[5], (*data)[6], (*data)[7]);
 
@@ -1730,7 +1750,7 @@ int usbredirparser_unserialize(struct usbredirparser *parser_pub,
     parser->type_header_read = i;
 
     if (parser->data_len) {
-        parser->data = malloc(parser->data_len);
+        parser->data = MALLOC(parser->data_len);
         if (!parser->data) {
             ERROR("Out of memory allocating unserialize buffer");
             return -1;
@@ -1746,7 +1766,7 @@ int usbredirparser_unserialize(struct usbredirparser *parser_pub,
         return -1;
     next = &parser->write_buf;
     while (i) {
-        wbuf = calloc(1, sizeof(*wbuf));
+        wbuf = CALLOC(1, sizeof(*wbuf));
         if (!wbuf) {
             ERROR("Out of memory allocating unserialize buffer");
             return -1;
diff --git a/usbredirparser/usbredirproto-compat.h b/usbredirparser/usbredirproto-compat.h
index 9155d45..55d2ccf 100644
--- a/usbredirparser/usbredirproto-compat.h
+++ b/usbredirparser/usbredirproto-compat.h
@@ -40,7 +40,9 @@
 
 #endif
 
+#if ! defined(__KERNEL__)
 #include <stdint.h>
+#endif
 
 struct usb_redir_device_connect_header_no_device_version {
     uint8_t speed;
diff --git a/usbredirparser/usbredirproto.h b/usbredirparser/usbredirproto.h
index 89fb862..46b82e5 100644
--- a/usbredirparser/usbredirproto.h
+++ b/usbredirparser/usbredirproto.h
@@ -40,7 +40,9 @@
 
 #endif
 
+#if ! defined(__KERNEL__)
 #include <stdint.h>
+#endif
 
 #ifdef __cplusplus
 extern "C" {
-- 
2.1.4



More information about the Spice-devel mailing list