Cross Reference: sh.misc.c
xref
: /
illumos-gate
/
usr
/
src
/
cmd
/
csh
/
sh.misc.c
Home
History
Annotate
Line#
Navigate
Download
Search
only in
./
sh.misc.c revision 65b0c20e9bbaf87a200ce20a4decf18585e61a25
355
N/A
/*
355
N/A
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
355
N/A
* Use is subject to license terms.
355
N/A
*/
355
N/A
355
N/A
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
355
N/A
/* All Rights Reserved */
355
N/A
355
N/A
/*
355
N/A
* Copyright (c) 1980 Regents of the University of California.
355
N/A
* All rights reserved. The Berkeley Software License Agreement
355
N/A
* specifies the terms and conditions for redistribution.
355
N/A
*/
355
N/A
355
N/A
#
pragma
ident
"%Z%%M% %I% %E% SMI"
355
N/A
355
N/A
#
include
"
sh.h
"
355
N/A
#
include
"
sh.tconst.h
"
873
N/A
#
include
<
fcntl.h
>
355
N/A
#
include
<
unistd.h
>
355
N/A
355
N/A
/*
355
N/A
* C Shell
355
N/A
*/
733
N/A
tchar
**
blkcat
(
tchar
**,
tchar
**);
355
N/A
tchar
**
blkend
(
tchar
**);
355
N/A
355
N/A
int
355
N/A
any
(
int
c,
tchar
*s)
355
N/A
{
355
N/A
355
N/A
while
(s && *s)
355
N/A
if
(*s++ == c)
355
N/A
return
(
1
);
355
N/A
return
(0);
355
N/A
}
355
N/A
355
N/A
int
355
N/A
onlyread
(
tchar
*
cp
)
355
N/A
{
355
N/A
extern
char
end
[];
355
N/A
844
N/A
return
((
char
*)
cp
<
end
);
355
N/A
}
355
N/A
355
N/A
tchar
*
355
N/A
savestr
(
tchar
*s)
355
N/A
{
723
N/A
tchar
*n;
355
N/A
tchar
*p;
355
N/A
355
N/A
if
(s == 0)
355
N/A
s =
S_
/* "" */
;
355
N/A
#
ifndef
m32
355
N/A
for
(p = s; *p++; )
355
N/A
;
355
N/A
n = p = (
tchar
*)
xalloc
((
unsigned
)(p - s)*
sizeof
(
tchar
));
355
N/A
while
(*p++ = *s++)
355
N/A
;
777
N/A
return
(n);
355
N/A
#
else
355
N/A
p = (
tchar
*)
xalloc
((
strlen_
(s) +
1
)*
sizeof
(
tchar
));
355
N/A
strcpy_
(p, s);
355
N/A
return
(p);
355
N/A
#
endif
1454
N/A
}
430
N/A
355
N/A
static
void
*
355
N/A
nomem
(
size_t
i)
355
N/A
{
355
N/A
#
ifdef
debug
355
N/A
static
tchar
*
av
[
2
] = {0, 0};
408
N/A
#
endif
355
N/A
355
N/A
child
++;
355
N/A
#
ifndef
debug
1454
N/A
error
(
"Out of memory"
);
1454
N/A
#
ifdef
lint
1454
N/A
i = i;
355
N/A
#
endif
355
N/A
#
else
355
N/A
showall
(
av
);
408
N/A
printf
(
"i=%d: Out of memory\n"
, i);
355
N/A
chdir
(
"/
usr
/
bill
/
cshcore
"
);
355
N/A
abort
();
355
N/A
#
endif
355
N/A
return
(0);
/* fool lint */
355
N/A
}
355
N/A
355
N/A
tchar
**
355
N/A
blkend
(
tchar
**
up
)
355
N/A
{
355
N/A
355
N/A
while
(*
up
)
355
N/A
up
++;
355
N/A
return
(
up
);
355
N/A
}
355
N/A
355
N/A
void
355
N/A
blkpr
(
tchar
**
av
)
355
N/A
{
355
N/A
355
N/A
for
(; *
av
;
av
++) {
355
N/A
printf
(
"%t"
, *
av
);
355
N/A
if
(
av
[
1
])
355
N/A
printf
(
" "
);
355
N/A
}
355
N/A
}
355
N/A
355
N/A
int
355
N/A
blklen
(
tchar
**
av
)
355
N/A
{
355
N/A
int
i = 0;
355
N/A
355
N/A
while
(*
av
++)
355
N/A
i++;
355
N/A
return
(i);
355
N/A
}
355
N/A
355
N/A
tchar
**
355
N/A
blkcpy
(
tchar
**
oav
,
tchar
**
bv
)
355
N/A
{
355
N/A
tchar
**
av
=
oav
;
355
N/A
355
N/A
while
(*
av
++ = *
bv
++)
355
N/A
continue
;
355
N/A
return
(
oav
);
355
N/A
}
355
N/A
355
N/A
tchar
**
355
N/A
blkcat
(
tchar
**
up
,
tchar
**
vp
)
355
N/A
{
355
N/A
355
N/A
(
void
)
blkcpy
(
blkend
(
up
),
vp
);
355
N/A
return
(
up
);
355
N/A
}
355
N/A
355
N/A
void
355
N/A
blkfree
(
tchar
**
av0
)
777
N/A
{
777
N/A
tchar
**
av
=
av0
;
777
N/A
777
N/A
for
(; *
av
;
av
++)
777
N/A
xfree
(*
av
);
777
N/A
xfree
(
av0
);
777
N/A
}
777
N/A
777
N/A
tchar
**
777
N/A
saveblk
(
tchar
**v)
777
N/A
{
777
N/A
tchar
**
newv
=
777
N/A
(
tchar
**)
xcalloc
((
unsigned
)(
blklen
(v) +
1
),
1065
N/A
sizeof
(
tchar
**));
777
N/A
tchar
**
onewv
=
newv
;
777
N/A
777
N/A
while
(*v)
777
N/A
*
newv
++ =
savestr
(*v++);
777
N/A
return
(
onewv
);
777
N/A
}
355
N/A
355
N/A
tchar
*
355
N/A
strspl
(
tchar
*
cp
,
tchar
*
dp
)
355
N/A
{
355
N/A
tchar
*
ep
;
355
N/A
tchar
*p, *q;
355
N/A
355
N/A
#
ifndef
m32
355
N/A
for
(p =
cp
; *p++; )
355
N/A
;
355
N/A
for
(q =
dp
; *q++; )
355
N/A
;
355
N/A
ep
= (
tchar
*)
xalloc
((
unsigned
)(((p -
cp
) +
355
N/A
(q -
dp
) -
1
))*
sizeof
(
tchar
));
355
N/A
for
(p =
ep
, q =
cp
; *p++ = *q++; )
355
N/A
;
355
N/A
for
(p--, q =
dp
; *p++ = *q++; )
355
N/A
;
1137
N/A
#
else
355
N/A
int
len1
=
strlen_
(
cp
);
355
N/A
int
len2
=
strlen_
(
dp
);
355
N/A
355
N/A
ep
= (
tchar
*)
xalloc
((
unsigned
)(
len1
+
len2
+
1
)*
sizeof
(
tchar
));
355
N/A
strcpy_
(
ep
,
cp
);
355
N/A
strcat_
(
ep
,
dp
);
355
N/A
#
endif
355
N/A
return
(
ep
);
355
N/A
}
355
N/A
355
N/A
tchar
**
355
N/A
blkspl
(
tchar
**
up
,
tchar
**
vp
)
355
N/A
{
355
N/A
tchar
**
wp
=
355
N/A
(
tchar
**)
xcalloc
((
unsigned
)(
blklen
(
up
) +
blklen
(
vp
) +
1
),
355
N/A
sizeof
(
tchar
**));
355
N/A
355
N/A
(
void
)
blkcpy
(
wp
,
up
);
355
N/A
return
(
blkcat
(
wp
,
vp
));
355
N/A
}
1137
N/A
355
N/A
int
355
N/A
lastchr
(
tchar
*
cp
)
355
N/A
{
355
N/A
355
N/A
if
(!*
cp
)
355
N/A
return
(0);
355
N/A
while
(
cp
[
1
])
355
N/A
cp
++;
355
N/A
return
(*
cp
);
355
N/A
}
355
N/A
355
N/A
void
355
N/A
donefds
(
void
)
355
N/A
{
355
N/A
(
void
)
close
(0);
355
N/A
(
void
)
close
(
1
);
355
N/A
(
void
)
close
(
2
);
355
N/A
355
N/A
/*
355
N/A
* To avoid NIS+ functions to get hold of 0/1/2,
1137
N/A
* use descriptor 0, and dup it to 1 and 2.
355
N/A
*/
355
N/A
open
(
"/
dev
/
null
"
, 0);
355
N/A
dup
(0);
dup
(0);
355
N/A
didfds
= 0;
355
N/A
}
355
N/A
355
N/A
/*
355
N/A
* Move descriptor i to j.
355
N/A
* If j is -1 then we just want to get i to a safe place,
355
N/A
* i.e. to a unit > 2. This also happens in dcopy.
355
N/A
*/
355
N/A
int
355
N/A
dmove
(
int
i,
int
j)
355
N/A
{
355
N/A
int
fd
;
355
N/A
355
N/A
if
(i == j || i < 0)
355
N/A
return
(i);
355
N/A
if
(j >= 0) {
355
N/A
fd
=
dup2
(i, j);
355
N/A
if
(
fd
!= -
1
)
355
N/A
setfd
(
fd
);
355
N/A
}
else
355
N/A
j =
dcopy
(i, j);
355
N/A
if
(j != i) {
355
N/A
(
void
)
close
(i);
355
N/A
unsetfd
(i);
355
N/A
}
355
N/A
return
(j);
355
N/A
}
355
N/A
355
N/A
int
355
N/A
dcopy
(
int
i,
int
j)
355
N/A
{
355
N/A
355
N/A
int
fd
;
355
N/A
355
N/A
if
(i == j || i < 0 || j < 0 && i >
2
)
355
N/A
return
(i);
355
N/A
if
(j >= 0) {
355
N/A
fd
=
dup2
(i, j);
355
N/A
if
(
fd
!= -
1
)
355
N/A
setfd
(
fd
);
355
N/A
return
(j);
355
N/A
}
355
N/A
(
void
)
close
(j);
355
N/A
unsetfd
(j);
355
N/A
return
(
renum
(i, j));
355
N/A
}
355
N/A
355
N/A
int
355
N/A
renum
(
int
i,
int
j)
509
N/A
{
509
N/A
int
k =
dup
(i);
355
N/A
509
N/A
if
(k < 0)
355
N/A
return
(-
1
);
355
N/A
if
(j == -
1
&& k >
2
) {
355
N/A
setfd
(k);
355
N/A
return
(k);
355
N/A
}
355
N/A
if
(k != j) {
355
N/A
j =
renum
(k, j);
355
N/A
(
void
)
close
(k);
/* no need ofr unsetfd() */
355
N/A
return
(j);
355
N/A
}
355
N/A
return
(k);
355
N/A
}
355
N/A
355
N/A
#
ifndef
copy
355
N/A
void
355
N/A
copy
(
tchar
*
to
,
tchar
*
from
,
int
size
)
355
N/A
{
355
N/A
355
N/A
if
(
size
)
355
N/A
do
355
N/A
*
to
++ = *
from
++;
509
N/A
while
(--
size
!= 0);
509
N/A
}
355
N/A
#
endif
509
N/A
355
N/A
/*
355
N/A
* Left shift a command argument list, discarding
355
N/A
* the first c arguments. Used in "shift" commands
355
N/A
* as well as by commands like "repeat".
355
N/A
*/
355
N/A
void
355
N/A
lshift
(
tchar
**v,
int
c)
355
N/A
{
355
N/A
tchar
**u = v;
355
N/A
355
N/A
while
(*u && --c >= 0)
355
N/A
xfree
((
char
*)*u++);
355
N/A
(
void
)
blkcpy
(v, u);
355
N/A
}
355
N/A
355
N/A
int
355
N/A
number
(
tchar
*
cp
)
355
N/A
{
355
N/A
355
N/A
if
(*
cp
==
'-'
) {
355
N/A
cp
++;
355
N/A
if
(!
digit
(*
cp
++))
355
N/A
return
(0);
355
N/A
}
355
N/A
while
(*
cp
&&
digit
(*
cp
))
355
N/A
cp
++;
355
N/A
return
(*
cp
== 0);
355
N/A
}
355
N/A
355
N/A
tchar
**
509
N/A
copyblk
(
tchar
**v)
509
N/A
{
355
N/A
tchar
**
nv
=
509
N/A
(
tchar
**)
xcalloc
((
unsigned
)(
blklen
(v) +
1
),
355
N/A
sizeof
(
tchar
**));
355
N/A
355
N/A
return
(
blkcpy
(
nv
, v));
355
N/A
}
355
N/A
355
N/A
tchar
*
355
N/A
strend
(
tchar
*
cp
)
355
N/A
{
355
N/A
355
N/A
while
(*
cp
)
355
N/A
cp
++;
355
N/A
return
(
cp
);
355
N/A
}
355
N/A
355
N/A
tchar
*
355
N/A
strip
(
tchar
*
cp
)
355
N/A
{
355
N/A
tchar
*
dp
=
cp
;
355
N/A
355
N/A
while
(*
dp
++ &=
TRIM
)
355
N/A
continue
;
509
N/A
return
(
cp
);
509
N/A
}
355
N/A
509
N/A
void
355
N/A
udvar
(
tchar
*
name
)
355
N/A
{
355
N/A
355
N/A
setname
(
name
);
355
N/A
bferr
(
"Undefined variable"
);
355
N/A
}
355
N/A
355
N/A
int
355
N/A
prefix
(
tchar
*
sub
,
tchar
*
str
)
355
N/A
{
355
N/A
355
N/A
for
(;;) {
355
N/A
if
(*
sub
== 0)
355
N/A
return
(
1
);
355
N/A
if
(*
str
== 0)
355
N/A
return
(0);
355
N/A
if
(*
sub
++ != *
str
++)
355
N/A
return
(0);
355
N/A
}
355
N/A
}
355
N/A
355
N/A
/*
355
N/A
* blk*_ routines
355
N/A
*/
355
N/A
355
N/A
char
**
355
N/A
blkend_
(
char
**
up
)
355
N/A
{
355
N/A
355
N/A
while
(*
up
)
509
N/A
up
++;
509
N/A
return
(
up
);
355
N/A
}
509
N/A
355
N/A
int
355
N/A
blklen_
(
char
**
av
)
355
N/A
{
355
N/A
int
i = 0;
355
N/A
355
N/A
while
(*
av
++)
355
N/A
i++;
355
N/A
return
(i);
355
N/A
}
355
N/A
355
N/A
char
**
355
N/A
blkcpy_
(
char
**
oav
,
char
**
bv
)
355
N/A
{
355
N/A
char
**
av
=
oav
;
355
N/A
355
N/A
while
(*
av
++ = *
bv
++)
355
N/A
continue
;
355
N/A
return
(
oav
);
355
N/A
}
355
N/A
355
N/A
char
**
509
N/A
blkcat_
(
char
**
up
,
char
**
vp
)
509
N/A
{
355
N/A
509
N/A
(
void
)
blkcpy_
(
blkend_
(
up
),
vp
);
355
N/A
return
(
up
);
355
N/A
}
355
N/A
355
N/A
char
**
355
N/A
blkspl_
(
char
**
up
,
char
**
vp
)
355
N/A
{
355
N/A
char
**
wp
=
355
N/A
(
char
**)
xcalloc
((
unsigned
)(
blklen_
(
up
) +
blklen_
(
vp
) +
1
),
355
N/A
sizeof
(
char
**));
355
N/A
355
N/A
(
void
)
blkcpy_
(
wp
,
up
);
355
N/A
return
(
blkcat_
(
wp
,
vp
));
355
N/A
}
355
N/A
355
N/A
/*
355
N/A
* If stack address was passed to free(), we have no good way to see if
355
N/A
* they are really in the stack. Therefore, we record the bottom of heap,
355
N/A
* and filter out the address not within heap's top(end) and bottom
355
N/A
* (xalloc_bottom).
355
N/A
*/
355
N/A
extern
char
end
[];
355
N/A
static
char
*
xalloc_bottom
;
355
N/A
355
N/A
void
*
355
N/A
xalloc
(
size_t
size
)
355
N/A
{
355
N/A
char
*
rptr
, *
bp
;
355
N/A
355
N/A
if
((
rptr
=
malloc
(
size
)) ==
NULL
)
355
N/A
return
(
nomem
(
size
));
509
N/A
bp
=
rptr
+
size
;
509
N/A
if
(
bp
>
xalloc_bottom
)
355
N/A
xalloc_bottom
=
bp
;
509
N/A
return
(
rptr
);
355
N/A
}
355
N/A
355
N/A
void
*
355
N/A
xrealloc
(
void
*
ptr
,
size_t
size
)
355
N/A
{
355
N/A
char
*
rptr
=
ptr
, *
bp
;
355
N/A
355
N/A
if
(
ptr
==
NULL
)
355
N/A
return
(
xalloc
(
size
));
355
N/A
if
(
rptr
<
end
) {
355
N/A
/* data area, but not in heap area. don't touch it */
355
N/A
oob
:
355
N/A
if
(
size
== 0)
355
N/A
return
(
NULL
);
355
N/A
rptr
=
xalloc
(
size
);
355
N/A
/* copy max size */
355
N/A
(
void
)
memcpy
(
rptr
,
ptr
,
size
);
355
N/A
return
(
rptr
);
355
N/A
}
355
N/A
if
(
rptr
<
xalloc_bottom
) {
355
N/A
/* address in the heap */
509
N/A
inb
:
509
N/A
if
(
size
== 0) {
355
N/A
free
(
ptr
);
509
N/A
return
(
NULL
);
355
N/A
}
355
N/A
if
((
rptr
=
realloc
(
ptr
,
size
)) ==
NULL
)
355
N/A
return
(
nomem
(
size
));
355
N/A
bp
=
rptr
+
size
;
355
N/A
if
(
bp
>
xalloc_bottom
)
355
N/A
xalloc_bottom
=
bp
;
355
N/A
return
(
rptr
);
355
N/A
}
355
N/A
#
if
defined
(
__sparc
)
355
N/A
if
(
rptr
> (
char
*)&
rptr
) {
355
N/A
/* in the stack frame */
355
N/A
goto
oob
;
355
N/A
}
355
N/A
#
endif
355
N/A
/*
355
N/A
* can be a memory block returned indirectly from
355
N/A
* library functions. update bottom, and check it again.
355
N/A
*/
355
N/A
xalloc_bottom
=
sbrk
(0);
355
N/A
if
(
rptr
<=
xalloc_bottom
)
355
N/A
goto
inb
;
355
N/A
else
355
N/A
goto
oob
;
355
N/A
/*NOTREACHED*/
355
N/A
}
355
N/A
355
N/A
void
355
N/A
xfree
(
void
*
ptr
)
355
N/A
{
355
N/A
char
*
rptr
=
ptr
;
509
N/A
509
N/A
if
(
rptr
<
end
) {
355
N/A
return
;
509
N/A
}
355
N/A
if
(
rptr
<
xalloc_bottom
) {
355
N/A
free
(
ptr
);
355
N/A
return
;
355
N/A
}
355
N/A
#
if
defined
(
__sparc
)
355
N/A
if
(
rptr
> (
char
*)&
rptr
) {
355
N/A
/* in the stack frame */
355
N/A
return
;
355
N/A
}
355
N/A
#
endif
355
N/A
xalloc_bottom
=
sbrk
(0);
355
N/A
if
(
rptr
<=
xalloc_bottom
) {
355
N/A
free
(
ptr
);
355
N/A
}
355
N/A
}
355
N/A
355
N/A
void
*
355
N/A
xcalloc
(
size_t
i,
size_t
j)
355
N/A
{
355
N/A
char
*
cp
;
355
N/A
509
N/A
i *= j;
509
N/A
cp
=
xalloc
(i);
355
N/A
(
void
)
memset
(
cp
,
'\0'
, i);
509
N/A
return
(
cp
);
355
N/A
}
355
N/A