mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-31 02:46:29 +01:00 
			
		
		
		
	 4aaa38d26e
			
		
	
	
	4aaa38d26e
	
	
	
		
			
			- Added sql/mariadb.h file that should be included first by files in sql directory, if sql_plugin.h is not used (sql_plugin.h adds SHOW variables that must be done before my_global.h is included) - Removed a lot of include my_global.h from include files - Removed include's of some files that my_global.h automatically includes - Removed duplicated include's of my_sys.h - Replaced include my_config.h with my_global.h
		
			
				
	
	
		
			185 lines
		
	
	
	
		
			4.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			185 lines
		
	
	
	
		
			4.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
 | |
| // vim:sw=2:ai
 | |
| 
 | |
| /*
 | |
|  * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
 | |
|  * See COPYRIGHT.txt for details.
 | |
|  */
 | |
| 
 | |
| #include <my_global.h>
 | |
| 
 | |
| #include <stdexcept>
 | |
| #include <string.h>
 | |
| #include <signal.h>
 | |
| #include <sys/un.h>
 | |
| 
 | |
| #include "socket.hpp"
 | |
| #include "string_util.hpp"
 | |
| #include "fatal.hpp"
 | |
| 
 | |
| namespace dena {
 | |
| 
 | |
| void
 | |
| ignore_sigpipe()
 | |
| {
 | |
|   if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
 | |
|     fatal_abort("SIGPIPE SIG_IGN");
 | |
|   }
 | |
| }
 | |
| 
 | |
| void
 | |
| socket_args::set(const config& conf)
 | |
