⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 utils.c

📁 wget (command line browser) source code
💻 C
📖 第 1 页 / 共 4 页
字号:
  /* Approximately, the time elapsed between the true start of the     measurement and the time represented by START.  */  double elapsed_pre_start;};/* Allocate a timer.  It is not legal to do anything with a freshly   allocated timer, except call wtimer_reset() or wtimer_delete().  */struct wget_timer *wtimer_allocate (void){  struct wget_timer *wt =    (struct wget_timer *)xmalloc (sizeof (struct wget_timer));  return wt;}/* Allocate a new timer and reset it.  Return the new timer. */struct wget_timer *wtimer_new (void){  struct wget_timer *wt = wtimer_allocate ();  wtimer_reset (wt);  return wt;}/* Free the resources associated with the timer.  Its further use is   prohibited.  */voidwtimer_delete (struct wget_timer *wt){  xfree (wt);}/* Store system time to WST.  */static voidwtimer_sys_set (wget_sys_time *wst){#ifdef TIMER_GETTIMEOFDAY  gettimeofday (wst, NULL);#endif#ifdef TIMER_TIME  time (wst);#endif#ifdef TIMER_WINDOWS  /* We use GetSystemTime to get the elapsed time.  MSDN warns that     system clock adjustments can skew the output of GetSystemTime     when used as a timer and gives preference to GetTickCount and     high-resolution timers.  But GetTickCount can overflow, and hires     timers are typically used for profiling, not for regular time     measurement.  Since we handle clock skew anyway, we just use     GetSystemTime.  */  FILETIME ft;  SYSTEMTIME st;  GetSystemTime (&st);  /* As recommended by MSDN, we convert SYSTEMTIME to FILETIME, copy     FILETIME to ULARGE_INTEGER, and use regular 64-bit integer     arithmetic on that.  */  SystemTimeToFileTime (&st, &ft);  wst->HighPart = ft.dwHighDateTime;  wst->LowPart  = ft.dwLowDateTime;#endif}/* Reset timer WT.  This establishes the starting point from which   wtimer_elapsed() will return the number of elapsed   milliseconds.  It is allowed to reset a previously used timer.  */voidwtimer_reset (struct wget_timer *wt){  /* Set the start time to the current time. */  wtimer_sys_set (&wt->start);  wt->elapsed_last = 0;  wt->elapsed_pre_start = 0;}static doublewtimer_sys_diff (wget_sys_time *wst1, wget_sys_time *wst2){#ifdef TIMER_GETTIMEOFDAY  return ((double)(wst1->tv_sec - wst2->tv_sec) * 1000	  + (double)(wst1->tv_usec - wst2->tv_usec) / 1000);#endif#ifdef TIMER_TIME  return 1000 * (*wst1 - *wst2);#endif#ifdef WINDOWS  /* VC++ 6 doesn't support direct cast of uint64 to double.  To work     around this, we subtract, then convert to signed, then finally to     double.  */  return (double)(signed __int64)(wst1->QuadPart - wst2->QuadPart) / 10000;#endif}/* Return the number of milliseconds elapsed since the timer was last   reset.  It is allowed to call this function more than once to get   increasingly higher elapsed values.  These timers handle clock   skew.  */doublewtimer_elapsed (struct wget_timer *wt){  wget_sys_time now;  double elapsed;  wtimer_sys_set (&now);  elapsed = wt->elapsed_pre_start + wtimer_sys_diff (&now, &wt->start);  /* Ideally we'd just return the difference between NOW and     wt->start.  However, the system timer can be set back, and we     could return a value smaller than when we were last called, even     a negative value.  Both of these would confuse the callers, which     expect us to return monotonically nondecreasing values.     Therefore: if ELAPSED is smaller than its previous known value,     we reset wt->start to the current time and effectively start     measuring from this point.  But since we don't want the elapsed     value to start from zero, we set elapsed_pre_start to the last     elapsed time and increment all future calculations by that     amount.  */  if (elapsed < wt->elapsed_last)    {      wt->start = now;      wt->elapsed_pre_start = wt->elapsed_last;      elapsed = wt->elapsed_last;    }  wt->elapsed_last = elapsed;  return elapsed;}/* Return the assessed granularity of the timer implementation, in   milliseconds.  This is used by code that tries to substitute a   better value for timers that have returned zero.  */doublewtimer_granularity (void){#ifdef TIMER_GETTIMEOFDAY  /* Granularity of gettimeofday varies wildly between architectures.     However, it appears that on modern machines it tends to be better     than 1ms.  Assume 100 usecs.  (Perhaps the configure process     could actually measure this?)  */  return 0.1;#endif#ifdef TIMER_TIME  return 1000;#endif#ifdef TIMER_WINDOWS  /* According to MSDN, GetSystemTime returns a broken-down time     structure the smallest member of which are milliseconds.  */  return 1;#endif}/* This should probably be at a better place, but it doesn't really   fit into html-parse.c.  *//* The function returns the pointer to the malloc-ed quoted version of   string s.  It will recognize and quote numeric and special graphic   entities, as per RFC1866:   `&' -> `&amp;'   `<' -> `&lt;'   `>' -> `&gt;'   `"' -> `&quot;'   SP  -> `&#32;'   No other entities are recognized or replaced.  */char *html_quote_string (const char *s){  const char *b = s;  char *p, *res;  int i;  /* Pass through the string, and count the new size.  */  for (i = 0; *s; s++, i++)    {      if (*s == '&')	i += 4;			/* `amp;' */      else if (*s == '<' || *s == '>')	i += 3;			/* `lt;' and `gt;' */      else if (*s == '\"')	i += 5;			/* `quot;' */      else if (*s == ' ')	i += 4;			/* #32; */    }  res = (char *)xmalloc (i + 1);  s = b;  for (p = res; *s; s++)    {      switch (*s)	{	case '&':	  *p++ = '&';	  *p++ = 'a';	  *p++ = 'm';	  *p++ = 'p';	  *p++ = ';';	  break;	case '<': case '>':	  *p++ = '&';	  *p++ = (*s == '<' ? 'l' : 'g');	  *p++ = 't';	  *p++ = ';';	  break;	case '\"':	  *p++ = '&';	  *p++ = 'q';	  *p++ = 'u';	  *p++ = 'o';	  *p++ = 't';	  *p++ = ';';	  break;	case ' ':	  *p++ = '&';	  *p++ = '#';	  *p++ = '3';	  *p++ = '2';	  *p++ = ';';	  break;	default:	  *p++ = *s;	}    }  *p = '\0';  return res;}/* Determine the width of the terminal we're running on.  If that's   not possible, return 0.  */intdetermine_screen_width (void){  /* If there's a way to get the terminal size using POSIX     tcgetattr(), somebody please tell me.  */#ifndef TIOCGWINSZ  return 0;#else  /* TIOCGWINSZ */  int fd;  struct winsize wsz;  if (opt.lfilename != NULL)    return 0;  fd = fileno (stderr);  if (ioctl (fd, TIOCGWINSZ, &wsz) < 0)    return 0;			/* most likely ENOTTY */  return wsz.ws_col;#endif /* TIOCGWINSZ */}/* Return a random number between 0 and MAX-1, inclusive.   If MAX is greater than the value of RAND_MAX+1 on the system, the   returned value will be in the range [0, RAND_MAX].  This may be   fixed in a future release.   The random number generator is seeded automatically the first time   it is called.   This uses rand() for portability.  It has been suggested that   random() offers better randomness, but this is not required for   Wget, so I chose to go for simplicity and use rand   unconditionally.   DO NOT use this for cryptographic purposes.  It is only meant to be   used in situations where quality of the random numbers returned   doesn't really matter.  */intrandom_number (int max){  static int seeded;  double bounded;  int rnd;  if (!seeded)    {      srand (time (NULL));      seeded = 1;    }  rnd = rand ();  /* On systems that don't define RAND_MAX, assume it to be 2**15 - 1,     and enforce that assumption by masking other bits.  */#ifndef RAND_MAX# define RAND_MAX 32767  rnd &= RAND_MAX;#endif  /* This is equivalent to rand() % max, but uses the high-order bits     for better randomness on architecture where rand() is implemented     using a simple congruential generator.  */  bounded = (double)max * rnd / (RAND_MAX + 1.0);  return (int)bounded;}/* Return a random uniformly distributed floating point number in the   [0, 1) range.  The precision of returned numbers is 9 digits.   Modify this to use erand48() where available!  */doublerandom_float (void){  /* We can't rely on any specific value of RAND_MAX, but I'm pretty     sure it's greater than 1000.  */  int rnd1 = random_number (1000);  int rnd2 = random_number (1000);  int rnd3 = random_number (1000);  return rnd1 / 1000.0 + rnd2 / 1000000.0 + rnd3 / 1000000000.0;}#if 0/* A debugging function for checking whether an MD5 library works. */#include "gen-md5.h"char *debug_test_md5 (char *buf){  unsigned char raw[16];  static char res[33];  unsigned char *p1;  char *p2;  int cnt;  ALLOCA_MD5_CONTEXT (ctx);  gen_md5_init (ctx);  gen_md5_update ((unsigned char *)buf, strlen (buf), ctx);  gen_md5_finish (ctx, raw);  p1 = raw;  p2 = res;  cnt = 16;  while (cnt--)    {      *p2++ = XNUM_TO_digit (*p1 >> 4);      *p2++ = XNUM_TO_digit (*p1 & 0xf);      ++p1;    }  *p2 = '\0';  return res;}#endif/* Implementation of run_with_timeout, a generic timeout-forcing   routine for systems with Unix-like signal handling.  */#ifdef USE_SIGNAL_TIMEOUT# ifdef HAVE_SIGSETJMP#  define SETJMP(env) sigsetjmp (env, 1)static sigjmp_buf run_with_timeout_env;static RETSIGTYPEabort_run_with_timeout (int sig){  assert (sig == SIGALRM);  siglongjmp (run_with_timeout_env, -1);}# else /* not HAVE_SIGSETJMP */#  define SETJMP(env) setjmp (env)static jmp_buf run_with_timeout_env;static RETSIGTYPEabort_run_with_timeout (int sig){  assert (sig == SIGALRM);  /* We don't have siglongjmp to preserve the set of blocked signals;     if we longjumped out of the handler at this point, SIGALRM would     remain blocked.  We must unblock it manually. */  int mask = siggetmask ();  mask &= ~sigmask (SIGALRM);  sigsetmask (mask);  /* Now it's safe to longjump. */  longjmp (run_with_timeout_env, -1);}# endif /* not HAVE_SIGSETJMP *//* Arrange for SIGALRM to be delivered in TIMEOUT seconds.  This uses   setitimer where available, alarm otherwise.   TIMEOUT should be non-zero.  If the timeout value is so small that   it would be rounded to zero, it is rounded to the least legal value   instead (1us for setitimer, 1s for alarm).  That ensures that   SIGALRM will be delivered in all cases.  */static voidalarm_set (double timeout){#ifdef ITIMER_REAL  /* Use the modern itimer interface. */  struct itimerval itv;  memset (&itv, 0, sizeof (itv));  itv.it_value.tv_sec = (long) timeout;  itv.it_value.tv_usec = 1000000L * (timeout - (long)timeout);  if (itv.it_value.tv_sec == 0 && itv.it_value.tv_usec == 0)    /* Ensure that we wait for at least the minimum interval.       Specifying zero would mean "wait forever".  */    itv.it_value.tv_usec = 1;  setitimer (ITIMER_REAL, &itv, NULL);#else  /* not ITIMER_REAL */  /* Use the old alarm() interface. */  int secs = (int) timeout;  if (secs == 0)    /* Round TIMEOUTs smaller than 1 to 1, not to zero.  This is       because alarm(0) means "never deliver the alarm", i.e. "wait       forever", which is not what someone who specifies a 0.5s       timeout would expect.  */    secs = 1;  alarm (secs);#endif /* not ITIMER_REAL */}/* Cancel the alarm set with alarm_set. */static voidalarm_cancel (void){#ifdef ITIMER_REAL  struct itimerval disable;  memset (&disable, 0, sizeof (disable));  setitimer (ITIMER_REAL, &disable, NULL);#else  /* not ITIMER_REAL */  alarm (0);#endif /* not ITIMER_REAL */}/* Call FUN(ARG), but don't allow it to run for more than TIMEOUT   seconds.  Returns non-zero if the function was interrupted with a   timeout, zero otherwise.   This works by setting up SIGALRM to be delivered in TIMEOUT seconds   using setitimer() or alarm().  The timeout is enforced by   longjumping out of the SIGALRM handler.  This has several   advantages compared to the traditional approach of relying on   signals causing system calls to exit with EINTR:     * The callback function is *forcibly* interrupted after the       timeout expires, (almost) regardless of what it was doing and       whether it was in a syscall.  For example, a calculation that       takes a long time is interrupted as reliably as an IO       operation.     * It works with both SYSV and BSD signals because it doesn't       depend on the default setting of SA_RESTART.     * It doesn't special handler setup beyond a simple call to       signal().  (It does use sigsetjmp/siglongjmp, but they're       optional.)   The only downside is that, if FUN allocates internal resources that   are normally freed prior to exit from the functions, they will be   lost in case of timeout.  */intrun_with_timeout (double timeout, void (*fun) (void *), void *arg){  int saved_errno;  if (timeout == 0)    {      fun (arg);      return 0;    }  signal (SIGALRM, abort_run_with_timeout);  if (SETJMP (run_with_timeout_env) != 0)    {      /* Longjumped out of FUN with a timeout. */      signal (SIGALRM, SIG_DFL);      return 1;    }  alarm_set (timeout);  fun (arg);  /* Preserve errno in case alarm() or signal() modifies it. */  saved_errno = errno;  alarm_cancel ();  signal (SIGALRM, SIG_DFL);  errno = saved_errno;  return 0;}#else  /* not USE_SIGNAL_TIMEOUT */#ifndef WINDOWS/* A stub version of run_with_timeout that just calls FUN(ARG).  Don't   define it under Windows, because Windows has its own version of   run_with_timeout that uses threads.  */intrun_with_timeout (double timeout, void (*fun) (void *), void *arg){  fun (arg);  return 0;}#endif /* not WINDOWS */#endif /* not USE_SIGNAL_TIMEOUT */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -