|  | /* 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; | 
|  | } |