From 5c1f3b65a6f5abeae8459f41adb8fd2316971515 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 6 Feb 2003 12:21:49 +0000 Subject: 18202: New TCP function system plus small error message change in ztcp. --- Functions/TCP/tcp_close | 134 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 Functions/TCP/tcp_close (limited to 'Functions/TCP/tcp_close') diff --git a/Functions/TCP/tcp_close b/Functions/TCP/tcp_close new file mode 100644 index 000000000..61508f4c6 --- /dev/null +++ b/Functions/TCP/tcp_close @@ -0,0 +1,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 consistenty 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 -- cgit 1.4.1