diff options
Diffstat (limited to 'src/dbusbind.c')
| -rw-r--r-- | src/dbusbind.c | 130 |
1 files changed, 88 insertions, 42 deletions
diff --git a/src/dbusbind.c b/src/dbusbind.c index 62923b462b5..e506380e607 100644 --- a/src/dbusbind.c +++ b/src/dbusbind.c | |||
| @@ -254,22 +254,6 @@ xd_symbol_to_dbus_type (Lisp_Object object) | |||
| 254 | #define XD_OBJECT_TO_STRING(object) \ | 254 | #define XD_OBJECT_TO_STRING(object) \ |
| 255 | SDATA (format2 ("%s", object, Qnil)) | 255 | SDATA (format2 ("%s", object, Qnil)) |
| 256 | 256 | ||
| 257 | /* Check whether X is a valid dbus serial number. If valid, set | ||
| 258 | SERIAL to its value. Otherwise, signal an error. */ | ||
| 259 | #define XD_CHECK_DBUS_SERIAL(x, serial) \ | ||
| 260 | do { \ | ||
| 261 | dbus_uint32_t DBUS_SERIAL_MAX = -1; \ | ||
| 262 | if (NATNUMP (x) && XINT (x) <= DBUS_SERIAL_MAX) \ | ||
| 263 | serial = XINT (x); \ | ||
| 264 | else if (MOST_POSITIVE_FIXNUM < DBUS_SERIAL_MAX \ | ||
| 265 | && FLOATP (x) \ | ||
| 266 | && 0 <= XFLOAT_DATA (x) \ | ||
| 267 | && XFLOAT_DATA (x) <= DBUS_SERIAL_MAX) \ | ||
| 268 | serial = XFLOAT_DATA (x); \ | ||
| 269 | else \ | ||
| 270 | XD_SIGNAL2 (build_string ("Invalid dbus serial"), x); \ | ||
| 271 | } while (0) | ||
| 272 | |||
| 273 | #define XD_DBUS_VALIDATE_BUS_ADDRESS(bus) \ | 257 | #define XD_DBUS_VALIDATE_BUS_ADDRESS(bus) \ |
| 274 | do { \ | 258 | do { \ |
| 275 | if (STRINGP (bus)) \ | 259 | if (STRINGP (bus)) \ |
| @@ -366,9 +350,9 @@ xd_signature_cat (char *signature, char const *x) | |||
| 366 | signature is embedded, or DBUS_TYPE_INVALID. It is needed for the | 350 | signature is embedded, or DBUS_TYPE_INVALID. It is needed for the |
| 367 | check that DBUS_TYPE_DICT_ENTRY occurs only as array element. */ | 351 | check that DBUS_TYPE_DICT_ENTRY occurs only as array element. */ |
| 368 | static void | 352 | static void |
| 369 | xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lisp_Object object) | 353 | xd_signature (char *signature, int dtype, int parent_type, Lisp_Object object) |
| 370 | { | 354 | { |
| 371 | unsigned int subtype; | 355 | int subtype; |
| 372 | Lisp_Object elt; | 356 | Lisp_Object elt; |
| 373 | char const *subsig; | 357 | char const *subsig; |
| 374 | int subsiglen; | 358 | int subsiglen; |
| @@ -538,13 +522,67 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis | |||
| 538 | XD_DEBUG_MESSAGE ("%s", signature); | 522 | XD_DEBUG_MESSAGE ("%s", signature); |
| 539 | } | 523 | } |
| 540 | 524 | ||
| 525 | /* Convert X to a signed integer with bounds LO and HI. */ | ||
| 526 | static intmax_t | ||
| 527 | extract_signed (Lisp_Object x, intmax_t lo, intmax_t hi) | ||
| 528 | { | ||
| 529 | CHECK_NUMBER_OR_FLOAT (x); | ||
| 530 | if (INTEGERP (x)) | ||
| 531 | { | ||
| 532 | if (lo <= XINT (x) && XINT (x) <= hi) | ||
| 533 | return XINT (x); | ||
| 534 | } | ||
| 535 | else | ||
| 536 | { | ||
| 537 | double d = XFLOAT_DATA (x); | ||
| 538 | if (lo <= d && d <= hi) | ||
| 539 | { | ||
| 540 | intmax_t n = d; | ||
| 541 | if (n == d) | ||
| 542 | return n; | ||
| 543 | } | ||
| 544 | } | ||
| 545 | if (xd_in_read_queued_messages) | ||
| 546 | Fthrow (Qdbus_error, Qnil); | ||
| 547 | else | ||
| 548 | args_out_of_range_3 (x, | ||
| 549 | make_fixnum_or_float (lo), | ||
| 550 | make_fixnum_or_float (hi)); | ||
| 551 | } | ||
| 552 | |||
| 553 | /* Convert X to an unsigned integer with bounds 0 and HI. */ | ||
| 554 | static uintmax_t | ||
| 555 | extract_unsigned (Lisp_Object x, uintmax_t hi) | ||
| 556 | { | ||
| 557 | CHECK_NUMBER_OR_FLOAT (x); | ||
| 558 | if (INTEGERP (x)) | ||
| 559 | { | ||
| 560 | if (0 <= XINT (x) && XINT (x) <= hi) | ||
| 561 | return XINT (x); | ||
| 562 | } | ||
| 563 | else | ||
| 564 | { | ||
| 565 | double d = XFLOAT_DATA (x); | ||
| 566 | if (0 <= d && d <= hi) | ||
| 567 | { | ||
| 568 | uintmax_t n = d; | ||
| 569 | if (n == d) | ||
| 570 | return n; | ||
| 571 | } | ||
| 572 | } | ||
| 573 | if (xd_in_read_queued_messages) | ||
| 574 | Fthrow (Qdbus_error, Qnil); | ||
| 575 | else | ||
| 576 | args_out_of_range_3 (x, make_number (0), make_fixnum_or_float (hi)); | ||
| 577 | } | ||
| 578 | |||
| 541 | /* Append C value, extracted from Lisp OBJECT, to iteration ITER. | 579 | /* Append C value, extracted from Lisp OBJECT, to iteration ITER. |
| 542 | DTYPE must be a valid DBusType. It is used to convert Lisp | 580 | DTYPE must be a valid DBusType. It is used to convert Lisp |
| 543 | objects, being arguments of `dbus-call-method' or | 581 | objects, being arguments of `dbus-call-method' or |
| 544 | `dbus-send-signal', into corresponding C values appended as | 582 | `dbus-send-signal', into corresponding C values appended as |
| 545 | arguments to a D-Bus message. */ | 583 | arguments to a D-Bus message. */ |
| 546 | static void | 584 | static void |
| 547 | xd_append_arg (unsigned int dtype, Lisp_Object object, DBusMessageIter *iter) | 585 | xd_append_arg (int dtype, Lisp_Object object, DBusMessageIter *iter) |
| 548 | { | 586 | { |
| 549 | char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH]; | 587 | char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH]; |
| 550 | DBusMessageIter subiter; | 588 | DBusMessageIter subiter; |
| @@ -572,9 +610,10 @@ xd_append_arg (unsigned int dtype, Lisp_Object object, DBusMessageIter *iter) | |||
| 572 | } | 610 | } |
| 573 | 611 | ||
| 574 | case DBUS_TYPE_INT16: | 612 | case DBUS_TYPE_INT16: |
| 575 | CHECK_NUMBER (object); | ||
| 576 | { | 613 | { |
| 577 | dbus_int16_t val = XINT (object); | 614 | dbus_int16_t val = extract_signed (object, |
| 615 | TYPE_MINIMUM (dbus_int16_t), | ||
| 616 | TYPE_MAXIMUM (dbus_int16_t)); | ||
| 578 | int pval = val; | 617 | int pval = val; |
| 579 | XD_DEBUG_MESSAGE ("%c %d", dtype, pval); | 618 | XD_DEBUG_MESSAGE ("%c %d", dtype, pval); |
| 580 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) | 619 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) |
| @@ -583,9 +622,9 @@ xd_append_arg (unsigned int dtype, Lisp_Object object, DBusMessageIter *iter) | |||
| 583 | } | 622 | } |
| 584 | 623 | ||
| 585 | case DBUS_TYPE_UINT16: | 624 | case DBUS_TYPE_UINT16: |
| 586 | CHECK_NATNUM (object); | ||
| 587 | { | 625 | { |
| 588 | dbus_uint16_t val = XFASTINT (object); | 626 | dbus_uint16_t val = extract_unsigned (object, |
| 627 | TYPE_MAXIMUM (dbus_uint16_t)); | ||
| 589 | unsigned int pval = val; | 628 | unsigned int pval = val; |
| 590 | XD_DEBUG_MESSAGE ("%c %u", dtype, pval); | 629 | XD_DEBUG_MESSAGE ("%c %u", dtype, pval); |
| 591 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) | 630 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) |
| @@ -595,7 +634,9 @@ xd_append_arg (unsigned int dtype, Lisp_Object object, DBusMessageIter *iter) | |||
| 595 | 634 | ||
| 596 | case DBUS_TYPE_INT32: | 635 | case DBUS_TYPE_INT32: |
| 597 | { | 636 | { |
| 598 | dbus_int32_t val = extract_float (object); | 637 | dbus_int32_t val = extract_signed (object, |
| 638 | TYPE_MINIMUM (dbus_int32_t), | ||
| 639 | TYPE_MAXIMUM (dbus_int32_t)); | ||
| 599 | int pval = val; | 640 | int pval = val; |
| 600 | XD_DEBUG_MESSAGE ("%c %d", dtype, pval); | 641 | XD_DEBUG_MESSAGE ("%c %d", dtype, pval); |
| 601 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) | 642 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) |
| @@ -608,7 +649,8 @@ xd_append_arg (unsigned int dtype, Lisp_Object object, DBusMessageIter *iter) | |||
| 608 | case DBUS_TYPE_UNIX_FD: | 649 | case DBUS_TYPE_UNIX_FD: |
| 609 | #endif | 650 | #endif |
| 610 | { | 651 | { |
| 611 | dbus_uint32_t val = extract_float (object); | 652 | dbus_uint32_t val = extract_unsigned (object, |
| 653 | TYPE_MAXIMUM (dbus_uint32_t)); | ||
| 612 | unsigned int pval = val; | 654 | unsigned int pval = val; |
| 613 | XD_DEBUG_MESSAGE ("%c %u", dtype, pval); | 655 | XD_DEBUG_MESSAGE ("%c %u", dtype, pval); |
| 614 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) | 656 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) |
| @@ -618,7 +660,9 @@ xd_append_arg (unsigned int dtype, Lisp_Object object, DBusMessageIter *iter) | |||
| 618 | 660 | ||
| 619 | case DBUS_TYPE_INT64: | 661 | case DBUS_TYPE_INT64: |
| 620 | { | 662 | { |
| 621 | dbus_int64_t val = extract_float (object); | 663 | dbus_int64_t val = extract_signed (object, |
| 664 | TYPE_MINIMUM (dbus_int64_t), | ||
| 665 | TYPE_MAXIMUM (dbus_int64_t)); | ||
| 622 | printmax_t pval = val; | 666 | printmax_t pval = val; |
| 623 | XD_DEBUG_MESSAGE ("%c %"pMd, dtype, pval); | 667 | XD_DEBUG_MESSAGE ("%c %"pMd, dtype, pval); |
| 624 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) | 668 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) |
| @@ -628,7 +672,8 @@ xd_append_arg (unsigned int dtype, Lisp_Object object, DBusMessageIter *iter) | |||
| 628 | 672 | ||
| 629 | case DBUS_TYPE_UINT64: | 673 | case DBUS_TYPE_UINT64: |
| 630 | { | 674 | { |
| 631 | dbus_uint64_t val = extract_float (object); | 675 | dbus_uint64_t val = extract_unsigned (object, |
| 676 | TYPE_MAXIMUM (dbus_uint64_t)); | ||
| 632 | uprintmax_t pval = val; | 677 | uprintmax_t pval = val; |
| 633 | XD_DEBUG_MESSAGE ("%c %"pMu, dtype, pval); | 678 | XD_DEBUG_MESSAGE ("%c %"pMu, dtype, pval); |
| 634 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) | 679 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) |
| @@ -755,7 +800,7 @@ xd_append_arg (unsigned int dtype, Lisp_Object object, DBusMessageIter *iter) | |||
| 755 | D-Bus message must be a valid DBusType. Compound D-Bus types | 800 | D-Bus message must be a valid DBusType. Compound D-Bus types |
| 756 | result always in a Lisp list. */ | 801 | result always in a Lisp list. */ |
| 757 | static Lisp_Object | 802 | static Lisp_Object |
| 758 | xd_retrieve_arg (unsigned int dtype, DBusMessageIter *iter) | 803 | xd_retrieve_arg (int dtype, DBusMessageIter *iter) |
| 759 | { | 804 | { |
| 760 | 805 | ||
| 761 | switch (dtype) | 806 | switch (dtype) |
| @@ -887,7 +932,7 @@ xd_retrieve_arg (unsigned int dtype, DBusMessageIter *iter) | |||
| 887 | } | 932 | } |
| 888 | 933 | ||
| 889 | /* Return the number of references of the shared CONNECTION. */ | 934 | /* Return the number of references of the shared CONNECTION. */ |
| 890 | static int | 935 | static ptrdiff_t |
| 891 | xd_get_connection_references (DBusConnection *connection) | 936 | xd_get_connection_references (DBusConnection *connection) |
| 892 | { | 937 | { |
| 893 | ptrdiff_t *refcount; | 938 | ptrdiff_t *refcount; |
| @@ -1060,7 +1105,7 @@ this connection to those buses. */) | |||
| 1060 | DBusConnection *connection; | 1105 | DBusConnection *connection; |
| 1061 | DBusError derror; | 1106 | DBusError derror; |
| 1062 | Lisp_Object val; | 1107 | Lisp_Object val; |
| 1063 | int refcount; | 1108 | ptrdiff_t refcount; |
| 1064 | 1109 | ||
| 1065 | /* Check parameter. */ | 1110 | /* Check parameter. */ |
| 1066 | XD_DBUS_VALIDATE_BUS_ADDRESS (bus); | 1111 | XD_DBUS_VALIDATE_BUS_ADDRESS (bus); |
| @@ -1130,7 +1175,7 @@ this connection to those buses. */) | |||
| 1130 | 1175 | ||
| 1131 | /* Return reference counter. */ | 1176 | /* Return reference counter. */ |
| 1132 | refcount = xd_get_connection_references (connection); | 1177 | refcount = xd_get_connection_references (connection); |
| 1133 | XD_DEBUG_MESSAGE ("Bus %s, Reference counter %d", | 1178 | XD_DEBUG_MESSAGE ("Bus %s, Reference counter %"pD"d", |
| 1134 | XD_OBJECT_TO_STRING (bus), refcount); | 1179 | XD_OBJECT_TO_STRING (bus), refcount); |
| 1135 | return make_number (refcount); | 1180 | return make_number (refcount); |
| 1136 | } | 1181 | } |
| @@ -1194,8 +1239,8 @@ usage: (dbus-message-internal &rest REST) */) | |||
| 1194 | DBusConnection *connection; | 1239 | DBusConnection *connection; |
| 1195 | DBusMessage *dmessage; | 1240 | DBusMessage *dmessage; |
| 1196 | DBusMessageIter iter; | 1241 | DBusMessageIter iter; |
| 1197 | unsigned int dtype; | 1242 | int dtype; |
| 1198 | unsigned int mtype; | 1243 | int mtype; |
| 1199 | dbus_uint32_t serial = 0; | 1244 | dbus_uint32_t serial = 0; |
| 1200 | unsigned int ui_serial; | 1245 | unsigned int ui_serial; |
| 1201 | int timeout = -1; | 1246 | int timeout = -1; |
| @@ -1209,9 +1254,10 @@ usage: (dbus-message-internal &rest REST) */) | |||
| 1209 | handler = Qnil; | 1254 | handler = Qnil; |
| 1210 | 1255 | ||
| 1211 | CHECK_NATNUM (message_type); | 1256 | CHECK_NATNUM (message_type); |
| 1212 | mtype = XFASTINT (message_type); | 1257 | if (! (DBUS_MESSAGE_TYPE_INVALID < XFASTINT (message_type) |
| 1213 | if ((mtype <= DBUS_MESSAGE_TYPE_INVALID) || (mtype >= DBUS_NUM_MESSAGE_TYPES)) | 1258 | && XFASTINT (message_type) < DBUS_NUM_MESSAGE_TYPES)) |
| 1214 | XD_SIGNAL2 (build_string ("Invalid message type"), message_type); | 1259 | XD_SIGNAL2 (build_string ("Invalid message type"), message_type); |
| 1260 | mtype = XFASTINT (message_type); | ||
| 1215 | 1261 | ||
| 1216 | if ((mtype == DBUS_MESSAGE_TYPE_METHOD_CALL) | 1262 | if ((mtype == DBUS_MESSAGE_TYPE_METHOD_CALL) |
| 1217 | || (mtype == DBUS_MESSAGE_TYPE_SIGNAL)) | 1263 | || (mtype == DBUS_MESSAGE_TYPE_SIGNAL)) |
| @@ -1225,7 +1271,7 @@ usage: (dbus-message-internal &rest REST) */) | |||
| 1225 | } | 1271 | } |
| 1226 | else /* DBUS_MESSAGE_TYPE_METHOD_RETURN, DBUS_MESSAGE_TYPE_ERROR */ | 1272 | else /* DBUS_MESSAGE_TYPE_METHOD_RETURN, DBUS_MESSAGE_TYPE_ERROR */ |
| 1227 | { | 1273 | { |
| 1228 | XD_CHECK_DBUS_SERIAL (args[3], serial); | 1274 | serial = extract_unsigned (args[3], TYPE_MAXIMUM (dbus_uint32_t)); |
| 1229 | count = 4; | 1275 | count = 4; |
| 1230 | } | 1276 | } |
| 1231 | 1277 | ||
| @@ -1363,7 +1409,7 @@ usage: (dbus-message-internal &rest REST) */) | |||
| 1363 | if ((count+2 <= nargs) && (EQ ((args[count]), QCdbus_timeout))) | 1409 | if ((count+2 <= nargs) && (EQ ((args[count]), QCdbus_timeout))) |
| 1364 | { | 1410 | { |
| 1365 | CHECK_NATNUM (args[count+1]); | 1411 | CHECK_NATNUM (args[count+1]); |
| 1366 | timeout = XFASTINT (args[count+1]); | 1412 | timeout = min (XFASTINT (args[count+1]), INT_MAX); |
| 1367 | count = count+2; | 1413 | count = count+2; |
| 1368 | } | 1414 | } |
| 1369 | 1415 | ||
| @@ -1449,8 +1495,8 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus) | |||
| 1449 | struct input_event event; | 1495 | struct input_event event; |
| 1450 | DBusMessage *dmessage; | 1496 | DBusMessage *dmessage; |
| 1451 | DBusMessageIter iter; | 1497 | DBusMessageIter iter; |
| 1452 | unsigned int dtype; | 1498 | int dtype; |
| 1453 | unsigned int mtype; | 1499 | int mtype; |
| 1454 | dbus_uint32_t serial; | 1500 | dbus_uint32_t serial; |
| 1455 | unsigned int ui_serial; | 1501 | unsigned int ui_serial; |
| 1456 | const char *uname, *path, *interface, *member; | 1502 | const char *uname, *path, *interface, *member; |
| @@ -1698,10 +1744,10 @@ syms_of_dbusbind (void) | |||
| 1698 | { | 1744 | { |
| 1699 | #ifdef DBUS_VERSION | 1745 | #ifdef DBUS_VERSION |
| 1700 | int major, minor, micro; | 1746 | int major, minor, micro; |
| 1701 | char s[1024]; | 1747 | char s[sizeof ".." + 3 * INT_STRLEN_BOUND (int)]; |
| 1702 | dbus_get_version (&major, &minor, µ); | 1748 | dbus_get_version (&major, &minor, µ); |
| 1703 | snprintf (s, sizeof s, "%d.%d.%d", major, minor, micro); | 1749 | sprintf (s, "%d.%d.%d", major, minor, micro); |
| 1704 | Vdbus_runtime_version = make_string (s, strlen (s)); | 1750 | Vdbus_runtime_version = build_string (s); |
| 1705 | #else | 1751 | #else |
| 1706 | Vdbus_runtime_version = Qnil; | 1752 | Vdbus_runtime_version = Qnil; |
| 1707 | #endif | 1753 | #endif |