diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2013-07-12 06:34:42 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2013-07-12 06:34:42 -0400 |
commit | f2006e27396f55276f24434f56e208d86e7f9908 (patch) | |
tree | 71896db916d33888b4286f80117d3cac0da40e6d /lib/vsprintf.c | |
parent | e399eb56a6110e13f97e644658648602e2b08de7 (diff) | |
parent | 9903883f1dd6e86f286b7bfa6e4b423f98c1cd9e (diff) |
Merge branch 'linus' into timers/urgent
Get upstream changes so we can apply fixes against them
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'lib/vsprintf.c')
-rw-r--r-- | lib/vsprintf.c | 126 |
1 files changed, 123 insertions, 3 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index e149c6416384..739a36366b79 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
@@ -670,7 +670,7 @@ static noinline_for_stack | |||
670 | char *hex_string(char *buf, char *end, u8 *addr, struct printf_spec spec, | 670 | char *hex_string(char *buf, char *end, u8 *addr, struct printf_spec spec, |
671 | const char *fmt) | 671 | const char *fmt) |
672 | { | 672 | { |
673 | int i, len = 1; /* if we pass '%ph[CDN]', field witdh remains | 673 | int i, len = 1; /* if we pass '%ph[CDN]', field width remains |
674 | negative value, fallback to the default */ | 674 | negative value, fallback to the default */ |
675 | char separator; | 675 | char separator; |
676 | 676 | ||
@@ -923,6 +923,103 @@ char *ip4_addr_string(char *buf, char *end, const u8 *addr, | |||
923 | } | 923 | } |
924 | 924 | ||
925 | static noinline_for_stack | 925 | static noinline_for_stack |
926 | char *ip6_addr_string_sa(char *buf, char *end, const struct sockaddr_in6 *sa, | ||
927 | struct printf_spec spec, const char *fmt) | ||
928 | { | ||
929 | bool have_p = false, have_s = false, have_f = false, have_c = false; | ||
930 | char ip6_addr[sizeof("[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255]") + | ||
931 | sizeof(":12345") + sizeof("/123456789") + | ||
932 | sizeof("%1234567890")]; | ||
933 | char *p = ip6_addr, *pend = ip6_addr + sizeof(ip6_addr); | ||
934 | const u8 *addr = (const u8 *) &sa->sin6_addr; | ||
935 | char fmt6[2] = { fmt[0], '6' }; | ||
936 | u8 off = 0; | ||
937 | |||
938 | fmt++; | ||
939 | while (isalpha(*++fmt)) { | ||
940 | switch (*fmt) { | ||
941 | case 'p': | ||
942 | have_p = true; | ||
943 | break; | ||
944 | case 'f': | ||
945 | have_f = true; | ||
946 | break; | ||
947 | case 's': | ||
948 | have_s = true; | ||
949 | break; | ||
950 | case 'c': | ||
951 | have_c = true; | ||
952 | break; | ||
953 | } | ||
954 | } | ||
955 | |||
956 | if (have_p || have_s || have_f) { | ||
957 | *p = '['; | ||
958 | off = 1; | ||
959 | } | ||
960 | |||
961 | if (fmt6[0] == 'I' && have_c) | ||
962 | p = ip6_compressed_string(ip6_addr + off, addr); | ||
963 | else | ||
964 | p = ip6_string(ip6_addr + off, addr, fmt6); | ||
965 | |||
966 | if (have_p || have_s || have_f) | ||
967 | *p++ = ']'; | ||
968 | |||
969 | if (have_p) { | ||
970 | *p++ = ':'; | ||
971 | p = number(p, pend, ntohs(sa->sin6_port), spec); | ||
972 | } | ||
973 | if (have_f) { | ||
974 | *p++ = '/'; | ||
975 | p = number(p, pend, ntohl(sa->sin6_flowinfo & | ||
976 | IPV6_FLOWINFO_MASK), spec); | ||
977 | } | ||
978 | if (have_s) { | ||
979 | *p++ = '%'; | ||
980 | p = number(p, pend, sa->sin6_scope_id, spec); | ||
981 | } | ||
982 | *p = '\0'; | ||
983 | |||
984 | return string(buf, end, ip6_addr, spec); | ||
985 | } | ||
986 | |||
987 | static noinline_for_stack | ||
988 | char *ip4_addr_string_sa(char *buf, char *end, const struct sockaddr_in *sa, | ||
989 | struct printf_spec spec, const char *fmt) | ||
990 | { | ||
991 | bool have_p = false; | ||
992 | char *p, ip4_addr[sizeof("255.255.255.255") + sizeof(":12345")]; | ||
993 | char *pend = ip4_addr + sizeof(ip4_addr); | ||
994 | const u8 *addr = (const u8 *) &sa->sin_addr.s_addr; | ||
995 | char fmt4[3] = { fmt[0], '4', 0 }; | ||
996 | |||
997 | fmt++; | ||
998 | while (isalpha(*++fmt)) { | ||
999 | switch (*fmt) { | ||
1000 | case 'p': | ||
1001 | have_p = true; | ||
1002 | break; | ||
1003 | case 'h': | ||
1004 | case 'l': | ||
1005 | case 'n': | ||
1006 | case 'b': | ||
1007 | fmt4[2] = *fmt; | ||
1008 | break; | ||
1009 | } | ||
1010 | } | ||
1011 | |||
1012 | p = ip4_string(ip4_addr, addr, fmt4); | ||
1013 | if (have_p) { | ||
1014 | *p++ = ':'; | ||
1015 | p = number(p, pend, ntohs(sa->sin_port), spec); | ||
1016 | } | ||
1017 | *p = '\0'; | ||
1018 | |||
1019 | return string(buf, end, ip4_addr, spec); | ||
1020 | } | ||
1021 | |||
1022 | static noinline_for_stack | ||
926 | char *uuid_string(char *buf, char *end, const u8 *addr, | 1023 | char *uuid_string(char *buf, char *end, const u8 *addr, |
927 | struct printf_spec spec, const char *fmt) | 1024 | struct printf_spec spec, const char *fmt) |
928 | { | 1025 | { |
@@ -1007,11 +1104,17 @@ int kptr_restrict __read_mostly; | |||
1007 | * - 'I' [46] for IPv4/IPv6 addresses printed in the usual way | 1104 | * - 'I' [46] for IPv4/IPv6 addresses printed in the usual way |
1008 | * IPv4 uses dot-separated decimal without leading 0's (1.2.3.4) | 1105 | * IPv4 uses dot-separated decimal without leading 0's (1.2.3.4) |
1009 | * IPv6 uses colon separated network-order 16 bit hex with leading 0's | 1106 | * IPv6 uses colon separated network-order 16 bit hex with leading 0's |
1107 | * [S][pfs] | ||
1108 | * Generic IPv4/IPv6 address (struct sockaddr *) that falls back to | ||
1109 | * [4] or [6] and is able to print port [p], flowinfo [f], scope [s] | ||
1010 | * - 'i' [46] for 'raw' IPv4/IPv6 addresses | 1110 | * - 'i' [46] for 'raw' IPv4/IPv6 addresses |
1011 | * IPv6 omits the colons (01020304...0f) | 1111 | * IPv6 omits the colons (01020304...0f) |
1012 | * IPv4 uses dot-separated decimal with leading 0's (010.123.045.006) | 1112 | * IPv4 uses dot-separated decimal with leading 0's (010.123.045.006) |
1013 | * - '[Ii]4[hnbl]' IPv4 addresses in host, network, big or little endian order | 1113 | * [S][pfs] |
1014 | * - 'I6c' for IPv6 addresses printed as specified by | 1114 | * Generic IPv4/IPv6 address (struct sockaddr *) that falls back to |
1115 | * [4] or [6] and is able to print port [p], flowinfo [f], scope [s] | ||
1116 | * - '[Ii][4S][hnbl]' IPv4 addresses in host, network, big or little endian order | ||
1117 | * - 'I[6S]c' for IPv6 addresses printed as specified by | ||
1015 | * http://tools.ietf.org/html/rfc5952 | 1118 | * http://tools.ietf.org/html/rfc5952 |
1016 | * - 'U' For a 16 byte UUID/GUID, it prints the UUID/GUID in the form | 1119 | * - 'U' For a 16 byte UUID/GUID, it prints the UUID/GUID in the form |
1017 | * "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" | 1120 | * "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" |
@@ -1093,6 +1196,21 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, | |||
1093 | return ip6_addr_string(buf, end, ptr, spec, fmt); | 1196 | return ip6_addr_string(buf, end, ptr, spec, fmt); |
1094 | case '4': | 1197 | case '4': |
1095 | return ip4_addr_string(buf, end, ptr, spec, fmt); | 1198 | return ip4_addr_string(buf, end, ptr, spec, fmt); |
1199 | case 'S': { | ||
1200 | const union { | ||
1201 | struct sockaddr raw; | ||
1202 | struct sockaddr_in v4; | ||
1203 | struct sockaddr_in6 v6; | ||
1204 | } *sa = ptr; | ||
1205 | |||
1206 | switch (sa->raw.sa_family) { | ||
1207 | case AF_INET: | ||
1208 | return ip4_addr_string_sa(buf, end, &sa->v4, spec, fmt); | ||
1209 | case AF_INET6: | ||
1210 | return ip6_addr_string_sa(buf, end, &sa->v6, spec, fmt); | ||
1211 | default: | ||
1212 | return string(buf, end, "(invalid address)", spec); | ||
1213 | }} | ||
1096 | } | 1214 | } |
1097 | break; | 1215 | break; |
1098 | case 'U': | 1216 | case 'U': |
@@ -1370,6 +1488,8 @@ qualifier: | |||
1370 | * %pI6 print an IPv6 address with colons | 1488 | * %pI6 print an IPv6 address with colons |
1371 | * %pi6 print an IPv6 address without colons | 1489 | * %pi6 print an IPv6 address without colons |
1372 | * %pI6c print an IPv6 address as specified by RFC 5952 | 1490 | * %pI6c print an IPv6 address as specified by RFC 5952 |
1491 | * %pIS depending on sa_family of 'struct sockaddr *' print IPv4/IPv6 address | ||
1492 | * %piS depending on sa_family of 'struct sockaddr *' print IPv4/IPv6 address | ||
1373 | * %pU[bBlL] print a UUID/GUID in big or little endian using lower or upper | 1493 | * %pU[bBlL] print a UUID/GUID in big or little endian using lower or upper |
1374 | * case. | 1494 | * case. |
1375 | * %*ph[CDN] a variable-length hex string with a separator (supports up to 64 | 1495 | * %*ph[CDN] a variable-length hex string with a separator (supports up to 64 |