| /* Copyright (c) 2016 Google Inc. |
| * Barret Rhoden <brho@cs.berkeley.edu> |
| * See LICENSE for details. |
| * |
| * shutdown(). */ |
| |
| #include <sys/socket.h> |
| #include <sys/types.h> |
| #include <unistd.h> |
| #include <errno.h> |
| #include <sys/stat.h> |
| #include <fcntl.h> |
| |
| #include <sys/plan9_helpers.h> |
| |
| /* Shuts down all or part of the connection open on socket FD. Returns 0 on |
| * success, -1 for errors. */ |
| int shutdown(int fd, int how) |
| { |
| int ret; |
| static const char rd_msg[] = "shutdown rd"; |
| static const char wr_msg[] = "shutdown wr"; |
| static const char rdwr_msg[] = "shutdown rdwr"; |
| char *msg; |
| size_t msg_sz; |
| Rock *r; |
| |
| switch (how) { |
| case SHUT_RD: |
| msg = rd_msg; |
| msg_sz = sizeof(rd_msg); |
| break; |
| case SHUT_WR: |
| msg = wr_msg; |
| msg_sz = sizeof(wr_msg); |
| break; |
| case SHUT_RDWR: |
| msg = rdwr_msg; |
| msg_sz = sizeof(rdwr_msg); |
| break; |
| default: |
| errno = EINVAL; |
| werrstr("shutdown has bad 'how' %d", how); |
| return -1; |
| } |
| r = _sock_findrock(fd, 0); |
| if (!r) { |
| errno = EBADF; |
| werrstr("Rock lookup failed"); |
| return -1; |
| } |
| ret = write(r->ctl_fd, msg, msg_sz); |
| if (ret != msg_sz) |
| return -1; |
| return 0; |
| } |