|
| 1 | +Test that a socket reports and closes its own file descriptor. |
| 2 | + |
| 3 | +The descriptor is stored in the data pointer of the socket resource and |
| 4 | +was read back through an `int *`. On 64-bit big-endian systems that |
| 5 | +yields the upper half of the pointer: `fileno()` returned 0 for every |
| 6 | +socket and `close()` closed descriptor 0 instead of the socket. |
| 7 | + |
| 8 | +The failure only shows on a 64-bit big-endian build, on other systems |
| 9 | +this test passes regardless of the fix. |
| 10 | + |
| 11 | +-- Testcase -- |
| 12 | +{% |
| 13 | + import * as socket from 'socket'; |
| 14 | + import * as fs from 'fs'; |
| 15 | + |
| 16 | + let s1 = socket.create(socket.AF_INET, socket.SOCK_DGRAM, 0); |
| 17 | + let s2 = socket.create(socket.AF_INET, socket.SOCK_DGRAM, 0); |
| 18 | + let fd1 = s1.fileno(), fd2 = s2.fileno(); |
| 19 | + |
| 20 | + printf("fds_valid=%s fds_distinct=%s\n", |
| 21 | + (fd1 > 2 && fd2 > 2) ? "yes" : "no", |
| 22 | + (fd1 != fd2) ? "yes" : "no"); |
| 23 | + |
| 24 | + printf("close=%s\n", s1.close()); |
| 25 | + printf("fd_released=%s\n", fs.stat(`/proc/self/fd/${fd1}`) == null ? "yes" : "no"); |
| 26 | + printf("stdin_open=%s\n", fs.stat("/proc/self/fd/0") != null ? "yes" : "no"); |
| 27 | + |
| 28 | + printf("fileno_after_close=%J error=%s\n", s1.fileno(), socket.error()); |
| 29 | + printf("close_after_close=%J error=%s\n", s1.close(), socket.error()); |
| 30 | + |
| 31 | + printf("other_socket_intact=%s\n", s2.fileno() == fd2 ? "yes" : "no"); |
| 32 | +%} |
| 33 | +-- End -- |
| 34 | + |
| 35 | +-- Expect stdout -- |
| 36 | +fds_valid=yes fds_distinct=yes |
| 37 | +close=true |
| 38 | +fd_released=yes |
| 39 | +stdin_open=yes |
| 40 | +fileno_after_close=null error=Invalid socket context: Bad file descriptor |
| 41 | +close_after_close=null error=Invalid socket context: Bad file descriptor |
| 42 | +other_socket_intact=yes |
| 43 | +-- End -- |
0 commit comments