| {
 | |
|   timeout = conf.get_int("timeout", 600);
 | |
|   listen_backlog = conf.get_int("listen_backlog", 256);
 | |
|   std::string node = conf.get_str("host", "");
 | |
|   std::string port = conf.get_str("port", "");
 | |
|   if (!node.empty() || !port.empty()) {
 | |
|     if (family == AF_UNIX || node == "/") {
 | |
|       set_unix_domain(port.c_str());
 | |
|     } else {
 | |
|       const char *nd = node.empty() ? 0 : node.c_str();
 | |
|       if (resolve(nd, port.c_str()) != 0) {
 | |
| 	fatal_abort("getaddrinfo failed: " + node + ":" + port);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   sndbuf = conf.get_int("sndbuf", 0);
 | |
|   rcvbuf = conf.get_int("rcvbuf", 0);
 | |
| }
 | |
| 
 | |
| void
 | |
| socket_args::set_unix_domain(const char *path)
 | |
| {
 | |
|   family = AF_UNIX; 
 | |
|   addr = sockaddr_storage();
 | |
|   addrlen = sizeof(sockaddr_un);
 | |
|   sockaddr_un *const ap = reinterpret_cast<sockaddr_un *>(&addr);
 | |
|   ap->sun_family = AF_UNIX;
 | |
|   strncpy(ap->sun_path, path, sizeof(ap->sun_path) - 1);
 | |
| }
 | |
| 
 | |
| int
 | |
| socket_args::resolve(const char *node, const char *service)
 | |
| {
 | |
|   const int flags = (node == 0) ? AI_PASSIVE : 0;
 | |
|   auto_addrinfo ai;
 | |
|   addr = sockaddr_storage();
 | |
|   addrlen = 0;
 | |
|   const int r = ai.resolve(node, service, flags, family, socktype, protocol);
 | |
|   if (r != 0) {
 | |
|     return r;
 | |
|   }
 | |
|   memcpy(&addr, ai.get()->ai_addr, ai.get()->ai_addrlen);
 | |
|   addrlen = ai.get()->ai_addrlen;
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| int
 | |
| socket_set_options(auto_file& fd, const socket_args& args, std::string& err_r)
 | |
| {
 | |
|   if (args.timeout != 0 && !args.nonblocking) {
 | |
|     struct timeval tv;
 | |
|     tv.tv_sec = args.timeout;
 | |
|     tv.tv_usec = 0;
 | |
|     if (setsockopt(fd.get(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) != 0) {
 | |
|       return errno_string("setsockopt SO_RCVTIMEO", errno, err_r);
 | |
|     }
 | |
|     tv.tv_sec = args.timeout;
 | |
|     tv.tv_usec = 0;
 | |
|     if (setsockopt(fd.get(), SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) != 0) {
 | |
|       return errno_string("setsockopt SO_RCVTIMEO", errno, err_r);
 | |
|     }
 | |
|   }
 | |
|   if (args.nonblocking && fcntl(fd.get(), F_SETFL, O_NONBLOCK) != 0) {
 | |
|     return errno_string("fcntl O_NONBLOCK", errno, err_r);
 | |
|   }
 | |
|   if (args.sndbuf != 0) {
 | |
|     const int v = args.sndbuf;
 | |
|     if (setsockopt(fd.get(), SOL_SOCKET, SO_SNDBUF, &v, sizeof(v)) != 0) {
 | |
|       return errno_string("setsockopt SO_SNDBUF", errno, err_r);
 | |
|     }
 | |
|   }
 | |
|   if (args.rcvbuf != 0) {
 | |
|     const int v = args.rcvbuf;
 | |
|     if (setsockopt(fd.get(), SOL_SOCKET, SO_RCVBUF, &v, sizeof(v)) != 0) {
 | |
|       return errno_string("setsockopt SO_RCVBUF", errno, err_r);
 | |
|     }
 | |
|   }
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| int
 | |
| socket_open(auto_file& fd, const socket_args& args, std::string& err_r)
 | |
| {
 | |
|   fd.reset(socket(args.family, args.socktype, args.protocol));
 | |
|   if (fd.get() < 0) {
 | |
|     return errno_string("socket", errno, err_r);
 | |
|   }
 | |
|   return socket_set_options(fd, args, err_r);
 | |
| }
 | |
| 
 | |
| int
 | |
| socket_connect(auto_file& fd, const socket_args& args, std::string& err_r)
 | |
| {
 | |
|   int r = 0;
 | |
|   if ((r = socket_open(fd, args, err_r)) != 0) {
 | |
|     return r;
 | |
|   }
 | |
|   if (connect(fd.get(), reinterpret_cast<const sockaddr *>(&args.addr),
 | |
|     args.addrlen) != 0) {
 | |
|     if (!args.nonblocking || errno != EINPROGRESS) {
 | |
|       return errno_string("connect", errno, err_r);
 | |
|     }
 | |
|   }
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| int
 | |
| socket_bind(auto_file& fd, const socket_args& args, std::string& err_r)
 | |
| {
 | |
|   fd.reset(socket(args.family, args.socktype, args.protocol));
 | |
|   if (fd.get() < 0) {
 | |
|     return errno_string("socket", errno, err_r);
 | |
|   }
 | |
|   if (args.reuseaddr) {
 | |
|     if (args.family == AF_UNIX) {
 | |
|       const sockaddr_un *const ap =
 | |
| 	reinterpret_cast<const sockaddr_un *>(&args.addr);
 | |
|       if (unlink(ap->sun_path) != 0 && errno != ENOENT) {
 | |
| 	return errno_string("unlink uds", errno, err_r);
 | |
|       }
 | |
|     } else {
 | |
|       int v = 1;
 | |
|       if (setsockopt(fd.get(), SOL_SOCKET, SO_REUSEADDR, &v, sizeof(v)) != 0) {
 | |
| 	return errno_string("setsockopt SO_REUSEADDR", errno, err_r);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   if (bind(fd.get(), reinterpret_cast<const sockaddr *>(&args.addr),
 | |
|     args.addrlen) != 0) {
 | |
|     return errno_string("bind", errno, err_r);
 | |
|   }
 | |
|   if (listen(fd.get(), args.listen_backlog) != 0) {
 | |
|     return errno_string("listen", errno, err_r);
 | |
|   }
 | |
|   if (args.nonblocking && fcntl(fd.get(), F_SETFL, O_NONBLOCK) != 0) {
 | |
|     return errno_string("fcntl O_NONBLOCK", errno, err_r);
 | |
|   }
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| int
 | |
| socket_accept(int listen_fd, auto_file& fd, const socket_args& args,
 | |
|   sockaddr_storage& addr_r, size_socket& addrlen_r, std::string& err_r)
 | |
| {
 | |
|   fd.reset(accept(listen_fd, reinterpret_cast<sockaddr *>(&addr_r),
 | |
|     &addrlen_r));
 | |
|   if (fd.get() < 0) {
 | |
|     return errno_string("accept", errno, err_r);
 | |
|   }
 | |
|   return socket_set_options(fd, args, err_r);
 | |
| }
 | |
| 
 | |
| };
 | |
| 
 |