7641
|
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;
|