util.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /*
  2. * wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
  3. * For license, see COPYING.
  4. */
  5. #define _GNU_SOURCE /* vasprintf() */
  6. #include <stdint.h>
  7. #include <string.h>
  8. #include "util.h"
  9. /** malloc with error support and size_t overflow protection
  10. * \param nmemb number of objects
  11. * \param size size of single object
  12. * \return non null void pointer
  13. */
  14. void*
  15. xmalloc(size_t nmemb, size_t size)
  16. {
  17. void *ret;
  18. if(SIZE_MAX / nmemb < size)
  19. err(EXIT_FAILURE, "xmalloc(%zu, %zu), "
  20. "size_t overflow detected", nmemb, size);
  21. if((ret = malloc(nmemb * size)) == NULL)
  22. err(EXIT_FAILURE, "malloc(%zu)", nmemb * size);
  23. return ret;
  24. }
  25. /** calloc with error support
  26. * \param nmemb Number of objects
  27. * \param size size of single object
  28. * \return non null void pointer
  29. */
  30. void*
  31. xcalloc(size_t nmemb, size_t size)
  32. {
  33. void *ret;
  34. if((ret = calloc(nmemb, size)) == NULL)
  35. err(EXIT_FAILURE, "calloc(%zu * %zu)", nmemb, size);
  36. return ret;
  37. }
  38. /** asprintf wrapper
  39. * \param strp target string
  40. * \param fmt format
  41. * \return non zero integer
  42. */
  43. int
  44. xasprintf(char **strp, const char *fmt, ...)
  45. {
  46. int ret;
  47. va_list args;
  48. va_start(args, fmt);
  49. ret = vasprintf(strp, fmt, args);
  50. va_end(args);
  51. if (ret == -1)
  52. err(EXIT_FAILURE, "asprintf(%s)", fmt);
  53. return ret;
  54. }
  55. /** strdup with error support
  56. * \param str char pointer
  57. * \retun non null void pointer
  58. */
  59. char *
  60. xstrdup(const char *str)
  61. {
  62. char *ret;
  63. if (str == NULL || (ret = strdup(str)) == NULL)
  64. err(EXIT_FAILURE, "strdup(%s)", str);
  65. return ret;
  66. }
  67. /** Execute a system command
  68. * \param cmd Command
  69. * \return child pid
  70. */
  71. pid_t
  72. spawn(const char *format, ...)
  73. {
  74. char *sh = NULL;
  75. char cmd[512];
  76. va_list ap;
  77. pid_t pid;
  78. size_t len;
  79. va_start(ap, format);
  80. len = vsnprintf(cmd, sizeof(cmd), format, ap);
  81. va_end(ap);
  82. if (len >= sizeof(cmd))
  83. {
  84. warnx("command too long (> 512 bytes)");
  85. return -1;
  86. }
  87. if(!(sh = getenv("SHELL")))
  88. sh = "/bin/sh";
  89. if((pid = fork()) == 0)
  90. {
  91. setsid();
  92. if (execl(sh, sh, "-c", cmd, (char*)NULL) == -1)
  93. warn("execl(sh -c %s)", cmd);
  94. exit(EXIT_FAILURE);
  95. }
  96. else if (pid == -1)
  97. warn("fork");
  98. return pid;
  99. }
  100. void
  101. uicb_spawn(Uicb cmd)
  102. {
  103. spawn("%s", cmd);
  104. }