kaction.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <assert.h>
  5. #include <faux/str.h>
  6. #include <faux/conv.h>
  7. #include <faux/list.h>
  8. #include <klish/khelper.h>
  9. #include <klish/kaction.h>
  10. #include <klish/ksym.h>
  11. #include <klish/kplugin.h>
  12. struct kaction_s {
  13. char *sym_ref; // Text reference to symbol
  14. ksym_t *sym; // Symbol itself
  15. kplugin_t *plugin; // Source of symbol
  16. char *lock; // Named lock
  17. bool_t interrupt;
  18. kaction_io_e in;
  19. kaction_io_e out;
  20. kaction_cond_e exec_on;
  21. bool_t update_retcode;
  22. tri_t permanent;
  23. tri_t sync;
  24. char *script;
  25. void *udata;
  26. kaction_udata_free_fn udata_free_fn;
  27. };
  28. // Simple methods
  29. // Sym reference (must be resolved later)
  30. KGET_STR(action, sym_ref);
  31. KSET_STR_ONCE(action, sym_ref);
  32. // Lock
  33. KGET_STR(action, lock);
  34. KSET_STR(action, lock);
  35. // Interrupt
  36. KGET_BOOL(action, interrupt);
  37. KSET_BOOL(action, interrupt);
  38. // In/Out
  39. KGET(action, kaction_io_e, in);
  40. KSET(action, kaction_io_e, in);
  41. KGET(action, kaction_io_e, out);
  42. KSET(action, kaction_io_e, out);
  43. // Exec_on
  44. KGET(action, kaction_cond_e, exec_on);
  45. KSET(action, kaction_cond_e, exec_on);
  46. // Update_retcode
  47. KGET_BOOL(action, update_retcode);
  48. KSET_BOOL(action, update_retcode);
  49. // Permanent
  50. KGET(action, tri_t, permanent);
  51. KSET(action, tri_t, permanent);
  52. // Sync
  53. KGET(action, tri_t, sync);
  54. KSET(action, tri_t, sync);
  55. // Script
  56. KGET_STR(action, script);
  57. KSET_STR(action, script);
  58. // Symbol
  59. KGET(action, ksym_t *, sym);
  60. KSET(action, ksym_t *, sym);
  61. // Plugin. Source of sym
  62. KGET(action, kplugin_t *, plugin);
  63. KSET(action, kplugin_t *, plugin);
  64. kaction_t *kaction_new(void)
  65. {
  66. kaction_t *action = NULL;
  67. action = faux_zmalloc(sizeof(*action));
  68. assert(action);
  69. if (!action)
  70. return NULL;
  71. // Initialize
  72. action->sym_ref = NULL;
  73. action->lock = NULL;
  74. action->interrupt = BOOL_FALSE;
  75. action->in = KACTION_IO_FALSE;
  76. action->out = KACTION_IO_TRUE;
  77. action->exec_on = KACTION_COND_SUCCESS;
  78. action->update_retcode = BOOL_TRUE;
  79. action->script = NULL;
  80. action->sym = NULL;
  81. action->plugin = NULL;
  82. action->udata = NULL;
  83. action->udata_free_fn = NULL;
  84. return action;
  85. }
  86. void kaction_free(kaction_t *action)
  87. {
  88. if (!action)
  89. return;
  90. faux_str_free(action->sym_ref);
  91. faux_str_free(action->lock);
  92. faux_str_free(action->script);
  93. if (action->udata && action->udata_free_fn)
  94. action->udata_free_fn(action->udata);
  95. faux_free(action);
  96. }
  97. bool_t kaction_meet_exec_conditions(const kaction_t *action, int current_retcode)
  98. {
  99. bool_t r = BOOL_FALSE; // Default is pessimistic
  100. assert(action);
  101. if (!action)
  102. return BOOL_FALSE;
  103. switch (kaction_exec_on(action)) {
  104. case KACTION_COND_ALWAYS:
  105. r = BOOL_TRUE;
  106. break;
  107. case KACTION_COND_SUCCESS:
  108. if (0 == current_retcode)
  109. r = BOOL_TRUE;
  110. break;
  111. case KACTION_COND_FAIL:
  112. if (current_retcode != 0)
  113. r = BOOL_TRUE;
  114. break;
  115. default:
  116. r = BOOL_FALSE; // NEVER or NONE
  117. }
  118. return r;
  119. }
  120. bool_t kaction_is_permanent(const kaction_t *action)
  121. {
  122. ksym_t *sym = NULL;
  123. tri_t val = TRI_UNDEFINED;
  124. assert(action);
  125. if (!action)
  126. return BOOL_FALSE;
  127. sym = kaction_sym(action);
  128. if (!sym)
  129. return BOOL_FALSE;
  130. val = ksym_permanent(sym);
  131. if (TRI_UNDEFINED == val)
  132. val = kaction_permanent(action);
  133. if (TRI_TRUE == val)
  134. return BOOL_TRUE;
  135. return BOOL_FALSE; // Default if not set
  136. }
  137. bool_t kaction_is_sync(const kaction_t *action)
  138. {
  139. ksym_t *sym = NULL;
  140. tri_t val = TRI_UNDEFINED;
  141. assert(action);
  142. if (!action)
  143. return BOOL_FALSE;
  144. sym = kaction_sym(action);
  145. if (!sym)
  146. return BOOL_FALSE;
  147. val = ksym_sync(sym);
  148. if (TRI_UNDEFINED == val)
  149. val = kaction_sync(action);
  150. if (TRI_TRUE == val)
  151. return BOOL_TRUE;
  152. return BOOL_FALSE; // Default if not set
  153. }
  154. void *kaction_udata(const kaction_t *action)
  155. {
  156. assert(action);
  157. if (!action)
  158. return NULL;
  159. return action->udata;
  160. }
  161. bool_t kaction_set_udata(kaction_t *action, void *data,
  162. kaction_udata_free_fn free_fn)
  163. {
  164. assert(action);
  165. if (!action)
  166. return BOOL_FALSE;
  167. // Free old udata value
  168. if (action->udata) {
  169. if (action->udata_free_fn)
  170. action->udata_free_fn(action->udata);
  171. else if (free_fn)
  172. free_fn(action->udata);
  173. }
  174. action->udata = data;
  175. action->udata_free_fn = free_fn;
  176. return BOOL_TRUE;
  177. }