Denys Vlasenko | aa3576a | 2016-08-22 19:54:12 +0200 | [diff] [blame] | 1 | # Builds a " 3>&- 4>&-" string. |
| 2 | # Note: one of these fds is a directory opened to /proc/self/fd |
| 3 | # for globbing. It is unwanted, but I don't know how to filter it out. |
| 4 | find_fds() { |
| 5 | fds="" |
| 6 | for f in /proc/self/fd/*; do |
| 7 | test "$f" = "/proc/self/fd/0" && continue |
| 8 | test "$f" = "/proc/self/fd/1" && continue |
| 9 | test "$f" = "/proc/self/fd/2" && continue |
| 10 | fds="$fds ${f##*/}>&-" |
| 11 | done |
| 12 | } |
| 13 | |
| 14 | find_fds |
| 15 | fds1="$fds" |
| 16 | |
| 17 | # One of the fds is open to the script body |
| 18 | # Close it while executing something. |
| 19 | eval "find_fds $fds" |
| 20 | |
| 21 | # Shell should not lose that fd. Did it? |
| 22 | find_fds |
Denys Vlasenko | 035486c | 2017-07-31 04:09:19 +0200 | [diff] [blame] | 23 | test x"$fds1" = x"$fds" \ |
| 24 | && { echo "Ok: script fd is not closed"; exit 0; } |
| 25 | |
| 26 | # One legit way to handle it is to move script fd. For example, if we see that fd 10 moved to fd 11: |
| 27 | test x"$fds1" = x" 10>&- 3>&-" && \ |
| 28 | test x"$fds" = x" 11>&- 3>&-" \ |
| 29 | && { echo "Ok: script fd is not closed"; exit 0; } |
Denys Vlasenko | 41ef41b | 2018-07-24 16:54:41 +0200 | [diff] [blame] | 30 | # or we see that fd 3 moved to fd 10: |
| 31 | test x"$fds1" = x" 3>&- 4>&-" && \ |
| 32 | test x"$fds" = x" 10>&- 3>&-" \ |
| 33 | && { echo "Ok: script fd is not closed"; exit 0; } |
Denys Vlasenko | aa3576a | 2016-08-22 19:54:12 +0200 | [diff] [blame] | 34 | |
| 35 | echo "Bug: script fd is closed" |
| 36 | echo "fds1:$fds1" |
| 37 | echo "fds2:$fds" |
| 38 | exit 1 |