GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: bin/csh/misc.c Lines: 0 125 0.0 %
Date: 2017-11-07 Branches: 0 99 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: misc.c,v 1.20 2017/06/20 16:44:06 anton Exp $	*/
2
/*	$NetBSD: misc.c,v 1.6 1995/03/21 09:03:09 cgd Exp $	*/
3
4
/*-
5
 * Copyright (c) 1980, 1991, 1993
6
 *	The Regents of the University of California.  All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 * 3. Neither the name of the University nor the names of its contributors
17
 *    may be used to endorse or promote products derived from this software
18
 *    without specific prior written permission.
19
 *
20
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
 * SUCH DAMAGE.
31
 */
32
33
#include <sys/types.h>
34
#include <stdlib.h>
35
#include <unistd.h>
36
#include <stdarg.h>
37
38
#include "csh.h"
39
#include "extern.h"
40
41
static int	fdcmp(int);
42
static int	renum(int, int);
43
44
int
45
any(char *s, int c)
46
{
47
    if (!s)
48
	return (0);		/* Check for nil pointer */
49
    while (*s)
50
	if (*s++ == c)
51
	    return (1);
52
    return (0);
53
}
54
55
char   *
56
strsave(char *s)
57
{
58
    char   *n;
59
    char *p;
60
61
    if (s == NULL)
62
	s = "";
63
    for (p = s; *p++;)
64
	continue;
65
    n = p = xreallocarray(NULL, (p - s), sizeof(char));
66
    while ((*p++ = *s++) != '\0')
67
	continue;
68
    return (n);
69
}
70
71
Char  **
72
blkend(Char **up)
73
{
74
75
    while (*up)
76
	up++;
77
    return (up);
78
}
79
80
81
void
82
blkpr(FILE *fp, Char **av)
83
{
84
85
    for (; *av; av++) {
86
	(void) fprintf(fp, "%s", vis_str(*av));
87
	if (av[1])
88
	    (void) fprintf(fp, " ");
89
    }
90
}
91
92
int
93
blklen(Char **av)
94
{
95
    int i = 0;
96
97
    while (*av++)
98
	i++;
99
    return (i);
100
}
101
102
Char  **
103
blkcpy(Char **oav, Char **bv)
104
{
105
    Char **av = oav;
106
107
    while ((*av++ = *bv++) != NULL)
108
	continue;
109
    return (oav);
110
}
111
112
Char  **
113
blkcat(Char **up, Char **vp)
114
{
115
116
    (void) blkcpy(blkend(up), vp);
117
    return (up);
118
}
119
120
void
121
blkfree(Char **av0)
122
{
123
    Char **av = av0;
124
125
    if (!av0)
126
	return;
127
    for (; *av; av++)
128
	free(* av);
129
    free(av0);
130
}
131
132
Char  **
133
saveblk(Char **v)
134
{
135
    Char **newv = xcalloc((size_t) (blklen(v) + 1), sizeof(Char **));
136
    Char  **onewv = newv;
137
138
    while (*v)
139
	*newv++ = Strsave(*v++);
140
    return (onewv);
141
}
142
143
Char  **
144
blkspl(Char **up, Char **vp)
145
{
146
    Char **wp = xcalloc((size_t) (blklen(up) + blklen(vp) + 1),
147
		      sizeof(Char **));
148
149
    (void) blkcpy(wp, up);
150
    return (blkcat(wp, vp));
151
}
152
153
Char
154
lastchr(Char *cp)
155
{
156
157
    if (!cp)
158
	return (0);
159
    if (!*cp)
160
	return (0);
161
    while (cp[1])
162
	cp++;
163
    return (*cp);
164
}
165
166
/*
167
 * Returns 0 if fd is in use, 1 if fd is greater than the largest used file
168
 * descriptor and -1 otherwise.
169
 */
