utilunix__my_system-common.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. /*
  2. lib - common code for testing lib/utilinux:my_system() function
  3. Copyright (C) 2013-2024
  4. Free Software Foundation, Inc.
  5. Written by:
  6. Slava Zanko <slavazanko@gmail.com>, 2013
  7. This file is part of the Midnight Commander.
  8. The Midnight Commander is free software: you can redistribute it
  9. and/or modify it under the terms of the GNU General Public License as
  10. published by the Free Software Foundation, either version 3 of the License,
  11. or (at your option) any later version.
  12. The Midnight Commander is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. GNU General Public License for more details.
  16. You should have received a copy of the GNU General Public License
  17. along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <signal.h>
  20. #include <unistd.h>
  21. #include "lib/vfs/vfs.h"
  22. /* --------------------------------------------------------------------------------------------- */
  23. /* @CapturedValue */
  24. static sigset_t *sigemptyset_set__captured;
  25. /* @ThenReturnValue */
  26. static int sigemptyset__return_value = 0;
  27. #ifdef sigemptyset
  28. #undef sigemptyset
  29. #endif
  30. /* @Mock */
  31. int
  32. sigemptyset (sigset_t *set)
  33. {
  34. sigemptyset_set__captured = set;
  35. return sigemptyset__return_value;
  36. }
  37. /* --------------------------------------------------------------------------------------------- */
  38. /* @CapturedValue */
  39. static GPtrArray *sigaction_signum__captured = NULL;
  40. /* @CapturedValue */
  41. static GPtrArray *sigaction_act__captured = NULL;
  42. /* @CapturedValue */
  43. static GPtrArray *sigaction_oldact__captured = NULL;
  44. /* @ThenReturnValue */
  45. static int sigaction__return_value = 0;
  46. /* @Mock */
  47. int
  48. my_sigaction (int signum, const struct sigaction *act, struct sigaction *oldact)
  49. {
  50. int *tmp_signum;
  51. struct sigaction *tmp_act;
  52. /* store signum */
  53. tmp_signum = g_new (int, 1);
  54. memcpy (tmp_signum, &signum, sizeof (*tmp_signum));
  55. if (sigaction_signum__captured != NULL)
  56. g_ptr_array_add (sigaction_signum__captured, tmp_signum);
  57. /* store act */
  58. if (act != NULL)
  59. {
  60. tmp_act = g_new (struct sigaction, 1);
  61. memcpy (tmp_act, act, sizeof (*tmp_act));
  62. }
  63. else
  64. tmp_act = NULL;
  65. if (sigaction_act__captured != NULL)
  66. g_ptr_array_add (sigaction_act__captured, tmp_act);
  67. /* store oldact */
  68. if (oldact != NULL)
  69. {
  70. tmp_act = g_new (struct sigaction, 1);
  71. memcpy (tmp_act, oldact, sizeof (*tmp_act));
  72. }
  73. else
  74. tmp_act = NULL;
  75. if (sigaction_oldact__captured != NULL)
  76. g_ptr_array_add (sigaction_oldact__captured, tmp_act);
  77. return sigaction__return_value;
  78. }
  79. static void
  80. sigaction__init (void)
  81. {
  82. sigaction_signum__captured = g_ptr_array_new_with_free_func (g_free);
  83. sigaction_act__captured = g_ptr_array_new_with_free_func (g_free);
  84. sigaction_oldact__captured = g_ptr_array_new_with_free_func (g_free);
  85. }
  86. static void
  87. sigaction__deinit (void)
  88. {
  89. g_ptr_array_free (sigaction_signum__captured, TRUE);
  90. sigaction_signum__captured = NULL;
  91. g_ptr_array_free (sigaction_act__captured, TRUE);
  92. sigaction_act__captured = NULL;
  93. g_ptr_array_free (sigaction_oldact__captured, TRUE);
  94. sigaction_oldact__captured = NULL;
  95. }
  96. /* --------------------------------------------------------------------------------------------- */
  97. /* @CapturedValue */
  98. static GPtrArray *signal_signum__captured;
  99. /* @CapturedValue */
  100. static GPtrArray *signal_handler__captured;
  101. /* @ThenReturnValue */
  102. static sighandler_t signal__return_value = NULL;
  103. /* @Mock */
  104. sighandler_t
  105. my_signal (int signum, sighandler_t handler)
  106. {
  107. int *tmp_signum;
  108. sighandler_t *tmp_handler;
  109. /* store signum */
  110. tmp_signum = g_new (int, 1);
  111. memcpy (tmp_signum, &signum, sizeof (*tmp_signum));
  112. g_ptr_array_add (signal_signum__captured, tmp_signum);
  113. /* store handler */
  114. if (handler != SIG_DFL)
  115. {
  116. tmp_handler = g_new (sighandler_t, 1);
  117. memcpy (tmp_handler, handler, sizeof (*tmp_handler));
  118. }
  119. else
  120. tmp_handler = (void *) SIG_DFL;
  121. g_ptr_array_add (signal_handler__captured, tmp_handler);
  122. return signal__return_value;
  123. }
  124. static void
  125. signal__init (void)
  126. {
  127. signal_signum__captured = g_ptr_array_new_with_free_func (g_free);
  128. signal_handler__captured = g_ptr_array_new_with_free_func (g_free);
  129. }
  130. static void
  131. signal__deinit (void)
  132. {
  133. g_ptr_array_free (signal_signum__captured, TRUE);
  134. signal_signum__captured = NULL;
  135. g_ptr_array_free (signal_handler__captured, TRUE);
  136. signal_handler__captured = NULL;
  137. }
  138. /* --------------------------------------------------------------------------------------------- */
  139. /* @ThenReturnValue */
  140. static pid_t fork__return_value;
  141. /* @Mock */
  142. pid_t
  143. my_fork (void)
  144. {
  145. return fork__return_value;
  146. }
  147. /* --------------------------------------------------------------------------------------------- */
  148. /* @CapturedValue */
  149. static int my_exit__status__captured;
  150. /* @Mock */
  151. void
  152. my_exit (int status)
  153. {
  154. my_exit__status__captured = status;
  155. }
  156. /* --------------------------------------------------------------------------------------------- */
  157. /* @CapturedValue */
  158. static char *execvp__file__captured = NULL;
  159. /* @CapturedValue */
  160. static GPtrArray *execvp__args__captured;
  161. /* @ThenReturnValue */
  162. static int execvp__return_value = 0;
  163. /* @Mock */
  164. int
  165. my_execvp (const char *file, char *const argv[])
  166. {
  167. char **one_arg;
  168. execvp__file__captured = g_strdup (file);
  169. for (one_arg = (char **) argv; *one_arg != NULL; one_arg++)
  170. g_ptr_array_add (execvp__args__captured, g_strdup (*one_arg));
  171. return execvp__return_value;
  172. }
  173. static void
  174. execvp__init (void)
  175. {
  176. execvp__args__captured = g_ptr_array_new_with_free_func (g_free);
  177. }
  178. static void
  179. execvp__deinit (void)
  180. {
  181. g_ptr_array_free (execvp__args__captured, TRUE);
  182. execvp__args__captured = NULL;
  183. MC_PTR_FREE (execvp__file__captured);
  184. }
  185. /* --------------------------------------------------------------------------------------------- */
  186. #define VERIFY_SIGACTION__ACT_IGNORED(_pntr) { \
  187. struct sigaction *_act = (struct sigaction *) _pntr; \
  188. mctest_assert_ptr_eq (_act->sa_handler, SIG_IGN); \
  189. ck_assert_int_eq (_act->sa_flags, 0); \
  190. }
  191. #define VERIFY_SIGACTION__IS_RESTORED(oldact_idx, act_idx) { \
  192. struct sigaction *_oldact = (struct sigaction *) g_ptr_array_index(sigaction_oldact__captured, oldact_idx); \
  193. struct sigaction *_act = (struct sigaction *) g_ptr_array_index(sigaction_act__captured, act_idx); \
  194. ck_assert_msg (memcmp(_oldact, _act, sizeof(struct sigaction)) == 0, \
  195. "sigaction(): oldact[%d] should be equals to act[%d]", oldact_idx, act_idx); \
  196. }
  197. /* @Verify */
  198. #define VERIFY_SIGACTION_CALLS() { \
  199. ck_assert_int_eq (sigaction_signum__captured->len, 6); \
  200. \
  201. ck_assert_int_eq (*((int *) g_ptr_array_index(sigaction_signum__captured, 0)), SIGINT); \
  202. ck_assert_int_eq (*((int *) g_ptr_array_index(sigaction_signum__captured, 1)), SIGQUIT); \
  203. ck_assert_int_eq (*((int *) g_ptr_array_index(sigaction_signum__captured, 2)), SIGTSTP); \
  204. ck_assert_int_eq (*((int *) g_ptr_array_index(sigaction_signum__captured, 3)), SIGINT); \
  205. ck_assert_int_eq (*((int *) g_ptr_array_index(sigaction_signum__captured, 4)), SIGQUIT); \
  206. ck_assert_int_eq (*((int *) g_ptr_array_index(sigaction_signum__captured, 5)), SIGTSTP); \
  207. \
  208. VERIFY_SIGACTION__ACT_IGNORED(g_ptr_array_index(sigaction_act__captured, 0)); \
  209. VERIFY_SIGACTION__ACT_IGNORED(g_ptr_array_index(sigaction_act__captured, 1)); \
  210. { \
  211. struct sigaction *_act = g_ptr_array_index(sigaction_act__captured, 2); \
  212. ck_assert_msg (memcmp (_act, &startup_handler, sizeof(struct sigaction)) == 0, \
  213. "The 'act' in third call to sigaction() should be equals to startup_handler"); \
  214. } \
  215. \
  216. VERIFY_SIGACTION__IS_RESTORED (0, 3); \
  217. VERIFY_SIGACTION__IS_RESTORED (1, 4); \
  218. VERIFY_SIGACTION__IS_RESTORED (2, 5); \
  219. \
  220. ck_assert_msg (g_ptr_array_index(sigaction_oldact__captured, 3) == NULL, \
  221. "oldact in fourth call to sigaction() should be NULL"); \
  222. ck_assert_msg (g_ptr_array_index(sigaction_oldact__captured, 4) == NULL, \
  223. "oldact in fifth call to sigaction() should be NULL"); \
  224. ck_assert_msg (g_ptr_array_index(sigaction_oldact__captured, 5) == NULL, \
  225. "oldact in sixth call to sigaction() should be NULL"); \
  226. }
  227. /* --------------------------------------------------------------------------------------------- */
  228. #define VERIFY_SIGNAL_HANDLER_IS_SIG_DFL(_idx) { \
  229. sighandler_t *tmp_handler = (sighandler_t *) g_ptr_array_index(signal_handler__captured, _idx);\
  230. mctest_assert_ptr_eq (tmp_handler, (sighandler_t *) SIG_DFL); \
  231. }
  232. /* @Verify */
  233. #define VERIFY_SIGNAL_CALLS() { \
  234. ck_assert_int_eq (signal_signum__captured->len, 4); \
  235. ck_assert_int_eq (*((int *) g_ptr_array_index(signal_signum__captured, 0)), SIGINT); \
  236. ck_assert_int_eq (*((int *) g_ptr_array_index(signal_signum__captured, 1)), SIGQUIT); \
  237. ck_assert_int_eq (*((int *) g_ptr_array_index(signal_signum__captured, 2)), SIGTSTP); \
  238. ck_assert_int_eq (*((int *) g_ptr_array_index(signal_signum__captured, 3)), SIGCHLD); \
  239. \
  240. VERIFY_SIGNAL_HANDLER_IS_SIG_DFL (0); \
  241. VERIFY_SIGNAL_HANDLER_IS_SIG_DFL (1); \
  242. VERIFY_SIGNAL_HANDLER_IS_SIG_DFL (2); \
  243. VERIFY_SIGNAL_HANDLER_IS_SIG_DFL (3); \
  244. }
  245. /* --------------------------------------------------------------------------------------------- */
  246. /* @Before */
  247. static void
  248. setup (void)
  249. {
  250. signal__return_value = NULL;
  251. sigaction__init ();
  252. signal__init ();
  253. execvp__init ();
  254. }
  255. /* --------------------------------------------------------------------------------------------- */
  256. /* @After */
  257. static void
  258. teardown (void)
  259. {
  260. execvp__deinit ();
  261. signal__deinit ();
  262. sigaction__deinit ();
  263. }
  264. /* --------------------------------------------------------------------------------------------- */