+ struct sock_list *list;
+
+ /* Find socket in management structure. */
+ list = list_elem_from_socket(__fd);
+ if (list == NULL) {
+ errno = EBADF;
+ goto list_elem_err;
+ }
+
+ /* Check and update socket state. */
+ if (__how == STATE_SHUT_RDWR)
+ list->rw_state = STATE_SHUT_RDWR;
+ else if (__how == STATE_SHUT_WR) {
+ if (list->rw_state == STATE_SHUT_RD)
+ list->rw_state = STATE_SHUT_RDWR;
+ else if (list->rw_state == STATE_SHUT_WR) {
+ errno = ENOTCONN;
+ goto not_conn_err;
+ }
+ }
+ else if (__how == STATE_SHUT_RD) {
+ if (list->rw_state == STATE_SHUT_WR)
+ list->rw_state = STATE_SHUT_RDWR;
+ else if (list->rw_state == STATE_SHUT_RD) {
+ errno = ENOTCONN;
+ goto not_conn_err;
+ }
+ }
+
+ /* Remove socket from socket management structure. */
+ if (list->rw_state == STATE_SHUT_RDWR) {
+ list = list_unlink_socket(__fd);
+ if (list == NULL) {
+ errno = EBADF;
+ goto list_unlink_err;
+ }
+ }
+