diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 1c2b16fda13aa8caf87869f29d2db8eb29ac8438..a0f682cdd03e06e8802efdf320c6da9d436d31ad 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -599,7 +599,7 @@ sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event __user *event) switch (op) { case EPOLL_CTL_ADD: if (!epi) { - epds.events |= POLLERR | POLLHUP; + epds.events |= POLLERR | POLLHUP | POLLRDHUP; error = ep_insert(ep, &epds, tfile, fd); } else @@ -613,7 +613,7 @@ sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event __user *event) break; case EPOLL_CTL_MOD: if (epi) { - epds.events |= POLLERR | POLLHUP; + epds.events |= POLLERR | POLLHUP | POLLRDHUP; error = ep_modify(ep, epi, &epds); } else error = -ENOENT; diff --git a/include/asm-alpha/poll.h b/include/asm-alpha/poll.h index 34f333b762a04b57e244ff0b2f9b2fe34df510c6..95707182b3ed3c7a7c7609d4307bc137c0572a48 100644 --- a/include/asm-alpha/poll.h +++ b/include/asm-alpha/poll.h @@ -13,6 +13,8 @@ #define POLLWRBAND (1 << 9) #define POLLMSG (1 << 10) #define POLLREMOVE (1 << 11) +#define POLLRDHUP (1 << 12) + struct pollfd { int fd; diff --git a/include/asm-arm/poll.h b/include/asm-arm/poll.h index 2744ca831f5d126130df470e06a4805c062c9832..5030b2b232a3c7433be4c96676da242e77155c90 100644 --- a/include/asm-arm/poll.h +++ b/include/asm-arm/poll.h @@ -16,6 +16,7 @@ #define POLLWRBAND 0x0200 #define POLLMSG 0x0400 #define POLLREMOVE 0x1000 +#define POLLRDHUP 0x2000 struct pollfd { int fd; diff --git a/include/asm-arm26/poll.h b/include/asm-arm26/poll.h index fdfdab064a658a0d31465d29fa0a0636f8162abf..9ccb7f4190cafaae318e3e4eb2d784c8d13cb7a1 100644 --- a/include/asm-arm26/poll.h +++ b/include/asm-arm26/poll.h @@ -15,6 +15,7 @@ #define POLLWRNORM 0x0100 #define POLLWRBAND 0x0200 #define POLLMSG 0x0400 +#define POLLRDHUP 0x2000 struct pollfd { int fd; diff --git a/include/asm-cris/poll.h b/include/asm-cris/poll.h index 1c0efc3e4be70e5fc067a4ee9d01cc0426471567..1b25d4cf498c4aab72193c3246c94f312d00b1eb 100644 --- a/include/asm-cris/poll.h +++ b/include/asm-cris/poll.h @@ -15,6 +15,7 @@ #define POLLWRBAND 512 #define POLLMSG 1024 #define POLLREMOVE 4096 +#define POLLRDHUP 8192 struct pollfd { int fd; diff --git a/include/asm-frv/poll.h b/include/asm-frv/poll.h index 8cbcd60e334fb293224789b2e8f753bc0730122e..c8fe8801d075819c3e069e720e7806604d6ea8b5 100644 --- a/include/asm-frv/poll.h +++ b/include/asm-frv/poll.h @@ -12,6 +12,7 @@ #define POLLRDBAND 128 #define POLLWRBAND 256 #define POLLMSG 0x0400 +#define POLLRDHUP 0x2000 struct pollfd { int fd; diff --git a/include/asm-h8300/poll.h b/include/asm-h8300/poll.h index bf49ab8ad6da173f8c9d7313bf845e76a73aa922..fc52103b276ae0011a2dfcb755c5b201ae6ea161 100644 --- a/include/asm-h8300/poll.h +++ b/include/asm-h8300/poll.h @@ -12,6 +12,7 @@ #define POLLRDBAND 128 #define POLLWRBAND 256 #define POLLMSG 0x0400 +#define POLLRDHUP 0x2000 struct pollfd { int fd; diff --git a/include/asm-i386/poll.h b/include/asm-i386/poll.h index aecc80a15d3687f6fdc6274e4a17bc08eb5f4210..2cd4929abd40426b3ad88ef33762c859227b497b 100644 --- a/include/asm-i386/poll.h +++ b/include/asm-i386/poll.h @@ -16,6 +16,7 @@ #define POLLWRBAND 0x0200 #define POLLMSG 0x0400 #define POLLREMOVE 0x1000 +#define POLLRDHUP 0x2000 struct pollfd { int fd; diff --git a/include/asm-ia64/poll.h b/include/asm-ia64/poll.h index 160258a0528d2692292cd8d3941bf595e6fcfa31..bcaf9f1402427ddaef313f0d82306d58e6a7410e 100644 --- a/include/asm-ia64/poll.h +++ b/include/asm-ia64/poll.h @@ -21,6 +21,7 @@ #define POLLWRBAND 0x0200 #define POLLMSG 0x0400 #define POLLREMOVE 0x1000 +#define POLLRDHUP 0x2000 struct pollfd { int fd; diff --git a/include/asm-m32r/poll.h b/include/asm-m32r/poll.h index 43b7acf732d57ae1310819edb022133fb6b1fb1f..9e0e700e727c94e2e160b7b1e717181ce142a190 100644 --- a/include/asm-m32r/poll.h +++ b/include/asm-m32r/poll.h @@ -21,6 +21,7 @@ #define POLLWRBAND 0x0200 #define POLLMSG 0x0400 #define POLLREMOVE 0x1000 +#define POLLRDHUP 0x2000 struct pollfd { int fd; diff --git a/include/asm-m68k/poll.h b/include/asm-m68k/poll.h index c4b69c4a87e1a337d6c66b564f264d57ccd05fa2..0fb8843647f8a4a4bbafc74d99bda97e622db475 100644 --- a/include/asm-m68k/poll.h +++ b/include/asm-m68k/poll.h @@ -13,6 +13,7 @@ #define POLLWRBAND 256 #define POLLMSG 0x0400 #define POLLREMOVE 0x1000 +#define POLLRDHUP 0x2000 struct pollfd { int fd; diff --git a/include/asm-mips/poll.h b/include/asm-mips/poll.h index a000f1f789e342b296b305879caa4f6b3921da6f..70881f8c5c5092e58e00df92ec21956abeb1586e 100644 --- a/include/asm-mips/poll.h +++ b/include/asm-mips/poll.h @@ -17,6 +17,7 @@ /* These seem to be more or less nonstandard ... */ #define POLLMSG 0x0400 #define POLLREMOVE 0x1000 +#define POLLRDHUP 0x2000 struct pollfd { int fd; diff --git a/include/asm-parisc/poll.h b/include/asm-parisc/poll.h index 1c1da86934cffc08326f181478f437c50b502faa..20e4d03c74cb835d7d873015456aa26a0b67a6c6 100644 --- a/include/asm-parisc/poll.h +++ b/include/asm-parisc/poll.h @@ -16,6 +16,7 @@ #define POLLWRBAND 0x0200 #define POLLMSG 0x0400 #define POLLREMOVE 0x1000 +#define POLLRDHUP 0x2000 struct pollfd { int fd; diff --git a/include/asm-powerpc/poll.h b/include/asm-powerpc/poll.h index edd2054da86b49d3b83503b7aed2962ab3f416af..9c7d1263103353745dfb10cece78ac1e3719d976 100644 --- a/include/asm-powerpc/poll.h +++ b/include/asm-powerpc/poll.h @@ -13,6 +13,7 @@ #define POLLWRBAND 0x0200 #define POLLMSG 0x0400 #define POLLREMOVE 0x1000 +#define POLLRDHUP 0x2000 struct pollfd { int fd; diff --git a/include/asm-s390/poll.h b/include/asm-s390/poll.h index e90a5ca4206193716cf4490270ce9a4e2ae55f82..6f7f65ac7d27da520ca756590ba1495076dd34a2 100644 --- a/include/asm-s390/poll.h +++ b/include/asm-s390/poll.h @@ -24,6 +24,7 @@ #define POLLWRBAND 0x0200 #define POLLMSG 0x0400 #define POLLREMOVE 0x1000 +#define POLLRDHUP 0x2000 struct pollfd { int fd; diff --git a/include/asm-sh/poll.h b/include/asm-sh/poll.h index 52f95b9188dcfe1105901a28a718424f500127f5..dbca9b32f4a6c4ff0f9f5f250e218e3eed4a0846 100644 --- a/include/asm-sh/poll.h +++ b/include/asm-sh/poll.h @@ -16,6 +16,7 @@ #define POLLWRBAND 0x0200 #define POLLMSG 0x0400 #define POLLREMOVE 0x1000 +#define POLLRDHUP 0x2000 struct pollfd { int fd; diff --git a/include/asm-sh64/poll.h b/include/asm-sh64/poll.h index a420d14eb704a548ffb5591fa9521a5d5b657adb..3a6cbad08d281a9bc2a94a3b7fdc0397eca31502 100644 --- a/include/asm-sh64/poll.h +++ b/include/asm-sh64/poll.h @@ -26,6 +26,7 @@ #define POLLWRNORM 0x0100 #define POLLWRBAND 0x0200 #define POLLMSG 0x0400 +#define POLLRDHUP 0x2000 struct pollfd { int fd; diff --git a/include/asm-sparc/poll.h b/include/asm-sparc/poll.h index 3ddcc6481f0973d3441c7a18605e843fbfcf4a8f..26f13fb35497f77926404a6503e7b091c1f5a425 100644 --- a/include/asm-sparc/poll.h +++ b/include/asm-sparc/poll.h @@ -13,6 +13,7 @@ #define POLLWRBAND 256 #define POLLMSG 512 #define POLLREMOVE 1024 +#define POLLRDHUP 2048 struct pollfd { int fd; diff --git a/include/asm-sparc64/poll.h b/include/asm-sparc64/poll.h index 31b611aa74685d61ac7f244d6429298cc8bac450..ab6b0d1bb4adb6c0d2b1599fc951e5a5b7399896 100644 --- a/include/asm-sparc64/poll.h +++ b/include/asm-sparc64/poll.h @@ -13,6 +13,7 @@ #define POLLWRBAND 256 #define POLLMSG 512 #define POLLREMOVE 1024 +#define POLLRDHUP 2048 struct pollfd { int fd; diff --git a/include/asm-v850/poll.h b/include/asm-v850/poll.h index 0369562c7e1588db6fe077a723096cba9eb60f2e..c10176c2c28ff7b7b15a05e3e600399948a59966 100644 --- a/include/asm-v850/poll.h +++ b/include/asm-v850/poll.h @@ -13,6 +13,7 @@ #define POLLWRBAND 0x0100 #define POLLMSG 0x0400 #define POLLREMOVE 0x1000 +#define POLLRDHUP 0x2000 struct pollfd { int fd; diff --git a/include/asm-x86_64/poll.h b/include/asm-x86_64/poll.h index c43cbba31913dbaf0809938cacb272526c4ab8fe..c0475a9d8bb860d0e330a866b6d6576b9a99d114 100644 --- a/include/asm-x86_64/poll.h +++ b/include/asm-x86_64/poll.h @@ -16,6 +16,7 @@ #define POLLWRBAND 0x0200 #define POLLMSG 0x0400 #define POLLREMOVE 0x1000 +#define POLLRDHUP 0x2000 struct pollfd { int fd; diff --git a/include/asm-xtensa/poll.h b/include/asm-xtensa/poll.h index dffe447534e063d58d480937515691f415ca8927..6fd94773e866051bef79e0cff38fe5d6e0b04e6b 100644 --- a/include/asm-xtensa/poll.h +++ b/include/asm-xtensa/poll.h @@ -27,6 +27,7 @@ #define POLLMSG 0x0400 #define POLLREMOVE 0x0800 +#define POLLRDHUP 0x2000 struct pollfd { int fd; diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index fb031fe9be9ed140bce6fdfe6092f3ab6df8ff87..469eda0f0dfd713f0d998b5c830faaff2e9c71fd 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -238,6 +238,9 @@ unsigned int bt_sock_poll(struct file * file, struct socket *sock, poll_table *w if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) mask |= POLLERR; + if (sk->sk_shutdown & RCV_SHUTDOWN) + mask |= POLLRDHUP; + if (sk->sk_shutdown == SHUTDOWN_MASK) mask |= POLLHUP; diff --git a/net/core/datagram.c b/net/core/datagram.c index b8ce6bf81188943a1ac91f3b80b361d03ce3c955..aecddcc304012d48769e9f98b91157aa946cd60d 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -500,6 +500,8 @@ unsigned int datagram_poll(struct file *file, struct socket *sock, /* exceptional events? */ if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) mask |= POLLERR; + if (sk->sk_shutdown & RCV_SHUTDOWN) + mask |= POLLRDHUP; if (sk->sk_shutdown == SHUTDOWN_MASK) mask |= POLLHUP; diff --git a/net/dccp/proto.c b/net/dccp/proto.c index d4b293e16283e4e2e5ddc3b5b25fb84c2aecc05b..1ff7328b0e170bf137819ab03a76b3a4acdd9572 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c @@ -350,7 +350,7 @@ unsigned int dccp_poll(struct file *file, struct socket *sock, if (sk->sk_shutdown == SHUTDOWN_MASK || sk->sk_state == DCCP_CLOSED) mask |= POLLHUP; if (sk->sk_shutdown & RCV_SHUTDOWN) - mask |= POLLIN | POLLRDNORM; + mask |= POLLIN | POLLRDNORM | POLLRDHUP; /* Connected? */ if ((1 << sk->sk_state) & ~(DCCPF_REQUESTING | DCCPF_RESPOND)) { diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 4b0272c92d665a3b8b1caef5e4ed7d2526e06bb4..19ea5c0b094bcb47ba180907a290a7d75d5a0f71 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -365,7 +365,7 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) if (sk->sk_shutdown == SHUTDOWN_MASK || sk->sk_state == TCP_CLOSE) mask |= POLLHUP; if (sk->sk_shutdown & RCV_SHUTDOWN) - mask |= POLLIN | POLLRDNORM; + mask |= POLLIN | POLLRDNORM | POLLRDHUP; /* Connected? */ if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV)) { diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 0ea947eb681320561d3e3d61ac91001aa1043926..b6e4b89539b3178216037c53350f5591dde8a1b6 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -4894,6 +4894,8 @@ unsigned int sctp_poll(struct file *file, struct socket *sock, poll_table *wait) /* Is there any exceptional events? */ if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) mask |= POLLERR; + if (sk->sk_shutdown & RCV_SHUTDOWN) + mask |= POLLRDHUP; if (sk->sk_shutdown == SHUTDOWN_MASK) mask |= POLLHUP; diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 2b4cc2eea5b38bd6a686b94cb0136f8b7a18adbf..d901465ce0135093276d55adabbb7691591097c3 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1878,6 +1878,8 @@ static unsigned int unix_poll(struct file * file, struct socket *sock, poll_tabl mask |= POLLERR; if (sk->sk_shutdown == SHUTDOWN_MASK) mask |= POLLHUP; + if (sk->sk_shutdown & RCV_SHUTDOWN) + mask |= POLLRDHUP; /* readable? */ if (!skb_queue_empty(&sk->sk_receive_queue) ||