Use shutdown() from FreeBSD

This commit is contained in:
Sebastian Huber 2013-10-11 14:48:13 +02:00
parent bada2f77d0
commit 6ffb9b9e27
5 changed files with 108 additions and 29 deletions

View File

@ -152,6 +152,41 @@ getsock(struct filedesc *fdp, int fd, struct file **fpp, u_int *fflagp)
*fpp = fp; *fpp = fp;
return (error); 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. * 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) #if defined(COMPAT_43)
#define COMPAT_OLDSOCK #define COMPAT_OLDSOCK
#endif #endif
#endif /* __rtems__ */
#ifndef __rtems__ #ifndef __rtems__
int int
@ -1292,10 +1326,16 @@ recvmsg(td, uap)
free(iov, M_IOV); free(iov, M_IOV);
return (error); return (error);
} }
#endif /* __rtems__ */
/* ARGSUSED */ /* ARGSUSED */
#ifndef __rtems__
int int
shutdown(td, uap) shutdown(td, uap)
#else /* __rtems__ */
static int
rtems_bsd_shutdown(td, uap)
#endif /* __rtems__ */
struct thread *td; struct thread *td;
struct shutdown_args /* { struct shutdown_args /* {
int s; int s;
@ -1315,7 +1355,21 @@ shutdown(td, uap)
} }
return (error); 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 */ /* ARGSUSED */
int int
setsockopt(td, uap) setsockopt(td, uap)

View File

@ -448,10 +448,12 @@ struct sendto_args {
char to_l_[PADL_(caddr_t)]; caddr_t to; char to_r_[PADR_(caddr_t)]; 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)]; char tolen_l_[PADL_(int)]; int tolen; char tolen_r_[PADR_(int)];
}; };
#endif /* __rtems__ */
struct shutdown_args { struct shutdown_args {
char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)]; char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)];
char how_l_[PADL_(int)]; int how; char how_r_[PADR_(int)]; char how_l_[PADL_(int)]; int how; char how_r_[PADR_(int)];
}; };
#ifndef __rtems__
struct socketpair_args { struct socketpair_args {
char domain_l_[PADL_(int)]; int domain; char domain_r_[PADR_(int)]; char domain_l_[PADL_(int)]; int domain; char domain_r_[PADR_(int)];
char type_l_[PADL_(int)]; int type; char type_r_[PADR_(int)]; char type_l_[PADL_(int)]; int type; char type_r_[PADR_(int)];

View File

@ -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 select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
int shutdown(int, int);
int socket(int, int, int); int socket(int, int, int);
__END_DECLS __END_DECLS

View File

@ -538,31 +538,6 @@ accept (int s, struct sockaddr *name, int *namelen)
return -1; 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 int
kern_sendit(td, s, mp, flags, control, segflg) kern_sendit(td, s, mp, flags, control, segflg)
struct thread *td; struct thread *td;

View File

@ -370,7 +370,16 @@ no_mem_socket_fstat(int fd)
} }
static void 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 canrecv = S_IRUSR | S_IRGRP | S_IROTH;
mode_t cansend = S_IWUSR | S_IWGRP | S_IWOTH; mode_t cansend = S_IWUSR | S_IWGRP | S_IWOTH;
@ -379,7 +388,7 @@ test_socket_fstat(void)
int sd; int sd;
int rv; int rv;
puts("test socket fstat"); puts("test socket fstat and shutdown");
rtems_resource_snapshot_take(&snapshot); rtems_resource_snapshot_take(&snapshot);
@ -392,9 +401,46 @@ test_socket_fstat(void)
assert(rv == 0); assert(rv == 0);
assert(st.st_mode == (S_IFSOCK | canrecv | cansend)); 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); rv = close(sd);
assert(rv == 0); 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)); assert(rtems_resource_snapshot_check(&snapshot));
} }
@ -405,7 +451,7 @@ test_main(void)
test_sockets(); test_sockets();
test_socket_unsupported_ops(); test_socket_unsupported_ops();
test_socket_fstat(); test_socket_fstat_and_shutdown();
puts("*** END OF " TEST_NAME " TEST ***"); puts("*** END OF " TEST_NAME " TEST ***");
exit(0); exit(0);