PageRenderTime 36ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

/ext/standard/uniqid.c

http://github.com/php/php-src
C | 83 lines | 44 code | 13 blank | 26 comment | 6 complexity | fc1c3aef38dd395bc7e8f118abca04d0 MD5 | raw file
Possible License(s): BSD-2-Clause, BSD-3-Clause, MPL-2.0-no-copyleft-exception, LGPL-2.1
  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. | http://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. | Author: Stig Sæther Bakken <ssb@php.net> |
  14. +----------------------------------------------------------------------+
  15. */
  16. #include "php.h"
  17. #include <stdlib.h>
  18. #if HAVE_UNISTD_H
  19. #include <unistd.h>
  20. #endif
  21. #include <string.h>
  22. #include <errno.h>
  23. #include <stdio.h>
  24. #ifdef PHP_WIN32
  25. #include "win32/time.h"
  26. #else
  27. #include <sys/time.h>
  28. #endif
  29. #include "php_lcg.h"
  30. #ifdef HAVE_GETTIMEOFDAY
  31. ZEND_TLS struct timeval prev_tv = { 0, 0 };
  32. /* {{{ proto string uniqid([string prefix [, bool more_entropy]])
  33. Generates a unique ID */
  34. PHP_FUNCTION(uniqid)
  35. {
  36. char *prefix = "";
  37. zend_bool more_entropy = 0;
  38. zend_string *uniqid;
  39. int sec, usec;
  40. size_t prefix_len = 0;
  41. struct timeval tv;
  42. ZEND_PARSE_PARAMETERS_START(0, 2)
  43. Z_PARAM_OPTIONAL
  44. Z_PARAM_STRING(prefix, prefix_len)
  45. Z_PARAM_BOOL(more_entropy)
  46. ZEND_PARSE_PARAMETERS_END();
  47. /* This implementation needs current microsecond to change,
  48. * hence we poll time until it does. This is much faster than
  49. * calling usleep(1) which may cause the kernel to schedule
  50. * another process, causing a pause of around 10ms.
  51. */
  52. do {
  53. (void)gettimeofday((struct timeval *) &tv, (struct timezone *) NULL);
  54. } while (tv.tv_sec == prev_tv.tv_sec && tv.tv_usec == prev_tv.tv_usec);
  55. prev_tv.tv_sec = tv.tv_sec;
  56. prev_tv.tv_usec = tv.tv_usec;
  57. sec = (int) tv.tv_sec;
  58. usec = (int) (tv.tv_usec % 0x100000);
  59. /* The max value usec can have is 0xF423F, so we use only five hex
  60. * digits for usecs.
  61. */
  62. if (more_entropy) {
  63. uniqid = strpprintf(0, "%s%08x%05x%.8F", prefix, sec, usec, php_combined_lcg() * 10);
  64. } else {
  65. uniqid = strpprintf(0, "%s%08x%05x", prefix, sec, usec);
  66. }
  67. RETURN_STR(uniqid);
  68. }
  69. #endif
  70. /* }}} */