components/zsh/patches/watch.patch
changeset 7589 7eccd056eff6
equal deleted inserted replaced
7586:3db1c2ef2aa9 7589:7eccd056eff6
       
     1 This patch was submitted upstream by Jens Elkner, who reported it on #pkg5;
       
     2 it was accepted after the 5.3.1 release.
       
     3 
       
     4 --- zsh-5.0.7/Src/watch.c.orig	Thu Jul 31 20:41:49 2014
       
     5 +++ zsh-5.0.7/Src/watch.c	Wed Jan 11 16:37:49 2017
       
     6 @@ -87,6 +87,9 @@
       
     7  
       
     8  #if !defined(WATCH_STRUCT_UTMP) && defined(HAVE_STRUCT_UTMPX) && defined(REAL_UTMPX_FILE)
       
     9  # define WATCH_STRUCT_UTMP struct utmpx
       
    10 +# define setutent setutxent
       
    11 +# define getutent getutxent
       
    12 +# define endutent endutxent 
       
    13  /*
       
    14   * In utmpx, the ut_name field is replaced by ut_user.
       
    15   * Howver, on some systems ut_name may already be defined this
       
    16 @@ -141,9 +144,9 @@
       
    17  #  define WATCH_WTMP_FILE "/dev/null"
       
    18  # endif
       
    19  
       
    20 -static int wtabsz;
       
    21 -static WATCH_STRUCT_UTMP *wtab;
       
    22 -static time_t lastutmpcheck;
       
    23 +static int wtabsz = 0;
       
    24 +static WATCH_STRUCT_UTMP *wtab = NULL;
       
    25 +static time_t lastutmpcheck = 0;
       
    26  
       
    27  /* get the time of login/logout for WATCH */
       
    28  
       
    29 @@ -449,34 +452,44 @@
       
    30  /* initialize the user List */
       
    31  
       
    32  /**/
       
    33 -static void
       
    34 -readwtab(void)
       
    35 +static int
       
    36 +readwtab(WATCH_STRUCT_UTMP **head, int initial_sz)
       
    37  {
       
    38 -    WATCH_STRUCT_UTMP *uptr;
       
    39 -    int wtabmax = 32;
       
    40 -    FILE *in;
       
    41 +    WATCH_STRUCT_UTMP *uptr, *tmp;
       
    42 +    int wtabmax = initial_sz < 2 ? 32 : initial_sz;
       
    43 +    int sz = 0;
       
    44  
       
    45 -    wtabsz = 0;
       
    46 -    if (!(in = fopen(WATCH_UTMP_FILE, "r")))
       
    47 -	return;
       
    48 -    uptr = wtab = (WATCH_STRUCT_UTMP *)zalloc(wtabmax * sizeof(WATCH_STRUCT_UTMP));
       
    49 -    while (fread(uptr, sizeof(WATCH_STRUCT_UTMP), 1, in))
       
    50 +
       
    51 +    uptr = *head = (WATCH_STRUCT_UTMP *)zalloc(wtabmax * sizeof(WATCH_STRUCT_UTMP));
       
    52 +	setutent();
       
    53 +    while ((tmp = getutent()) != NULL)
       
    54  # ifdef USER_PROCESS
       
    55 -	if   (uptr->ut_type == USER_PROCESS)
       
    56 +	if   (tmp->ut_type == USER_PROCESS)
       
    57  # else /* !USER_PROCESS */
       
    58 -	if   (uptr->ut_name[0])
       
    59 +	if   (tmp->ut_name[0])
       
    60  # endif /* !USER_PROCESS */
       
    61  	{
       
    62 +		memcpy(uptr, tmp, sizeof (WATCH_STRUCT_UTMP));
       
    63  	    uptr++;
       
    64 -	    if (++wtabsz == wtabmax)
       
    65 -		uptr = (wtab = (WATCH_STRUCT_UTMP *)realloc((void *) wtab, (wtabmax *= 2) *
       
    66 -						      sizeof(WATCH_STRUCT_UTMP))) + wtabsz;
       
    67 +	    if (++sz == wtabmax) {
       
    68 +			uptr = (WATCH_STRUCT_UTMP *)
       
    69 +				realloc(*head, (wtabmax *= 2) * sizeof(WATCH_STRUCT_UTMP));
       
    70 +			if (uptr == NULL) {
       
    71 +				/* memory pressure - so stop consuming and use, what we have
       
    72 +				 * Other option is to exit() here, as zmalloc does on error */
       
    73 +				sz--;
       
    74 +				break;
       
    75 +			}
       
    76 +			*head = uptr;
       
    77 +			uptr += sz;
       
    78 +		}
       
    79  	}
       
    80 -    fclose(in);
       
    81 +    endutent();
       
    82  
       
    83 -    if (wtabsz)
       
    84 -	qsort((void *) wtab, wtabsz, sizeof(WATCH_STRUCT_UTMP),
       
    85 +    if (sz)
       
    86 +	qsort((void *) *head, sz, sizeof(WATCH_STRUCT_UTMP),
       
    87  	           (int (*) _((const void *, const void *)))ucmp);
       
    88 +	return sz;
       
    89  }
       
    90  
       
    91  /* Check for login/logout events; executed before *
       
    92 @@ -486,55 +499,28 @@
       
    93  void
       
    94  dowatch(void)
       
    95  {
       
    96 -    FILE *in;
       
    97      WATCH_STRUCT_UTMP *utab, *uptr, *wptr;
       
    98      struct stat st;
       
    99      char **s;
       
   100      char *fmt;
       
   101 -    int utabsz = 0, utabmax = wtabsz + 4;
       
   102 -    int uct, wct;
       
   103 +    int utabsz, uct, wct;
       
   104  
       
   105      s = watch;
       
   106  
       
   107      holdintr();
       
   108 -    if (!wtab) {
       
   109 -	readwtab();
       
   110 -	noholdintr();
       
   111 -	return;
       
   112 -    }
       
   113 +    if (!wtab)
       
   114 +	wtabsz = readwtab(&wtab, 32);
       
   115      if ((stat(WATCH_UTMP_FILE, &st) == -1) || (st.st_mtime <= lastutmpcheck)) {
       
   116  	noholdintr();
       
   117  	return;
       
   118      }
       
   119      lastutmpcheck = st.st_mtime;
       
   120 -    uptr = utab = (WATCH_STRUCT_UTMP *) zalloc(utabmax * sizeof(WATCH_STRUCT_UTMP));
       
   121 -
       
   122 -    if (!(in = fopen(WATCH_UTMP_FILE, "r"))) {
       
   123 -	free(utab);
       
   124 -	noholdintr();
       
   125 -	return;
       
   126 -    }
       
   127 -    while (fread(uptr, sizeof *uptr, 1, in))
       
   128 -# ifdef USER_PROCESS
       
   129 -	if (uptr->ut_type == USER_PROCESS)
       
   130 -# else /* !USER_PROCESS */
       
   131 -	if (uptr->ut_name[0])
       
   132 -# endif /* !USER_PROCESS */
       
   133 -	{
       
   134 -	    uptr++;
       
   135 -	    if (++utabsz == utabmax)
       
   136 -		uptr = (utab = (WATCH_STRUCT_UTMP *)realloc((void *) utab, (utabmax *= 2) *
       
   137 -						      sizeof(WATCH_STRUCT_UTMP))) + utabsz;
       
   138 -	}
       
   139 -    fclose(in);
       
   140 +    utabsz = readwtab(&utab, wtabsz + 4);
       
   141      noholdintr();
       
   142      if (errflag) {
       
   143  	free(utab);
       
   144  	return;
       
   145      }
       
   146 -    if (utabsz)
       
   147 -	qsort((void *) utab, utabsz, sizeof(WATCH_STRUCT_UTMP),
       
   148 -	           (int (*) _((const void *, const void *)))ucmp);
       
   149  
       
   150      wct = wtabsz;
       
   151      uct = utabsz;