phpdbg_out.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Copyright (c) The PHP Group |
  4. +----------------------------------------------------------------------+
  5. | This source file is subject to version 3.01 of the PHP license, |
  6. | that is bundled with this package in the file LICENSE, and is |
  7. | available through the world-wide-web at the following url: |
  8. | https://www.php.net/license/3_01.txt |
  9. | If you did not receive a copy of the PHP license and are unable to |
  10. | obtain it through the world-wide-web, please send a note to |
  11. | license@php.net so we can mail you a copy immediately. |
  12. +----------------------------------------------------------------------+
  13. | Authors: Felipe Pena <felipe@php.net> |
  14. | Authors: Joe Watkins <joe.watkins@live.co.uk> |
  15. | Authors: Bob Weinand <bwoebi@php.net> |
  16. +----------------------------------------------------------------------+
  17. */
  18. #include "zend.h"
  19. #include "php.h"
  20. #include "spprintf.h"
  21. #include "phpdbg.h"
  22. #include "phpdbg_io.h"
  23. #include "ext/standard/html.h"
  24. #ifdef _WIN32
  25. # include "win32/time.h"
  26. #endif
  27. ZEND_EXTERN_MODULE_GLOBALS(phpdbg)
  28. PHPDBG_API int _phpdbg_asprintf(char **buf, const char *format, ...) {
  29. int ret;
  30. va_list va;
  31. va_start(va, format);
  32. ret = vasprintf(buf, format, va);
  33. va_end(va);
  34. return ret;
  35. }
  36. static int phpdbg_process_print(int fd, int type, const char *msg, int msglen) {
  37. char *msgout = NULL;
  38. int msgoutlen = FAILURE;
  39. switch (type) {
  40. case P_ERROR:
  41. if (!PHPDBG_G(last_was_newline)) {
  42. phpdbg_mixed_write(fd, ZEND_STRL("\n"));
  43. PHPDBG_G(last_was_newline) = 1;
  44. }
  45. if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) {
  46. msgoutlen = phpdbg_asprintf(&msgout, "\033[%sm[%.*s]\033[0m\n", PHPDBG_G(colors)[PHPDBG_COLOR_ERROR]->code, msglen, msg);
  47. } else {
  48. msgoutlen = phpdbg_asprintf(&msgout, "[%.*s]\n", msglen, msg);
  49. }
  50. break;
  51. case P_NOTICE:
  52. if (!PHPDBG_G(last_was_newline)) {
  53. phpdbg_mixed_write(fd, ZEND_STRL("\n"));
  54. PHPDBG_G(last_was_newline) = 1;
  55. }
  56. if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) {
  57. msgoutlen = phpdbg_asprintf(&msgout, "\033[%sm[%.*s]\033[0m\n", PHPDBG_G(colors)[PHPDBG_COLOR_NOTICE]->code, msglen, msg);
  58. } else {
  59. msgoutlen = phpdbg_asprintf(&msgout, "[%.*s]\n", msglen, msg);
  60. }
  61. break;
  62. case P_WRITELN:
  63. if (msg) {
  64. msgoutlen = phpdbg_asprintf(&msgout, "%.*s\n", msglen, msg);
  65. } else {
  66. msgoutlen = 1;
  67. msgout = strdup("\n");
  68. }
  69. PHPDBG_G(last_was_newline) = 1;
  70. break;
  71. case P_WRITE:
  72. if (msg) {
  73. msgout = pestrndup(msg, msglen, 1);
  74. msgoutlen = msglen;
  75. PHPDBG_G(last_was_newline) = msg[msglen - 1] == '\n';
  76. } else {
  77. msgoutlen = 0;
  78. msgout = strdup("");
  79. }
  80. break;
  81. case P_STDOUT:
  82. case P_STDERR:
  83. if (msg) {
  84. PHPDBG_G(last_was_newline) = msg[msglen - 1] == '\n';
  85. phpdbg_mixed_write(fd, msg, msglen);
  86. }
  87. return msglen;
  88. /* no formatting on logging output */
  89. case P_LOG:
  90. if (msg) {
  91. struct timeval tp;
  92. if (gettimeofday(&tp, NULL) == SUCCESS) {
  93. msgoutlen = phpdbg_asprintf(&msgout, "[%ld %.8F]: %.*s\n", tp.tv_sec, tp.tv_usec / 1000000., msglen, msg);
  94. } else {
  95. msgoutlen = FAILURE;
  96. }
  97. }
  98. break;
  99. EMPTY_SWITCH_DEFAULT_CASE()
  100. }
  101. if (msgoutlen != FAILURE) {
  102. phpdbg_mixed_write(fd, msgout, msgoutlen);
  103. free(msgout);
  104. }
  105. return msgoutlen;
  106. } /* }}} */
  107. PHPDBG_API int phpdbg_vprint(int type, int fd, const char *strfmt, va_list args) {
  108. char *msg = NULL;
  109. int msglen = 0;
  110. int len;
  111. va_list argcpy;
  112. if (strfmt != NULL && strlen(strfmt) > 0L) {
  113. va_copy(argcpy, args);
  114. msglen = vasprintf(&msg, strfmt, argcpy);
  115. va_end(argcpy);
  116. }
  117. if (PHPDBG_G(err_buf).active && type != P_STDOUT && type != P_STDERR) {
  118. phpdbg_free_err_buf();
  119. PHPDBG_G(err_buf).type = type;
  120. PHPDBG_G(err_buf).fd = fd;
  121. PHPDBG_G(err_buf).msg = msg;
  122. PHPDBG_G(err_buf).msglen = msglen;
  123. return msglen;
  124. }
  125. len = phpdbg_process_print(fd, type, msg, msglen);
  126. if (msg) {
  127. free(msg);
  128. }
  129. return len;
  130. }
  131. PHPDBG_API void phpdbg_free_err_buf(void) {
  132. if (PHPDBG_G(err_buf).type == 0) {
  133. return;
  134. }
  135. free(PHPDBG_G(err_buf).msg);
  136. PHPDBG_G(err_buf).type = 0;
  137. }
  138. PHPDBG_API void phpdbg_activate_err_buf(bool active) {
  139. PHPDBG_G(err_buf).active = active;
  140. }
  141. PHPDBG_API int phpdbg_output_err_buf(const char *strfmt, ...) {
  142. int len;
  143. va_list args;
  144. int errbuf_active = PHPDBG_G(err_buf).active;
  145. if (PHPDBG_G(flags) & PHPDBG_DISCARD_OUTPUT) {
  146. return 0;
  147. }
  148. PHPDBG_G(err_buf).active = 0;
  149. va_start(args, strfmt);
  150. len = phpdbg_vprint(PHPDBG_G(err_buf).type, PHPDBG_G(err_buf).fd, strfmt, args);
  151. va_end(args);
  152. PHPDBG_G(err_buf).active = errbuf_active;
  153. phpdbg_free_err_buf();
  154. return len;
  155. }
  156. PHPDBG_API int phpdbg_print(int type, int fd, const char *strfmt, ...) {
  157. va_list args;
  158. int len;
  159. if (PHPDBG_G(flags) & PHPDBG_DISCARD_OUTPUT) {
  160. return 0;
  161. }
  162. va_start(args, strfmt);
  163. len = phpdbg_vprint(type, fd, strfmt, args);
  164. va_end(args);
  165. return len;
  166. }
  167. PHPDBG_API int phpdbg_log_internal(int fd, const char *fmt, ...) {
  168. va_list args;
  169. char *buffer;
  170. int buflen;
  171. int len = 0;
  172. va_start(args, fmt);
  173. buflen = vasprintf(&buffer, fmt, args);
  174. va_end(args);
  175. len = phpdbg_mixed_write(fd, buffer, buflen);
  176. free(buffer);
  177. return len;
  178. }
  179. PHPDBG_API int phpdbg_out_internal(int fd, const char *fmt, ...) {
  180. va_list args;
  181. char *buffer;
  182. int buflen;
  183. int len = 0;
  184. if (PHPDBG_G(flags) & PHPDBG_DISCARD_OUTPUT) {
  185. return 0;
  186. }
  187. va_start(args, fmt);
  188. buflen = vasprintf(&buffer, fmt, args);
  189. va_end(args);
  190. len = phpdbg_mixed_write(fd, buffer, buflen);
  191. free(buffer);
  192. return len;
  193. }