170
static int
171
fdcmp(int fd)
172
{
173
    int fds[] = { SHIN, SHOUT, SHERR, OLDSTD, FSHTTY };
174
    int i, max;
175
176
    max = -1;
177
    for (i = 0; i < sizeof(fds)/sizeof(fds[0]); i++) {
178
	if (fd == fds[i])
179
	    return (0);
180
	if (fds[i] > max)
181
	    max = fds[i];
182
    }
183
    if (fd > max)
184
	return (1);
185
186
    return (-1);
187
}
188
189
/*
190
 * This routine is called after an error to close up
191
 * any units which may have been left open accidentally.
192
 */
193
void
194
closem(void)
195
{
196
    int f;
197
    int max = sysconf(_SC_OPEN_MAX);
198
199
    for (f = 0; f < max; f++)
200
	switch (fdcmp(f)) {
201
	case 0:
202
	    continue;
203
	case 1:
204
	    closefrom(f);
205
	    return;
206
	default:
207
	    close(f);
208
	}
209
}
210
211
void
212
donefds(void)
213
{
214
    (void) close(0);
215
    (void) close(1);
216
    (void) close(2);
217
218
    didfds = 0;
219
}
220
221
/*
222
 * Move descriptor i to j.
223
 * If j is -1 then we just want to get i to a safe place,
224
 * i.e. to a unit > 2.  This also happens in dcopy.
225
 */
226
int
227
dmove(int i, int j)
228
{
229
230
    if (i == j || i < 0)
231
	return (i);
232
    if (j >= 0) {
233
	(void) dup2(i, j);
234
	if (j != i)
235
	    (void) close(i);
236
	return (j);
237
    }
238
    j = dcopy(i, j);
239
    if (j != i)
240
	(void) close(i);
241
    return (j);
242
}
243
244
int
245
dcopy(int i, int j)
246
{
247
248
    if (i == j || i < 0 || (j < 0 && i > 2))
249
	return (i);
250
    if (j >= 0) {
251
	(void) dup2(i, j);
252
	return (j);
253
    }
254
    (void) close(j);
255
    return (renum(i, j));
256
}
257
258
static int
259
renum(int i, int j)
260
{
261
    int k = dup(i);
262
263
    if (k < 0)
264
	return (-1);
265
    if (j == -1 && k > 2)
266
	return (k);
267
    if (k != j) {
268
	j = renum(k, j);
269
	(void) close(k);
270
	return (j);
271
    }
272
    return (k);
273
}
274
275
/*
276
 * Left shift a command argument list, discarding
277
 * the first c arguments.  Used in "shift" commands
278
 * as well as by commands like "repeat".
279
 */
280
void
281
lshift(Char **v, int c)
282
{
283
    Char **u;
284
285
    for (u = v; *u && --c >= 0; u++)
286
	free(*u);
287
    (void) blkcpy(v, u);
288
}
289
290
int
291
number(Char *cp)
292
{
293
    if (!cp)
294
	return(0);
295
    if (*cp == '-') {
296
	cp++;
297
	if (!Isdigit(*cp))
298
	    return (0);
299
	cp++;
300
    }
301
    while (*cp && Isdigit(*cp))
302
	cp++;
303
    return (*cp == 0);
304
}
305
306
Char  **
307
copyblk(Char **v)
308
{
309
    Char  **nv = xcalloc((size_t) (blklen(v) + 1), sizeof(Char **));
310
311
    return (blkcpy(nv, v));
312
}
313
314
Char   *
315
strip(Char *cp)
316
{
317
    Char *dp = cp;
318
319
    if (!cp)
320
	return (cp);
321
    while ((*dp++ &= TRIM) != '\0')
322
	continue;
323
    return (cp);
324
}
325
326
Char   *
327
quote(Char *cp)
328
{
329
    Char *dp = cp;
330
331
    if (!cp)
332
	return (cp);
333
    while (*dp != '\0')
334
	*dp++ |= QUOTE;
335
    return (cp);
336
}
337
338
void
339
udvar(Char *name)
340
{
341
342
    setname(vis_str(name));
343
    stderror(ERR_NAME | ERR_UNDVAR);
344
}
345
346
int
347
prefix(Char *sub, Char *str)
348
{
349
350
    for (;;) {
351
	if (*sub == 0)
352
	    return (1);
353
	if (*str == 0)
354
	    return (0);
355
	if (*sub++ != *str++)
356
	    return (0);
357
    }
358
}