summaryrefslogtreecommitdiff
path: root/Functions/TCP/tcp_close
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2003-02-06 12:21:49 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2003-02-06 12:21:49 +0000
commit5c1f3b65a6f5abeae8459f41adb8fd2316971515 (patch)
tree21a82daa1abab96c967d731c7afe2a3a2bd07fff /Functions/TCP/tcp_close
parent809ab19dff75185a805b4cbb31a6b89f225167f4 (diff)
downloadzsh-5c1f3b65a6f5abeae8459f41adb8fd2316971515.tar.gz
zsh-5c1f3b65a6f5abeae8459f41adb8fd2316971515.zip
18202: New TCP function system plus small error message change in ztcp.
Diffstat (limited to 'Functions/TCP/tcp_close')
-rw-r--r--Functions/TCP/tcp_close134
1 files changed, 134 insertions, 0 deletions
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