Signed-off-by: Zeng Linggang <zenglg...@cn.fujitsu.com> Signed-off-by: Alexey Kodanev <alexey.koda...@oracle.com> Signed-off-by: Cyril Hrubis <chru...@suse.cz> --- include/safe_macros.h | 1 + include/safe_net.h | 59 +++++++++++++++++++++++++ lib/safe_net.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 177 insertions(+) create mode 100644 include/safe_net.h create mode 100644 lib/safe_net.c
diff --git a/include/safe_macros.h b/include/safe_macros.h index cd86931..e938f17 100644 --- a/include/safe_macros.h +++ b/include/safe_macros.h @@ -28,6 +28,7 @@ #include <dirent.h> #include "safe_stdio.h" +#include "safe_net.h" char* safe_basename(const char *file, const int lineno, void (*cleanup_fn)(void), char *path); diff --git a/include/safe_net.h b/include/safe_net.h new file mode 100644 index 0000000..f9ce040 --- /dev/null +++ b/include/safe_net.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2015 Fujitsu Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#ifndef __SAFE_NET_H__ +#define __SAFE_NET_H__ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#define GET_ADDR(sock_addr) \ + (inet_ntoa(((struct sockaddr_in *)sock_addr)->sin_addr)) + +int safe_socket(const char *file, const int lineno, void (cleanup_fn)(void), + int domain, int type, int protocol); +#define SAFE_SOCKET(cleanup_fn, domain, type, protocol) \ + safe_socket(__FILE__, __LINE__, (cleanup_fn), domain, type, protocol) + +int safe_bind(const char *file, const int lineno, void (cleanup_fn)(void), + int socket, const struct sockaddr *address, + socklen_t address_len); +#define SAFE_BIND(cleanup_fn, socket, address, address_len) \ + safe_bind(__FILE__, __LINE__, (cleanup_fn), socket, address, \ + address_len) + +int safe_listen(const char *file, const int lineno, void (cleanup_fn)(void), + int socket, int backlog); +#define SAFE_LISTEN(cleanup_fn, socket, backlog) \ + safe_listen(__FILE__, __LINE__, (cleanup_fn), socket, backlog) + +int safe_connect(const char *file, const int lineno, void (cleanup_fn)(void), + int sockfd, const struct sockaddr *addr, socklen_t addrlen); +#define SAFE_CONNECT(cleanup_fn, sockfd, addr, addrlen) \ + safe_connect(__FILE__, __LINE__, (cleanup_fn), sockfd, addr, addrlen) + +int safe_getsockname(const char *file, const int lineno, + void (cleanup_fn)(void), int sockfd, struct sockaddr *addr, + socklen_t *addrlen); +#define SAFE_GETSOCKNAME(cleanup_fn, sockfd, addr, addrlen) \ + safe_getsockname(__FILE__, __LINE__, (cleanup_fn), sockfd, addr, \ + addrlen) + +#endif /* __SAFE_NET_H__ */ diff --git a/lib/safe_net.c b/lib/safe_net.c new file mode 100644 index 0000000..5130fac --- /dev/null +++ b/lib/safe_net.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2015 Fujitsu Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <errno.h> +#include "test.h" +#include "safe_net.h" + +int safe_socket(const char *file, const int lineno, void (cleanup_fn)(void), + int domain, int type, int protocol) +{ + int rval; + + rval = socket(domain, type, protocol); + + if (rval < 0) { + tst_brkm(TBROK | TERRNO, cleanup_fn, + "%s:%d: socket(%d, %d, %d) failed", file, lineno, + domain, type, protocol); + } + + return rval; +} + +int safe_bind(const char *file, const int lineno, void (cleanup_fn)(void), + int socket, const struct sockaddr *address, + socklen_t address_len) +{ + int i; + + for (i = 0; i < 120; i++) { + if (!bind(socket, address, address_len)) { + tst_resm(TINFO, "bind is OK now"); + return 0; + } + + if (errno != EADDRINUSE) { + tst_brkm(TBROK | TERRNO, cleanup_fn, + "%s:%d: bind(%d, %s, %d) failed", file, lineno, + socket, GET_ADDR(address), address_len); + } + + if ((i + 1) % 10 == 1) { + tst_resm(TINFO, "address is in use, waited %3i sec", + i + 1); + } + + sleep(1); + } + + tst_brkm(TBROK | TERRNO, cleanup_fn, + "%s:%d: Failed to bind(%d, %p, %d) after 30 retries", file, + lineno, socket, GET_ADDR(address), address_len); +} + +int safe_listen(const char *file, const int lineno, void (cleanup_fn)(void), + int socket, int backlog) +{ + int rval; + + rval = listen(socket, backlog); + + if (rval < 0) { + tst_brkm(TBROK | TERRNO, cleanup_fn, + "%s:%d: listen(%d, %d) failed", file, lineno, socket, + backlog); + } + + return rval; +} + +int safe_connect(const char *file, const int lineno, void (cleanup_fn)(void), + int sockfd, const struct sockaddr *addr, socklen_t addrlen) +{ + int rval; + + rval = connect(sockfd, addr, addrlen); + + if (rval < 0) { + tst_brkm(TBROK | TERRNO, cleanup_fn, + "%s:%d: connect(%d, %s, %d) failed", file, lineno, + sockfd, GET_ADDR(addr), addrlen); + } + + return rval; +} + +int safe_getsockname(const char *file, const int lineno, + void (cleanup_fn)(void), int sockfd, struct sockaddr *addr, + socklen_t *addrlen) +{ + int rval; + + rval = getsockname(sockfd, addr, addrlen); + + if (rval < 0) { + tst_brkm(TBROK | TERRNO, cleanup_fn, + "%s:%d: getsockname(%d, %s, %p) failed", file, lineno, + sockfd, GET_ADDR(addr), addrlen); + } + + return rval; +} -- 1.9.3 ------------------------------------------------------------------------------ _______________________________________________ Ltp-list mailing list Ltp-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ltp-list