diff --git a/freebsd/sys/kern/uipc_syscalls.c b/freebsd/sys/kern/uipc_syscalls.c index 28f6c10c..451b4b18 100644 --- a/freebsd/sys/kern/uipc_syscalls.c +++ b/freebsd/sys/kern/uipc_syscalls.c @@ -152,6 +152,41 @@ getsock(struct filedesc *fdp, int fd, struct file **fpp, u_int *fflagp) *fpp = fp; return (error); } +#else /* __rtems__ */ +static int +rtems_bsd_getsock(int fd, struct file **fpp, u_int *fflagp) +{ + struct file *fp; + int error; + + if ((uint32_t) fd < rtems_libio_number_iops) { + fp = rtems_bsd_fd_to_fp(fd); + if ((fp->f_io.flags & LIBIO_FLAGS_OPEN) != LIBIO_FLAGS_OPEN) { + fp = NULL; + error = EBADF; + } else if (fp->f_io.pathinfo.handlers != &socketops) { + fp = NULL; + error = ENOTSOCK; + } else { + if (fflagp != NULL) { + *fflagp = rtems_bsd_libio_flags_to_fflag( + fp->f_io.flags); + } + + error = 0; + } + } else { + fp = NULL; + error = EBADF; + } + + *fpp = fp; + + return (error); +} + +#define getsock(fdp, fd, fpp, fflagp) rtems_bsd_getsock(fd, fpp, fflagp) +#endif /* __rtems__ */ /* * System call interface to the socket abstraction. @@ -159,7 +194,6 @@ getsock(struct filedesc *fdp, int fd, struct file **fpp, u_int *fflagp) #if defined(COMPAT_43) #define COMPAT_OLDSOCK #endif -#endif /* __rtems__ */ #ifndef __rtems__ int @@ -1292,10 +1326,16 @@ recvmsg(td, uap) free(iov, M_IOV); return (error); } +#endif /* __rtems__ */ /* ARGSUSED */ +#ifndef __rtems__ int shutdown(td, uap) +#else /* __rtems__ */ +static int +rtems_bsd_shutdown(td, uap) +#endif /* __rtems__ */ struct thread *td; struct shutdown_args /* { int s; @@ -1315,7 +1355,21 @@ shutdown(td, uap) } return (error); } +#ifdef __rtems__ +int +shutdown(int socket, int how) +{ + struct shutdown_args ua = { + .s = socket, + .how = how + }; + int error = rtems_bsd_shutdown(NULL, &ua); + return rtems_bsd_error_to_status_and_errno(error); +} +#endif /* __rtems__ */ + +#ifndef __rtems__ /* ARGSUSED */ int setsockopt(td, uap) diff --git a/freebsd/sys/sys/sysproto.h b/freebsd/sys/sys/sysproto.h index c9b813bb..d22197b2 100644 --- a/freebsd/sys/sys/sysproto.h +++ b/freebsd/sys/sys/sysproto.h @@ -448,10 +448,12 @@ struct sendto_args { char to_l_[PADL_(caddr_t)]; caddr_t to; char to_r_[PADR_(caddr_t)]; char tolen_l_[PADL_(int)]; int tolen; char tolen_r_[PADR_(int)]; }; +#endif /* __rtems__ */ struct shutdown_args { char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)]; char how_l_[PADL_(int)]; int how; char how_r_[PADR_(int)]; }; +#ifndef __rtems__ struct socketpair_args { char domain_l_[PADL_(int)]; int domain; char domain_r_[PADR_(int)]; char type_l_[PADL_(int)]; int type; char type_r_[PADR_(int)]; diff --git a/rtemsbsd/include/machine/rtems-bsd-syscall-api.h b/rtemsbsd/include/machine/rtems-bsd-syscall-api.h index 609ed842..acc75a03 100644 --- a/rtemsbsd/include/machine/rtems-bsd-syscall-api.h +++ b/rtemsbsd/include/machine/rtems-bsd-syscall-api.h @@ -55,6 +55,8 @@ int pselect(int, fd_set *__restrict, fd_set *__restrict, fd_set *__restrict, int select(int, fd_set *, fd_set *, fd_set *, struct timeval *); +int shutdown(int, int); + int socket(int, int, int); __END_DECLS diff --git a/rtemsbsd/rtems/rtems-bsd-syscalls.c b/rtemsbsd/rtems/rtems-bsd-syscalls.c index 1fce4773..d628b21a 100644 --- a/rtemsbsd/rtems/rtems-bsd-syscalls.c +++ b/rtemsbsd/rtems/rtems-bsd-syscalls.c @@ -538,31 +538,6 @@ accept (int s, struct sockaddr *name, int *namelen) return -1; } -/* - * Shutdown routine - */ - -int -shutdown (int s, int how) -{ - struct socket *so; - int error = 0; - - if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { - error = EBADF; - } - if( error == 0 ) - { - error = soshutdown(so, how); - } - if( error == 0 ) - { - return error; - } - errno = error; - return -1; -} - int kern_sendit(td, s, mp, flags, control, segflg) struct thread *td; diff --git a/testsuite/syscalls01/test_main.c b/testsuite/syscalls01/test_main.c index 58492af6..6f8dfcbf 100644 --- a/testsuite/syscalls01/test_main.c +++ b/testsuite/syscalls01/test_main.c @@ -370,7 +370,16 @@ no_mem_socket_fstat(int fd) } static void -test_socket_fstat(void) +no_mem_socket_shutdown(int fd) +{ + int rv; + + rv = shutdown(fd, SHUT_RDWR); + assert(rv == 0); +} + +static void +test_socket_fstat_and_shutdown(void) { mode_t canrecv = S_IRUSR | S_IRGRP | S_IROTH; mode_t cansend = S_IWUSR | S_IWGRP | S_IWOTH; @@ -379,7 +388,7 @@ test_socket_fstat(void) int sd; int rv; - puts("test socket fstat"); + puts("test socket fstat and shutdown"); rtems_resource_snapshot_take(&snapshot); @@ -392,9 +401,46 @@ test_socket_fstat(void) assert(rv == 0); assert(st.st_mode == (S_IFSOCK | canrecv | cansend)); + rv = shutdown(sd, SHUT_RD); + assert(rv == 0); + + rv = fstat(sd, &st); + assert(rv == 0); + assert(st.st_mode == (S_IFSOCK | cansend)); + + rv = shutdown(sd, SHUT_WR); + assert(rv == 0); + + rv = fstat(sd, &st); + assert(rv == 0); + assert(st.st_mode == S_IFSOCK); + + errno = 0; + rv = shutdown(sd, ~SHUT_RDWR); + assert(rv == -1); + assert(errno == EINVAL); + rv = close(sd); assert(rv == 0); + sd = socket(PF_INET, SOCK_DGRAM, 0); + assert(sd >= 0); + + do_no_mem_test(no_mem_socket_shutdown, sd); + + rv = close(sd); + assert(rv == 0); + + errno = 0; + rv = shutdown(sd, SHUT_RDWR); + assert(rv == -1); + assert(errno == EBADF); + + errno = 0; + rv = shutdown(0, SHUT_RDWR); + assert(rv == -1); + assert(errno == ENOTSOCK); + assert(rtems_resource_snapshot_check(&snapshot)); } @@ -405,7 +451,7 @@ test_main(void) test_sockets(); test_socket_unsupported_ops(); - test_socket_fstat(); + test_socket_fstat_and_shutdown(); puts("*** END OF " TEST_NAME " TEST ***"); exit(0);