diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-13 21:54:50 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-13 21:54:50 -0400 |
| commit | dfe2c6dcc8ca2cdc662d7c0473e9811b72ef3370 (patch) | |
| tree | 9ed639a08c16322cdf136d576f42df5b97cd1549 /lib/vsprintf.c | |
| parent | a45d572841a24db02a62cf05e1157c35fdd3705b (diff) | |
| parent | 64e455079e1bd7787cc47be30b7f601ce682a5f6 (diff) | |
Merge branch 'akpm' (patches from Andrew Morton)
Merge second patch-bomb from Andrew Morton:
- a few hotfixes
- drivers/dma updates
- MAINTAINERS updates
- Quite a lot of lib/ updates
- checkpatch updates
- binfmt updates
- autofs4
- drivers/rtc/
- various small tweaks to less used filesystems
- ipc/ updates
- kernel/watchdog.c changes
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (135 commits)
mm: softdirty: enable write notifications on VMAs after VM_SOFTDIRTY cleared
kernel/param: consolidate __{start,stop}___param[] in <linux/moduleparam.h>
ia64: remove duplicate declarations of __per_cpu_start[] and __per_cpu_end[]
frv: remove unused declarations of __start___ex_table and __stop___ex_table
kvm: ensure hard lockup detection is disabled by default
kernel/watchdog.c: control hard lockup detection default
staging: rtl8192u: use %*pEn to escape buffer
staging: rtl8192e: use %*pEn to escape buffer
staging: wlan-ng: use %*pEhp to print SN
lib80211: remove unused print_ssid()
wireless: hostap: proc: print properly escaped SSID
wireless: ipw2x00: print SSID via %*pE
wireless: libertas: print esaped string via %*pE
lib/vsprintf: add %*pE[achnops] format specifier
lib / string_helpers: introduce string_escape_mem()
lib / string_helpers: refactoring the test suite
lib / string_helpers: move documentation to c-file
include/linux: remove strict_strto* definitions
arch/x86/mm/numa.c: fix boot failure when all nodes are hotpluggable
fs: check bh blocknr earlier when searching lru
...
Diffstat (limited to 'lib/vsprintf.c')
| -rw-r--r-- | lib/vsprintf.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index ba3cd0a35640..ec337f64f52d 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <asm/page.h> /* for PAGE_SIZE */ | 33 | #include <asm/page.h> /* for PAGE_SIZE */ |
| 34 | #include <asm/sections.h> /* for dereference_function_descriptor() */ | 34 | #include <asm/sections.h> /* for dereference_function_descriptor() */ |
| 35 | 35 | ||
| 36 | #include <linux/string_helpers.h> | ||
| 36 | #include "kstrtox.h" | 37 | #include "kstrtox.h" |
| 37 | 38 | ||
| 38 | /** | 39 | /** |
| @@ -1101,6 +1102,62 @@ char *ip4_addr_string_sa(char *buf, char *end, const struct sockaddr_in *sa, | |||
| 1101 | } | 1102 | } |
| 1102 | 1103 | ||
| 1103 | static noinline_for_stack | 1104 | static noinline_for_stack |
| 1105 | char *escaped_string(char *buf, char *end, u8 *addr, struct printf_spec spec, | ||
| 1106 | const char *fmt) | ||
| 1107 | { | ||
| 1108 | bool found = true; | ||
| 1109 | int count = 1; | ||
| 1110 | unsigned int flags = 0; | ||
| 1111 | int len; | ||
| 1112 | |||
| 1113 | if (spec.field_width == 0) | ||
| 1114 | return buf; /* nothing to print */ | ||
| 1115 | |||
| 1116 | if (ZERO_OR_NULL_PTR(addr)) | ||
| 1117 | return string(buf, end, NULL, spec); /* NULL pointer */ | ||
| 1118 | |||
| 1119 | |||
| 1120 | do { | ||
| 1121 | switch (fmt[count++]) { | ||
| 1122 | case 'a': | ||
| 1123 | flags |= ESCAPE_ANY; | ||
| 1124 | break; | ||
| 1125 | case 'c': | ||
| 1126 | flags |= ESCAPE_SPECIAL; | ||
| 1127 | break; | ||
| 1128 | case 'h': | ||
| 1129 | flags |= ESCAPE_HEX; | ||
| 1130 | break; | ||
| 1131 | case 'n': | ||
| 1132 | flags |= ESCAPE_NULL; | ||
| 1133 | break; | ||
| 1134 | case 'o': | ||
| 1135 | flags |= ESCAPE_OCTAL; | ||
| 1136 | break; | ||
| 1137 | case 'p': | ||
| 1138 | flags |= ESCAPE_NP; | ||
| 1139 | break; | ||
| 1140 | case 's': | ||
| 1141 | flags |= ESCAPE_SPACE; | ||
| 1142 | break; | ||
| 1143 | default: | ||
| 1144 | found = false; | ||
| 1145 | break; | ||
| 1146 | } | ||
| 1147 | } while (found); | ||
| 1148 | |||
| 1149 | if (!flags) | ||
| 1150 | flags = ESCAPE_ANY_NP; | ||
| 1151 | |||
| 1152 | len = spec.field_width < 0 ? 1 : spec.field_width; | ||
| 1153 | |||
| 1154 | /* Ignore the error. We print as many characters as we can */ | ||
| 1155 | string_escape_mem(addr, len, &buf, end - buf, flags, NULL); | ||
| 1156 | |||
| 1157 | return buf; | ||
| 1158 | } | ||
| 1159 | |||
| 1160 | static noinline_for_stack | ||
| 1104 | char *uuid_string(char *buf, char *end, const u8 *addr, | 1161 | char *uuid_string(char *buf, char *end, const u8 *addr, |
| 1105 | struct printf_spec spec, const char *fmt) | 1162 | struct printf_spec spec, const char *fmt) |
| 1106 | { | 1163 | { |
| @@ -1221,6 +1278,17 @@ int kptr_restrict __read_mostly; | |||
| 1221 | * - '[Ii][4S][hnbl]' IPv4 addresses in host, network, big or little endian order | 1278 | * - '[Ii][4S][hnbl]' IPv4 addresses in host, network, big or little endian order |
| 1222 | * - 'I[6S]c' for IPv6 addresses printed as specified by | 1279 | * - 'I[6S]c' for IPv6 addresses printed as specified by |
| 1223 | * http://tools.ietf.org/html/rfc5952 | 1280 | * http://tools.ietf.org/html/rfc5952 |
| 1281 | * - 'E[achnops]' For an escaped buffer, where rules are defined by combination | ||
| 1282 | * of the following flags (see string_escape_mem() for the | ||
| 1283 | * details): | ||
| 1284 | * a - ESCAPE_ANY | ||
| 1285 | * c - ESCAPE_SPECIAL | ||
| 1286 | * h - ESCAPE_HEX | ||
| 1287 | * n - ESCAPE_NULL | ||
| 1288 | * o - ESCAPE_OCTAL | ||
| 1289 | * p - ESCAPE_NP | ||
| 1290 | * s - ESCAPE_SPACE | ||
| 1291 | * By default ESCAPE_ANY_NP is used. | ||
| 1224 | * - 'U' For a 16 byte UUID/GUID, it prints the UUID/GUID in the form | 1292 | * - 'U' For a 16 byte UUID/GUID, it prints the UUID/GUID in the form |
| 1225 | * "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" | 1293 | * "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" |
| 1226 | * Options for %pU are: | 1294 | * Options for %pU are: |
| @@ -1321,6 +1389,8 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, | |||
| 1321 | }} | 1389 | }} |
| 1322 | } | 1390 | } |
| 1323 | break; | 1391 | break; |
| 1392 | case 'E': | ||
| 1393 | return escaped_string(buf, end, ptr, spec, fmt); | ||
| 1324 | case 'U': | 1394 | case 'U': |
| 1325 | return uuid_string(buf, end, ptr, spec, fmt); | 1395 | return uuid_string(buf, end, ptr, spec, fmt); |
| 1326 | case 'V': | 1396 | case 'V': |
| @@ -1633,6 +1703,7 @@ qualifier: | |||
| 1633 | * %piS depending on sa_family of 'struct sockaddr *' print IPv4/IPv6 address | 1703 | * %piS depending on sa_family of 'struct sockaddr *' print IPv4/IPv6 address |
| 1634 | * %pU[bBlL] print a UUID/GUID in big or little endian using lower or upper | 1704 | * %pU[bBlL] print a UUID/GUID in big or little endian using lower or upper |
| 1635 | * case. | 1705 | * case. |
| 1706 | * %*pE[achnops] print an escaped buffer | ||
| 1636 | * %*ph[CDN] a variable-length hex string with a separator (supports up to 64 | 1707 | * %*ph[CDN] a variable-length hex string with a separator (supports up to 64 |
| 1637 | * bytes of the input) | 1708 | * bytes of the input) |
| 1638 | * %n is ignored | 1709 | * %n is ignored |
