2 * sh.misc.c: Miscelaneous functions
5 * Copyright (c) 1980, 1991 The Regents of the University of California.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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
34 static int renum (int, int);
35 static Char
**blkend (Char
**);
36 static Char
**blkcat (Char
**, Char
**);
37 static int xdup2 (int, int);
44 any(const char *s
, Char c
)
47 return (0); /* Check for nil pointer */
55 setzero(void *p
, size_t size
)
62 strnsave(const char *s
, size_t len
)
74 strsave(const char *s
)
98 blkpr(Char
*const *av
)
102 xprintf("%" TCSH_S
, *av
);
109 blkexpand(Char
*const *av
)
111 struct Strbuf buf
= Strbuf_INIT
;
114 Strbuf_append(&buf
, *av
);
116 Strbuf_append1(&buf
, ' ');
118 return Strbuf_finish(&buf
);
132 blkcpy(Char
**oav
, Char
**bv
)
136 while ((*av
++ = *bv
++) != NULL
)
142 blkcat(Char
**up
, Char
**vp
)
145 (void) blkcpy(blkend(up
), vp
);
162 blk_cleanup(void *ptr
)
168 blk_indirect_cleanup(void *xptr
)
180 Char
**newv
, **onewv
;
185 onewv
= newv
= xcalloc(blklen(v
) + 1, sizeof(Char
**));
188 *newv
++ = Strsave(*v
++);
194 strstr(const char *s
, const char *t
)
203 while (*ss
++ == *tt
++);
204 } while (*s
++ != '\0');
207 #endif /* !HAVE_STRSTR */
210 strspl(const char *cp
, const char *dp
)
221 ep
= xmalloc((cl
+ dl
+ 1) * sizeof(char));
223 memcpy(ep
+ cl
, dp
, dl
+ 1);
228 blkspl(Char
**up
, Char
**vp
)
230 Char
**wp
= xcalloc(blklen(up
) + blklen(vp
) + 1, sizeof(Char
**));
232 (void) blkcpy(wp
, up
);
233 return (blkcat(wp
, vp
));
250 * This routine is called after an error to close up
251 * any units which may have been left open accidentally.
264 #endif /* NLS_CATALOGS */
265 #endif /* NLS_BUGS */
267 /* suggested by Justin Bur; thanks to Karl Kleinpaste */
271 for (f
= 0; f
< num_files
; f
++)
272 if (f
!= SHIN
&& f
!= SHOUT
&& f
!= SHDIAG
&& f
!= OLDSTD
&&
276 #endif /* MALLOC_TRACE */
278 /* NSS modules (e.g. Linux nss_ldap) might keep sockets open.
279 * If we close such a socket, both the NSS module and tcsh think
280 * they "own" the descriptor.
282 * Not closing sockets does not make the cleanup use of closem()
283 * less reliable because tcsh never creates sockets.
285 && fstat(f
, &st
) == 0 && !S_ISSOCK(st
.st_mode
)
292 (void) xopen(_PATH_DEVNULL
, O_RDONLY
|O_LARGEFILE
);
298 #endif /* NLS_CATALOGS */
299 #endif /* NLS_BUGS */
302 #ifndef CLOSE_ON_EXEC
304 * Close files before executing a file.
305 * We could be MUCH more intelligent, since (on a version 7 system)
306 * we need only close files here during a source, the other
307 * shell fd's being in units 16-19 which are closed automatically!
321 isoutatty
= isatty(SHOUT
);
322 isdiagatty
= isatty(SHDIAG
);
324 for (f
= 3; f
< num_files
; f
++)
328 #endif /* CLOSE_ON_EXEC */
340 int fd
= xopen(_PATH_DEVNULL
, O_RDONLY
|O_LARGEFILE
);
349 * Move descriptor i to j.
350 * If j is -1 then we just want to get i to a safe place,
351 * i.e. to a unit > FSAFE. This also happens in dcopy.
377 if (i
== j
|| i
< 0 || (j
< 0 && i
> FSAFE
))
387 return (renum(i
, j
));
397 if (j
== -1 && k
> FSAFE
)
408 * Left shift a command argument list, discarding
409 * the first c arguments. Used in "shift" commands
410 * as well as by commands like "repeat".
413 lshift(Char
**v
, int c
)
417 for (u
= v
; *u
&& --c
>= 0; u
++)
433 while (*cp
&& Isdigit(*cp
))
441 Char
**nv
= xcalloc(blklen(v
) + 1, sizeof(Char
**));
443 return (blkcpy(nv
, v
));
447 strend(const char *cp
)
450 return ((char *)(intptr_t)cp
);
453 return ((char *)(intptr_t)cp
);
463 while (*dp
!= '\0') {
464 #if INVALID_BYTE != 0
465 if ((*dp
& INVALID_BYTE
) != INVALID_BYTE
) /* *dp < INVALID_BYTE */
480 while (*dp
!= '\0') {
482 if ((*dp
& 0xffffff80) == 0) /* *dp < 0x80 */
483 #elif defined SHORT_STRINGS
484 if ((*dp
& 0xff80) == 0) /* *dp < 0x80 */
486 if ((*dp
& 0x80) == 0) /* *dp < 0x80 */
495 quote_meta(struct Strbuf
*buf
, const Char
*s
)
499 if (cmap(*s
, _META
| _DOL
| _QF
| _QB
| _ESC
| _GLOB
))
500 Strbuf_append1(buf
, '\\');
501 Strbuf_append1(buf
, *s
++);
503 Strbuf_terminate(buf
);
510 setname(short2str(name
));
511 stderror(ERR_NAME
| ERR_UNDVAR
);
515 prefix(const Char
*sub
, const Char
*str
)
523 if ((*sub
++ & TRIM
) != (*str
++ & TRIM
))
529 areadlink(const char *path
)
536 * Prevent infinite recursion. Someone should tell me how to expand
540 static const char *vars
[] = {
546 for (i
= 0; i
< sizeof(vars
) / sizeof(vars
[0]); i
++) {
547 if (strcmp(vars
[i
], path
) == 0) {
554 size
= MAXPATHLEN
+ 1;
556 while ((size_t)(res
= readlink(path
, buf
, size
)) == size
) {
558 buf
= xrealloc(buf
, size
);
569 return xrealloc(buf
, res
+ 1);
571 #endif /*!WINNT_NATIVE*/
578 while (close(fildes
) == -1 && errno
== EINTR
)
579 if (handle_pending_signals())
586 while (closedir(dirp
) == -1 && errno
== EINTR
)
587 if (handle_pending_signals())
592 xcreat(const char *path
, mode_t mode
)
596 while ((res
= creat(path
, mode
)) == -1 && errno
== EINTR
)
597 if (handle_pending_signals())
604 xdup2(int fildes
, int fildes2
)
608 while ((res
= dup2(fildes
, fildes2
)) == -1 && errno
== EINTR
)
609 if (handle_pending_signals())
616 xgetgrgid(gid_t xgid
)
621 while ((res
= getgrgid(xgid
)) == NULL
&& errno
== EINTR
) {
622 if (handle_pending_signals())
630 xgetpwnam(const char *name
)
635 while ((res
= getpwnam(name
)) == NULL
&& errno
== EINTR
) {
636 if (handle_pending_signals())
644 xgetpwuid(uid_t xuid
)
649 while ((res
= getpwuid(xuid
)) == NULL
&& errno
== EINTR
) {
650 if (handle_pending_signals())
658 xopen(const char *path
, int oflag
, ...)
662 if ((oflag
& O_CREAT
) == 0) {
663 while ((res
= open(path
, oflag
)) == -1 && errno
== EINTR
)
664 if (handle_pending_signals())
671 /* "int" should actually be "mode_t after default argument
672 promotions". "int" is the best guess we have, "mode_t" used to be
673 "unsigned short", which we obviously can't use. */
674 mode
= va_arg(ap
, int);
676 while ((res
= open(path
, oflag
, mode
)) == -1 && errno
== EINTR
)
677 if (handle_pending_signals())
684 xread(int fildes
, void *buf
, size_t nbyte
)
688 /* This is where we will be blocked most of the time, so handle signals
689 that didn't interrupt any system call. */
691 if (handle_pending_signals())
693 while ((res
= read(fildes
, buf
, nbyte
)) == -1 && errno
== EINTR
);
699 xtcsetattr(int fildes
, int optional_actions
, const struct termios
*termios_p
)
703 while ((res
= tcsetattr(fildes
, optional_actions
, termios_p
)) == -1 &&
705 if (handle_pending_signals())
712 xwrite(int fildes
, const void *buf
, size_t nbyte
)
716 /* This is where we will be blocked most of the time, so handle signals
717 that didn't interrupt any system call. */
719 if (handle_pending_signals())
721 while ((res
= write(fildes
, buf
, nbyte
)) == -1 && errno
== EINTR
);