blob: 9c876786c0e67c57ee2bcf59a8a1497478fa48f5 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
# Usage:
# tcp_close [-q] [ -a | session ... ]
# -a means all sessions.
# -n means don't close a fake session's fd.
# -q means quiet.
#
# Accepts the -s and -l arguments for consistency with other functions,
# but there is no particular gain in using them
emulate -L zsh
setopt extendedglob cbases
local all quiet opt alias noclose
local -a sessnames
while getopts "aql:ns:" opt; do
case $opt in
(a) all=1
;;
(q) quiet=1
;;
(l) sessnames+=(${(s.,.)OPTARG})
;;
(n) noclose=1
;;
(s) sessnames+=($OPTARG)
;;
(*) return 1
;;
esac
done
(( OPTIND > 1 )) && shift $(( OPTIND - 1))
if [[ -n $all ]]; then
if (( $# )); then
print "Usage: $0 [ -q ] [ -a | [ session ... ] ]" >&2
return 1
fi
sessnames=(${(k)tcp_by_name})
if (( ! ${#sessnames} )); then
[[ -z $quiet ]] && print "No TCP sessions open." >&2
return 1
fi
fi
sessnames+=($*)
if (( ! ${#sessnames} )); then
sessnames+=($TCP_SESS)
fi
if (( ! ${#sessnames} )); then
[[ -z $quiet ]] && print "No current TCP session." >&2
return 1
fi
local tcp_sess fd
integer stat curstat
# Check to see if the fd is opened for a TCP session, or was opened
# to a pre-existing fd. We could remember this from tcp_open.
local -A ztcp_fds
local line match mbegin mend
if zmodload -e zsh/net/tcp; then
ztcp | while read line; do
if [[ $line = (#b)*fd\ ([0-9]##) ]]; then
ztcp_fds[$match[1]]=1
fi
done
fi
for tcp_sess in $sessnames; do
curstat=0
fd=${tcp_by_name[$tcp_sess]}
if [[ -z $fd ]]; then
print "No TCP session $tcp_sess!" >&2
stat=1
continue
fi
# We need the base name if this is an alias.
tcp_sess=${tcp_by_fd[$fd]}
if [[ -z $tcp_sess ]]; then
if [[ -z $quiet ]]; then
print "Aaargh! Session for fd $fd has disappeared!" >&2
fi
stat=1
continue
fi
if [[ ${+tcp_aliases} -ne 0 && -n ${tcp_aliases[$fd]} ]]; then
for alias in ${=tcp_aliases[$fd]}; do
if (( ${+functions[tcp_on_unalias]} )); then
tcp_on_unalias $alias $fd
fi
unset "tcp_by_name[$alias]"
done
unset "tcp_aliases[$fd]"
fi
# Don't return just because the zle handler couldn't be uninstalled...
if [[ -o zle ]]; then
zle -F $fd || print "[Ignoring...]" >&2
fi
if [[ -n $ztcp_fds[$fd] ]]; then
# It's a ztcp session.
if ! ztcp -c $fd; then
stat=1
curstat=1
fi
elif [[ -z $noclose ]]; then
# It's not, just close it normally.
# Careful: syntax for closing fd's is quite strict.
if [[ ${#fd} -gt 1 ]]; then
[[ -z $quiet ]] && print "Can't close fd $fd; will leave open." >&2
else
eval "exec $fd>&-"
fi
fi
unset "tcp_by_name[$tcp_sess]"
unset "tcp_by_fd[$fd]"
if [[ -z $quiet && $curstat -eq 0 ]]; then
print "Session $tcp_sess successfully closed."
fi
[[ $tcp_sess = $TCP_SESS ]] && unset TCP_SESS
if (( ${+functions[tcp_on_close]} )); then
tcp_on_close $tcp_sess $fd
fi
done
return $stat
|