PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/grub-core/kern/misc.c

https://github.com/albertz/grub-fuse
C | 1019 lines | 796 code | 165 blank | 58 comment | 197 complexity | c35a07c9ecbaaa7de3d1242476ba2d11 MD5 | raw file
  1. /* misc.c - definitions of misc functions */
  2. /*
  3. * GRUB -- GRand Unified Bootloader
  4. * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
  5. *
  6. * GRUB is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * GRUB is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <grub/misc.h>
  20. #include <grub/err.h>
  21. #include <grub/mm.h>
  22. #include <stdarg.h>
  23. #include <grub/term.h>
  24. #include <grub/env.h>
  25. #include <grub/i18n.h>
  26. static int
  27. grub_vsnprintf_real (char *str, grub_size_t n, const char *fmt, va_list args);
  28. static int
  29. grub_iswordseparator (int c)
  30. {
  31. return (grub_isspace (c) || c == ',' || c == ';' || c == '|' || c == '&');
  32. }
  33. /* grub_gettext_dummy is not translating anything. */
  34. static const char *
  35. grub_gettext_dummy (const char *s)
  36. {
  37. return s;
  38. }
  39. const char* (*grub_gettext) (const char *s) = grub_gettext_dummy;
  40. void *
  41. grub_memmove (void *dest, const void *src, grub_size_t n)
  42. {
  43. char *d = (char *) dest;
  44. const char *s = (const char *) src;
  45. if (d < s)
  46. while (n--)
  47. *d++ = *s++;
  48. else
  49. {
  50. d += n;
  51. s += n;
  52. while (n--)
  53. *--d = *--s;
  54. }
  55. return dest;
  56. }
  57. #ifndef APPLE_CC
  58. void *memmove (void *dest, const void *src, grub_size_t n)
  59. __attribute__ ((alias ("grub_memmove")));
  60. /* GCC emits references to memcpy() for struct copies etc. */
  61. void *memcpy (void *dest, const void *src, grub_size_t n)
  62. __attribute__ ((alias ("grub_memmove")));
  63. #else
  64. void *memcpy (void *dest, const void *src, grub_size_t n)
  65. {
  66. return grub_memmove (dest, src, n);
  67. }
  68. void *memmove (void *dest, const void *src, grub_size_t n)
  69. {
  70. return grub_memmove (dest, src, n);
  71. }
  72. #endif
  73. char *
  74. grub_strcpy (char *dest, const char *src)
  75. {
  76. char *p = dest;
  77. while ((*p++ = *src++) != '\0')
  78. ;
  79. return dest;
  80. }
  81. char *
  82. grub_strncpy (char *dest, const char *src, int c)
  83. {
  84. char *p = dest;
  85. while ((*p++ = *src++) != '\0' && --c)
  86. ;
  87. return dest;
  88. }
  89. char *
  90. grub_stpcpy (char *dest, const char *src)
  91. {
  92. char *d = dest;
  93. const char *s = src;
  94. do
  95. *d++ = *s;
  96. while (*s++ != '\0');
  97. return d - 1;
  98. }
  99. int
  100. grub_printf (const char *fmt, ...)
  101. {
  102. va_list ap;
  103. int ret;
  104. va_start (ap, fmt);
  105. ret = grub_vprintf (fmt, ap);
  106. va_end (ap);
  107. return ret;
  108. }
  109. int
  110. grub_printf_ (const char *fmt, ...)
  111. {
  112. va_list ap;
  113. int ret;
  114. va_start (ap, fmt);
  115. ret = grub_vprintf (_(fmt), ap);
  116. va_end (ap);
  117. return ret;
  118. }
  119. int
  120. grub_puts_ (const char *s)
  121. {
  122. return grub_puts (_(s));
  123. }
  124. #if defined (APPLE_CC) && ! defined (GRUB_UTIL)
  125. int
  126. grub_err_printf (const char *fmt, ...)
  127. {
  128. va_list ap;
  129. int ret;
  130. va_start (ap, fmt);
  131. ret = grub_vprintf (fmt, ap);
  132. va_end (ap);
  133. return ret;
  134. }
  135. #endif
  136. #if ! defined (APPLE_CC) && ! defined (GRUB_UTIL)
  137. int grub_err_printf (const char *fmt, ...)
  138. __attribute__ ((alias("grub_printf")));
  139. #endif
  140. void
  141. grub_real_dprintf (const char *file, const int line, const char *condition,
  142. const char *fmt, ...)
  143. {
  144. va_list args;
  145. const char *debug = grub_env_get ("debug");
  146. if (! debug)
  147. return;
  148. if (grub_strword (debug, "all") || grub_strword (debug, condition))
  149. {
  150. grub_printf ("%s:%d: ", file, line);
  151. va_start (args, fmt);
  152. grub_vprintf (fmt, args);
  153. va_end (args);
  154. grub_refresh ();
  155. }
  156. }
  157. #define PREALLOC_SIZE 255
  158. int
  159. grub_vprintf (const char *fmt, va_list args)
  160. {
  161. grub_size_t s;
  162. static char buf[PREALLOC_SIZE + 1];
  163. char *curbuf = buf;
  164. va_list ap2;
  165. va_copy (ap2, args);
  166. s = grub_vsnprintf_real (buf, PREALLOC_SIZE, fmt, args);
  167. if (s > PREALLOC_SIZE)
  168. {
  169. curbuf = grub_malloc (s + 1);
  170. if (!curbuf)
  171. {
  172. grub_errno = GRUB_ERR_NONE;
  173. buf[PREALLOC_SIZE - 3] = '.';
  174. buf[PREALLOC_SIZE - 2] = '.';
  175. buf[PREALLOC_SIZE - 1] = '.';
  176. buf[PREALLOC_SIZE] = 0;
  177. }
  178. else
  179. s = grub_vsnprintf_real (curbuf, s, fmt, ap2);
  180. }
  181. grub_xputs (curbuf);
  182. if (curbuf != buf)
  183. grub_free (curbuf);
  184. return s;
  185. }
  186. int
  187. grub_memcmp (const void *s1, const void *s2, grub_size_t n)
  188. {
  189. const char *t1 = s1;
  190. const char *t2 = s2;
  191. while (n--)
  192. {
  193. if (*t1 != *t2)
  194. return (int) *t1 - (int) *t2;
  195. t1++;
  196. t2++;
  197. }
  198. return 0;
  199. }
  200. #ifndef APPLE_CC
  201. int memcmp (const void *s1, const void *s2, grub_size_t n)
  202. __attribute__ ((alias ("grub_memcmp")));
  203. #else
  204. int memcmp (const void *s1, const void *s2, grub_size_t n)
  205. {
  206. return grub_memcmp (s1, s2, n);
  207. }
  208. #endif
  209. int
  210. grub_strcmp (const char *s1, const char *s2)
  211. {
  212. while (*s1 && *s2)
  213. {
  214. if (*s1 != *s2)
  215. break;
  216. s1++;
  217. s2++;
  218. }
  219. return (int) *s1 - (int) *s2;
  220. }
  221. int
  222. grub_strncmp (const char *s1, const char *s2, grub_size_t n)
  223. {
  224. if (n == 0)
  225. return 0;
  226. while (*s1 && *s2 && --n)
  227. {
  228. if (*s1 != *s2)
  229. break;
  230. s1++;
  231. s2++;
  232. }
  233. return (int) *s1 - (int) *s2;
  234. }
  235. char *
  236. grub_strchr (const char *s, int c)
  237. {
  238. do
  239. {
  240. if (*s == c)
  241. return (char *) s;
  242. }
  243. while (*s++);
  244. return 0;
  245. }
  246. char *
  247. grub_strrchr (const char *s, int c)
  248. {
  249. char *p = NULL;
  250. do
  251. {
  252. if (*s == c)
  253. p = (char *) s;
  254. }
  255. while (*s++);
  256. return p;
  257. }
  258. /* Copied from gnulib.
  259. Written by Bruno Haible <bruno@clisp.org>, 2005. */
  260. char *
  261. grub_strstr (const char *haystack, const char *needle)
  262. {
  263. /* Be careful not to look at the entire extent of haystack or needle
  264. until needed. This is useful because of these two cases:
  265. - haystack may be very long, and a match of needle found early,
  266. - needle may be very long, and not even a short initial segment of
  267. needle may be found in haystack. */
  268. if (*needle != '\0')
  269. {
  270. /* Speed up the following searches of needle by caching its first
  271. character. */
  272. char b = *needle++;
  273. for (;; haystack++)
  274. {
  275. if (*haystack == '\0')
  276. /* No match. */
  277. return NULL;
  278. if (*haystack == b)
  279. /* The first character matches. */
  280. {
  281. const char *rhaystack = haystack + 1;
  282. const char *rneedle = needle;
  283. for (;; rhaystack++, rneedle++)
  284. {
  285. if (*rneedle == '\0')
  286. /* Found a match. */
  287. return (char *) haystack;
  288. if (*rhaystack == '\0')
  289. /* No match. */
  290. return NULL;
  291. if (*rhaystack != *rneedle)
  292. /* Nothing in this round. */
  293. break;
  294. }
  295. }
  296. }
  297. }
  298. else
  299. return (char *) haystack;
  300. }
  301. int
  302. grub_strword (const char *haystack, const char *needle)
  303. {
  304. const char *n_pos = needle;
  305. while (grub_iswordseparator (*haystack))
  306. haystack++;
  307. while (*haystack)
  308. {
  309. /* Crawl both the needle and the haystack word we're on. */
  310. while(*haystack && !grub_iswordseparator (*haystack)
  311. && *haystack == *n_pos)
  312. {
  313. haystack++;
  314. n_pos++;
  315. }
  316. /* If we reached the end of both words at the same time, the word
  317. is found. If not, eat everything in the haystack that isn't the
  318. next word (or the end of string) and "reset" the needle. */
  319. if ( (!*haystack || grub_iswordseparator (*haystack))
  320. && (!*n_pos || grub_iswordseparator (*n_pos)))
  321. return 1;
  322. else
  323. {
  324. n_pos = needle;
  325. while (*haystack && !grub_iswordseparator (*haystack))
  326. haystack++;
  327. while (grub_iswordseparator (*haystack))
  328. haystack++;
  329. }
  330. }
  331. return 0;
  332. }
  333. int
  334. grub_isspace (int c)
  335. {
  336. return (c == '\n' || c == '\r' || c == ' ' || c == '\t');
  337. }
  338. int
  339. grub_isprint (int c)
  340. {
  341. return (c >= ' ' && c <= '~');
  342. }
  343. unsigned long
  344. grub_strtoul (const char *str, char **end, int base)
  345. {
  346. unsigned long long num;
  347. num = grub_strtoull (str, end, base);
  348. if (num > ~0UL)
  349. {
  350. grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow is detected");
  351. return ~0UL;
  352. }
  353. return (unsigned long) num;
  354. }
  355. unsigned long long
  356. grub_strtoull (const char *str, char **end, int base)
  357. {
  358. unsigned long long num = 0;
  359. int found = 0;
  360. /* Skip white spaces. */
  361. while (*str && grub_isspace (*str))
  362. str++;
  363. /* Guess the base, if not specified. The prefix `0x' means 16, and
  364. the prefix `0' means 8. */
  365. if (str[0] == '0')
  366. {
  367. if (str[1] == 'x')
  368. {
  369. if (base == 0 || base == 16)
  370. {
  371. base = 16;
  372. str += 2;
  373. }
  374. }
  375. else if (base == 0 && str[1] >= '0' && str[1] <= '7')
  376. base = 8;
  377. }
  378. if (base == 0)
  379. base = 10;
  380. while (*str)
  381. {
  382. unsigned long digit;
  383. digit = grub_tolower (*str) - '0';
  384. if (digit > 9)
  385. {
  386. digit += '0' - 'a' + 10;
  387. if (digit >= (unsigned long) base)
  388. break;
  389. }
  390. found = 1;
  391. /* NUM * BASE + DIGIT > ~0ULL */
  392. if (num > grub_divmod64 (~0ULL - digit, base, 0))
  393. {
  394. grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow is detected");
  395. return ~0ULL;
  396. }
  397. num = num * base + digit;
  398. str++;
  399. }
  400. if (! found)
  401. {
  402. grub_error (GRUB_ERR_BAD_NUMBER, "unrecognized number");
  403. return 0;
  404. }
  405. if (end)
  406. *end = (char *) str;
  407. return num;
  408. }
  409. char *
  410. grub_strdup (const char *s)
  411. {
  412. grub_size_t len;
  413. char *p;
  414. len = grub_strlen (s) + 1;
  415. p = (char *) grub_malloc (len);
  416. if (! p)
  417. return 0;
  418. return grub_memcpy (p, s, len);
  419. }
  420. char *
  421. grub_strndup (const char *s, grub_size_t n)
  422. {
  423. grub_size_t len;
  424. char *p;
  425. len = grub_strlen (s);
  426. if (len > n)
  427. len = n;
  428. p = (char *) grub_malloc (len + 1);
  429. if (! p)
  430. return 0;
  431. grub_memcpy (p, s, len);
  432. p[len] = '\0';
  433. return p;
  434. }
  435. void *
  436. grub_memset (void *s, int c, grub_size_t len)
  437. {
  438. void *p = s;
  439. grub_uint8_t pattern8 = c;
  440. if (len >= 3 * sizeof (unsigned long))
  441. {
  442. unsigned long patternl = 0;
  443. grub_size_t i;
  444. for (i = 0; i < sizeof (unsigned long); i++)
  445. patternl |= ((unsigned long) pattern8) << (8 * i);
  446. while (len > 0 && (((grub_addr_t) p) & (sizeof (unsigned long) - 1)))
  447. {
  448. *(grub_uint8_t *) p = pattern8;
  449. p = (grub_uint8_t *) p + 1;
  450. len--;
  451. }
  452. while (len >= sizeof (unsigned long))
  453. {
  454. *(unsigned long *) p = patternl;
  455. p = (unsigned long *) p + 1;
  456. len -= sizeof (unsigned long);
  457. }
  458. }
  459. while (len > 0)
  460. {
  461. *(grub_uint8_t *) p = pattern8;
  462. p = (grub_uint8_t *) p + 1;
  463. len--;
  464. }
  465. return s;
  466. }
  467. #ifndef APPLE_CC
  468. void *memset (void *s, int c, grub_size_t n)
  469. __attribute__ ((alias ("grub_memset")));
  470. #else
  471. void *memset (void *s, int c, grub_size_t n)
  472. {
  473. return grub_memset (s, c, n);
  474. }
  475. #endif
  476. grub_size_t
  477. grub_strlen (const char *s)
  478. {
  479. const char *p = s;
  480. while (*p)
  481. p++;
  482. return p - s;
  483. }
  484. static inline void
  485. grub_reverse (char *str)
  486. {
  487. char *p = str + grub_strlen (str) - 1;
  488. while (str < p)
  489. {
  490. char tmp;
  491. tmp = *str;
  492. *str = *p;
  493. *p = tmp;
  494. str++;
  495. p--;
  496. }
  497. }
  498. /* Divide N by D, return the quotient, and store the remainder in *R. */
  499. grub_uint64_t
  500. grub_divmod64 (grub_uint64_t n, grub_uint32_t d, grub_uint32_t *r)
  501. {
  502. /* This algorithm is typically implemented by hardware. The idea
  503. is to get the highest bit in N, 64 times, by keeping
  504. upper(N * 2^i) = upper((Q * 10 + M) * 2^i), where upper
  505. represents the high 64 bits in 128-bits space. */
  506. unsigned bits = 64;
  507. unsigned long long q = 0;
  508. unsigned m = 0;
  509. /* Skip the slow computation if 32-bit arithmetic is possible. */
  510. if (n < 0xffffffff)
  511. {
  512. if (r)
  513. *r = ((grub_uint32_t) n) % d;
  514. return ((grub_uint32_t) n) / d;
  515. }
  516. while (bits--)
  517. {
  518. m <<= 1;
  519. if (n & (1ULL << 63))
  520. m |= 1;
  521. q <<= 1;
  522. n <<= 1;
  523. if (m >= d)
  524. {
  525. q |= 1;
  526. m -= d;
  527. }
  528. }
  529. if (r)
  530. *r = m;
  531. return q;
  532. }
  533. /* Convert a long long value to a string. This function avoids 64-bit
  534. modular arithmetic or divisions. */
  535. static char *
  536. grub_lltoa (char *str, int c, unsigned long long n)
  537. {
  538. unsigned base = (c == 'x') ? 16 : 10;
  539. char *p;
  540. if ((long long) n < 0 && c == 'd')
  541. {
  542. n = (unsigned long long) (-((long long) n));
  543. *str++ = '-';
  544. }
  545. p = str;
  546. if (base == 16)
  547. do
  548. {
  549. unsigned d = (unsigned) (n & 0xf);
  550. *p++ = (d > 9) ? d + 'a' - 10 : d + '0';
  551. }
  552. while (n >>= 4);
  553. else
  554. /* BASE == 10 */
  555. do
  556. {
  557. unsigned m;
  558. n = grub_divmod64 (n, 10, &m);
  559. *p++ = m + '0';
  560. }
  561. while (n);
  562. *p = 0;
  563. grub_reverse (str);
  564. return p;
  565. }
  566. static int
  567. grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt, va_list args)
  568. {
  569. char c;
  570. grub_size_t count = 0;
  571. auto void write_char (unsigned char ch);
  572. auto void write_str (const char *s);
  573. auto void write_fill (const char ch, int n);
  574. void write_char (unsigned char ch)
  575. {
  576. if (count < max_len)
  577. *str++ = ch;
  578. count++;
  579. }
  580. void write_str (const char *s)
  581. {
  582. while (*s)
  583. write_char (*s++);
  584. }
  585. void write_fill (const char ch, int n)
  586. {
  587. int i;
  588. for (i = 0; i < n; i++)
  589. write_char (ch);
  590. }
  591. while ((c = *fmt++) != 0)
  592. {
  593. if (c != '%')
  594. write_char (c);
  595. else
  596. {
  597. char tmp[32];
  598. char *p;
  599. unsigned int format1 = 0;
  600. unsigned int format2 = ~ 0U;
  601. char zerofill = ' ';
  602. int rightfill = 0;
  603. int n;
  604. int longfmt = 0;
  605. int longlongfmt = 0;
  606. int unsig = 0;
  607. if (*fmt && *fmt =='-')
  608. {
  609. rightfill = 1;
  610. fmt++;
  611. }
  612. p = (char *) fmt;
  613. /* Read formatting parameters. */
  614. while (*p && grub_isdigit (*p))
  615. p++;
  616. if (p > fmt)
  617. {
  618. char s[p - fmt + 1];
  619. grub_strncpy (s, fmt, p - fmt);
  620. s[p - fmt] = 0;
  621. if (s[0] == '0')
  622. zerofill = '0';
  623. format1 = grub_strtoul (s, 0, 10);
  624. fmt = p;
  625. }
  626. if (*p && *p == '.')
  627. {
  628. p++;
  629. fmt++;
  630. while (*p && grub_isdigit (*p))
  631. p++;
  632. if (p > fmt)
  633. {
  634. char fstr[p - fmt + 1];
  635. grub_strncpy (fstr, fmt, p - fmt);
  636. fstr[p - fmt] = 0;
  637. format2 = grub_strtoul (fstr, 0, 10);
  638. fmt = p;
  639. }
  640. }
  641. c = *fmt++;
  642. if (c == 'l')
  643. {
  644. longfmt = 1;
  645. c = *fmt++;
  646. if (c == 'l')
  647. {
  648. longlongfmt = 1;
  649. c = *fmt++;
  650. }
  651. }
  652. switch (c)
  653. {
  654. case 'p':
  655. write_str ("0x");
  656. c = 'x';
  657. longlongfmt |= (sizeof (void *) == sizeof (long long));
  658. /* Fall through. */
  659. case 'x':
  660. case 'u':
  661. unsig = 1;
  662. /* Fall through. */
  663. case 'd':
  664. if (longlongfmt)
  665. {
  666. long long ll;
  667. ll = va_arg (args, long long);
  668. grub_lltoa (tmp, c, ll);
  669. }
  670. else if (longfmt && unsig)
  671. {
  672. unsigned long l = va_arg (args, unsigned long);
  673. grub_lltoa (tmp, c, l);
  674. }
  675. else if (longfmt)
  676. {
  677. long l = va_arg (args, long);
  678. grub_lltoa (tmp, c, l);
  679. }
  680. else if (unsig)
  681. {
  682. unsigned u = va_arg (args, unsigned);
  683. grub_lltoa (tmp, c, u);
  684. }
  685. else
  686. {
  687. n = va_arg (args, int);
  688. grub_lltoa (tmp, c, n);
  689. }
  690. if (! rightfill && grub_strlen (tmp) < format1)
  691. write_fill (zerofill, format1 - grub_strlen (tmp));
  692. write_str (tmp);
  693. if (rightfill && grub_strlen (tmp) < format1)
  694. write_fill (zerofill, format1 - grub_strlen (tmp));
  695. break;
  696. case 'c':
  697. n = va_arg (args, int);
  698. write_char (n & 0xff);
  699. break;
  700. case 'C':
  701. {
  702. grub_uint32_t code = va_arg (args, grub_uint32_t);
  703. int shift;
  704. unsigned mask;
  705. if (code <= 0x7f)
  706. {
  707. shift = 0;
  708. mask = 0;
  709. }
  710. else if (code <= 0x7ff)
  711. {
  712. shift = 6;
  713. mask = 0xc0;
  714. }
  715. else if (code <= 0xffff)
  716. {
  717. shift = 12;
  718. mask = 0xe0;
  719. }
  720. else if (code <= 0x1fffff)
  721. {
  722. shift = 18;
  723. mask = 0xf0;
  724. }
  725. else if (code <= 0x3ffffff)
  726. {
  727. shift = 24;
  728. mask = 0xf8;
  729. }
  730. else if (code <= 0x7fffffff)
  731. {
  732. shift = 30;
  733. mask = 0xfc;
  734. }
  735. else
  736. {
  737. code = '?';
  738. shift = 0;
  739. mask = 0;
  740. }
  741. write_char (mask | (code >> shift));
  742. for (shift -= 6; shift >= 0; shift -= 6)
  743. write_char (0x80 | (0x3f & (code >> shift)));
  744. }
  745. break;
  746. case 's':
  747. p = va_arg (args, char *);
  748. if (p)
  749. {
  750. grub_size_t len = 0;
  751. while (len < format2 && p[len])
  752. len++;
  753. if (!rightfill && len < format1)
  754. write_fill (zerofill, format1 - len);
  755. grub_size_t i;
  756. for (i = 0; i < len; i++)
  757. write_char (*p++);
  758. if (rightfill && len < format1)
  759. write_fill (zerofill, format1 - len);
  760. }
  761. else
  762. write_str ("(null)");
  763. break;
  764. default:
  765. write_char (c);
  766. break;
  767. }
  768. }
  769. }
  770. *str = '\0';
  771. return count;
  772. }
  773. int
  774. grub_vsnprintf (char *str, grub_size_t n, const char *fmt, va_list ap)
  775. {
  776. grub_size_t ret;
  777. if (!n)
  778. return 0;
  779. n--;
  780. ret = grub_vsnprintf_real (str, n, fmt, ap);
  781. return ret < n ? ret : n;
  782. }
  783. int
  784. grub_snprintf (char *str, grub_size_t n, const char *fmt, ...)
  785. {
  786. va_list ap;
  787. int ret;
  788. va_start (ap, fmt);
  789. ret = grub_vsnprintf (str, n, fmt, ap);
  790. va_end (ap);
  791. return ret;
  792. }
  793. char *
  794. grub_xvasprintf (const char *fmt, va_list ap)
  795. {
  796. grub_size_t s, as = PREALLOC_SIZE;
  797. char *ret;
  798. while (1)
  799. {
  800. va_list ap2;
  801. va_copy (ap2, ap);
  802. ret = grub_malloc (as + 1);
  803. if (!ret)
  804. return NULL;
  805. s = grub_vsnprintf_real (ret, as, fmt, ap2);
  806. if (s <= as)
  807. return ret;
  808. grub_free (ret);
  809. as = s;
  810. }
  811. }
  812. char *
  813. grub_xasprintf (const char *fmt, ...)
  814. {
  815. va_list ap;
  816. char *ret;
  817. va_start (ap, fmt);
  818. ret = grub_xvasprintf (fmt, ap);
  819. va_end (ap);
  820. return ret;
  821. }
  822. /* Abort GRUB. This function does not return. */
  823. void
  824. grub_abort (void)
  825. {
  826. grub_printf ("\nAborted.");
  827. #ifndef GRUB_UTIL
  828. if (grub_term_inputs)
  829. #endif
  830. {
  831. grub_printf (" Press any key to exit.");
  832. grub_getkey ();
  833. }
  834. grub_exit ();
  835. }
  836. #if ! defined (APPLE_CC) && !defined (GRUB_UTIL)
  837. /* GCC emits references to abort(). */
  838. void abort (void) __attribute__ ((alias ("grub_abort")));
  839. #endif
  840. #if NEED_ENABLE_EXECUTE_STACK && !defined(GRUB_UTIL) && !defined(GRUB_MACHINE_EMU)
  841. /* Some gcc versions generate a call to this function
  842. in trampolines for nested functions. */
  843. void __enable_execute_stack (void *addr __attribute__ ((unused)))
  844. {
  845. }
  846. #endif
  847. #if NEED_REGISTER_FRAME_INFO && !defined(GRUB_UTIL)
  848. void __register_frame_info (void)
  849. {
  850. }
  851. void __deregister_frame_info (void)
  852. {
  853. }
  854. #endif