aboutsummaryrefslogtreecommitdiffhomepage
path: root/share/functions/trap.fish
blob: 094d37f1b43fad311f51a3599fe5746278ed6db7 (plain)
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
135
136
137
138
139
140
141
142
143

function __trap_translate_signal
	set upper (echo $argv[1]|tr a-z A-Z)
	string replace -r '^SIG' '' -- $upper
end

function __trap_switch

	switch $argv[1]
		case EXIT
			echo --on-process-exit %self

		case '*'
			echo --on-signal $argv[1]
	end

end

function trap -d 'Perform an action when the shell receives a signal'

	set -l mode
	set -l cmd
	set -l sig

	set -l options
	set -l longopt
	set -l shortopt lph
	if not getopt -T > /dev/null
		# GNU getopt
		set longopt print,help,list-signals
		set options -o $shortopt -l $longopt --
		# Verify options
		if not getopt -n type $options $argv >/dev/null
			return 1
		end
	else
		# Old getopt, used on OS X
		set options $shortopt
		# Verify options
		if not getopt $options $argv >/dev/null
			return 1
		end
	end

	# Do the real getopt invocation
	set -l tmp (getopt $options $argv)

	# Break tmp up into an array
	set -l opt
	eval set opt $tmp

	while count $opt >/dev/null
		switch $opt[1]
			case -h --help
				__fish_print_help trap
				return 0

			case -p --print
				set mode print

			case -l --list-signals
				set mode list

			case --
				 set -e opt[1]
				 break

		end
		set -e opt[1]
	end

	if not count $mode >/dev/null

		switch (count $opt)

			case 0
				set mode print

			case 1
				set mode clear

			case '*'
				if test opt[1] = -
					set -e opt[1]
					set mode clear
				else
					set mode set
				end
		end
	end

	switch $mode
		case clear
			for i in $opt
				set sig (__trap_translate_signal $i)
				if test $sig
					functions -e __trap_handler_$sig
				end
			end

		case set
			set -l cmd $opt[1]
			set -e opt[1]

			for i in $opt

				set -l sig (__trap_translate_signal $i)
				set sw (__trap_switch $sig)

				if test $sig
					eval "function __trap_handler_$sig $sw; $cmd; end"
				else
					return 1
				end
			end

		case print
			set -l names

			if count $opt >/dev/null
				set names $opt
			else
				set names (functions -na| string match "__trap_handler_*" | string replace '__trap_handler_' '')
			end

			for i in $names

				set sig (__trap_translate_signal $i)

				if test sig
					functions __trap_handler_$i
				else
					return 1
				end

			end

		case list
			kill -l

	end

end