Add close-on-exec flag (#3553)
This commit is contained in:
parent
7c4035ba00
commit
b4921bfcd9
|
@ -76,6 +76,7 @@ PJ_DEF(pj_status_t) pj_dns_server_create( pj_pool_factory *pf,
|
|||
pj_dns_server *srv;
|
||||
pj_sockaddr sock_addr;
|
||||
pj_activesock_cb sock_cb;
|
||||
pj_activesock_cfg sock_cfg;
|
||||
pj_status_t status;
|
||||
|
||||
PJ_ASSERT_RETURN(pf && ioqueue && p_srv && flags==0, PJ_EINVAL);
|
||||
|
@ -90,11 +91,12 @@ PJ_DEF(pj_status_t) pj_dns_server_create( pj_pool_factory *pf,
|
|||
pj_bzero(&sock_addr, sizeof(sock_addr));
|
||||
sock_addr.addr.sa_family = (pj_uint16_t)af;
|
||||
pj_sockaddr_set_port(&sock_addr, (pj_uint16_t)port);
|
||||
|
||||
|
||||
pj_bzero(&sock_cb, sizeof(sock_cb));
|
||||
sock_cb.on_data_recvfrom = &on_data_recvfrom;
|
||||
pj_activesock_cfg_default(&sock_cfg);
|
||||
|
||||
status = pj_activesock_create_udp(pool, &sock_addr, NULL, ioqueue,
|
||||
status = pj_activesock_create_udp(pool, &sock_addr, &sock_cfg, ioqueue,
|
||||
&sock_cb, srv, &srv->asock, NULL);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_error;
|
||||
|
|
|
@ -1042,7 +1042,8 @@ static pj_status_t start_http_req(pj_http_req *http_req,
|
|||
http_req->resolved = PJ_TRUE;
|
||||
}
|
||||
|
||||
status = pj_sock_socket(http_req->param.addr_family, pj_SOCK_STREAM(),
|
||||
status = pj_sock_socket(http_req->param.addr_family,
|
||||
pj_SOCK_STREAM() | pj_SOCK_CLOEXEC(),
|
||||
0, &sock);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_return; // error creating socket
|
||||
|
|
|
@ -123,7 +123,7 @@ PJ_DEF(pj_status_t) pj_pcap_open(pj_pool_t *pool,
|
|||
|
||||
pj_ansi_strxcpy(file->obj_name, "pcap", sizeof(file->obj_name));
|
||||
|
||||
status = pj_file_open(pool, path, PJ_O_RDONLY, &file->fd);
|
||||
status = pj_file_open(pool, path, PJ_O_RDONLY | PJ_O_CLOEXEC, &file->fd);
|
||||
if (status != PJ_SUCCESS)
|
||||
return status;
|
||||
|
||||
|
|
|
@ -242,10 +242,18 @@ typedef struct pj_activesock_cfg
|
|||
* error is reported after partial data has been sent. Also setting
|
||||
* this will disable the ioqueue concurrency for the socket.
|
||||
*
|
||||
* Default value is 1.
|
||||
* Default value is PJ_TRUE.
|
||||
*/
|
||||
pj_bool_t whole_data;
|
||||
|
||||
/**
|
||||
* If this option is specified, set close-on-exec flag for socket.
|
||||
* This option is only used by #pj_activesock_create_udp()
|
||||
*
|
||||
* Default value is PJ_TRUE.
|
||||
*/
|
||||
pj_bool_t sock_cloexec;
|
||||
|
||||
} pj_activesock_cfg;
|
||||
|
||||
|
||||
|
|
|
@ -61,7 +61,8 @@ enum pj_file_access
|
|||
PJ_O_WRONLY = 0x1102, /**< Open file for writing. */
|
||||
PJ_O_RDWR = 0x1103, /**< Open file for reading and writing.
|
||||
File will be truncated. */
|
||||
PJ_O_APPEND = 0x1108 /**< Append to existing file. */
|
||||
PJ_O_APPEND = 0x1108, /**< Append to existing file. */
|
||||
PJ_O_CLOEXEC = 0x1104, /**< Enable unix close-on-exec flag. */
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -1519,6 +1519,17 @@ PJ_DECL(int) pj_run_app(pj_main_func_ptr main_func, int argc, char *argv[],
|
|||
pj_status_t pj_thread_init(void);
|
||||
|
||||
|
||||
/* **************************************************************************/
|
||||
/**
|
||||
* Set file descriptor close-on-exec flag
|
||||
*
|
||||
* @param fd The file descriptor
|
||||
* @return on success, PJ_SUCCESS
|
||||
*
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_set_cloexec_flag(int fd);
|
||||
|
||||
|
||||
PJ_END_DECL
|
||||
|
||||
#endif /* __PJ_OS_H__ */
|
||||
|
|
|
@ -140,6 +140,9 @@ extern const pj_uint16_t PJ_SOCK_RAW;
|
|||
/** Reliably-delivered messages. @see pj_SOCK_RDM() */
|
||||
extern const pj_uint16_t PJ_SOCK_RDM;
|
||||
|
||||
/** The close-on-exec flag. @see pj_SOCK_CLOEXEC() */
|
||||
extern const int PJ_SOCK_CLOEXEC;
|
||||
|
||||
|
||||
/*
|
||||
* Accessor functions for various constants. These functions are provided
|
||||
|
@ -155,6 +158,8 @@ extern const pj_uint16_t PJ_SOCK_RDM;
|
|||
PJ_DECL(int) pj_SOCK_RAW(void);
|
||||
/** Get #PJ_SOCK_RDM constant */
|
||||
PJ_DECL(int) pj_SOCK_RDM(void);
|
||||
/** Get #PJ_SOCK_CLOEXEC constant */
|
||||
PJ_DECL(int) pj_SOCK_CLOEXEC(void);
|
||||
#else
|
||||
/** Get #PJ_SOCK_STREAM constant */
|
||||
# define pj_SOCK_STREAM() PJ_SOCK_STREAM
|
||||
|
@ -164,6 +169,8 @@ extern const pj_uint16_t PJ_SOCK_RDM;
|
|||
# define pj_SOCK_RAW() PJ_SOCK_RAW
|
||||
/** Get #PJ_SOCK_RDM constant */
|
||||
# define pj_SOCK_RDM() PJ_SOCK_RDM
|
||||
/** Get #PJ_SOCK_CLOEXEC constant */
|
||||
# define pj_SOCK_CLOEXEC() PJ_SOCK_CLOEXEC
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -1082,6 +1082,13 @@ typedef struct pj_ssl_sock_param
|
|||
*/
|
||||
pj_bool_t sockopt_ignore_error;
|
||||
|
||||
/**
|
||||
* Specify if should set close-on-exec flag for socket.
|
||||
*
|
||||
* Default: PJ_TRUE
|
||||
*/
|
||||
pj_bool_t sock_cloexec;
|
||||
|
||||
} pj_ssl_sock_param;
|
||||
|
||||
|
||||
|
|
|
@ -127,6 +127,7 @@ PJ_DEF(void) pj_activesock_cfg_default(pj_activesock_cfg *cfg)
|
|||
cfg->async_cnt = 1;
|
||||
cfg->concurrency = -1;
|
||||
cfg->whole_data = PJ_TRUE;
|
||||
cfg->sock_cloexec = PJ_TRUE;
|
||||
}
|
||||
|
||||
#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \
|
||||
|
@ -197,13 +198,13 @@ PJ_DEF(pj_status_t) pj_activesock_create( pj_pool_t *pool,
|
|||
|
||||
PJ_ASSERT_RETURN(pool && ioqueue && cb && p_asock, PJ_EINVAL);
|
||||
PJ_ASSERT_RETURN(sock>=0 && sock!=PJ_INVALID_SOCKET, PJ_EINVAL);
|
||||
PJ_ASSERT_RETURN(sock_type==pj_SOCK_STREAM() ||
|
||||
sock_type==pj_SOCK_DGRAM(), PJ_EINVAL);
|
||||
PJ_ASSERT_RETURN((sock_type & 0xF)==pj_SOCK_STREAM() ||
|
||||
(sock_type & 0xF)==pj_SOCK_DGRAM(), PJ_EINVAL);
|
||||
PJ_ASSERT_RETURN(!opt || opt->async_cnt >= 1, PJ_EINVAL);
|
||||
|
||||
asock = PJ_POOL_ZALLOC_T(pool, pj_activesock_t);
|
||||
asock->ioqueue = ioqueue;
|
||||
asock->stream_oriented = (sock_type == pj_SOCK_STREAM());
|
||||
asock->stream_oriented = ((sock_type & 0xF) == pj_SOCK_STREAM());
|
||||
asock->async_count = (opt? opt->async_cnt : 1);
|
||||
asock->whole_data = (opt? opt->whole_data : 1);
|
||||
asock->max_loop = PJ_ACTIVESOCK_MAX_LOOP;
|
||||
|
@ -256,13 +257,17 @@ PJ_DEF(pj_status_t) pj_activesock_create_udp( pj_pool_t *pool,
|
|||
pj_sock_t sock_fd;
|
||||
pj_sockaddr default_addr;
|
||||
pj_status_t status;
|
||||
int sock_type = pj_SOCK_DGRAM();
|
||||
|
||||
if (opt && opt->sock_cloexec)
|
||||
sock_type |= pj_SOCK_CLOEXEC();
|
||||
|
||||
if (addr == NULL) {
|
||||
pj_sockaddr_init(pj_AF_INET(), &default_addr, NULL, 0);
|
||||
addr = &default_addr;
|
||||
}
|
||||
|
||||
status = pj_sock_socket(addr->addr.sa_family, pj_SOCK_DGRAM(), 0,
|
||||
status = pj_sock_socket(addr->addr.sa_family, sock_type, 0,
|
||||
&sock_fd);
|
||||
if (status != PJ_SUCCESS) {
|
||||
return status;
|
||||
|
@ -274,7 +279,7 @@ PJ_DEF(pj_status_t) pj_activesock_create_udp( pj_pool_t *pool,
|
|||
return status;
|
||||
}
|
||||
|
||||
status = pj_activesock_create(pool, sock_fd, pj_SOCK_DGRAM(), opt,
|
||||
status = pj_activesock_create(pool, sock_fd, sock_type, opt,
|
||||
ioqueue, cb, user_data, p_asock);
|
||||
if (status != PJ_SUCCESS) {
|
||||
pj_sock_close(sock_fd);
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
#include <pj/limits.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#if defined(PJ_HAS_FCNTL_H) && PJ_HAS_FCNTL_H != 0
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
PJ_DEF(pj_status_t) pj_file_open( pj_pool_t *pool,
|
||||
const char *pathname,
|
||||
|
@ -54,6 +57,11 @@ PJ_DEF(pj_status_t) pj_file_open( pj_pool_t *pool,
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(O_CLOEXEC)
|
||||
if ((flags & PJ_O_CLOEXEC) == PJ_O_CLOEXEC)
|
||||
*p++ = 'e';
|
||||
#endif
|
||||
|
||||
if (p==mode)
|
||||
return PJ_EINVAL;
|
||||
|
||||
|
|
|
@ -89,6 +89,11 @@ PJ_DEF(pj_status_t) pj_file_open( pj_pool_t *pool,
|
|||
|
||||
PJ_ASSERT_RETURN(pathname!=NULL, PJ_EINVAL);
|
||||
|
||||
if ((flags & PJ_O_CLOEXEC) == PJ_O_CLOEXEC) {
|
||||
/* Win32 not support cloexec flag, should remove it */
|
||||
flags &= ~(PJ_O_CLOEXEC & 0xF);
|
||||
}
|
||||
|
||||
if ((flags & PJ_O_WRONLY) == PJ_O_WRONLY) {
|
||||
dwDesiredAccess |= GENERIC_WRITE;
|
||||
if ((flags & PJ_O_APPEND) == PJ_O_APPEND) {
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
#define os_ioctl ioctl
|
||||
#define os_read read
|
||||
#define os_close close
|
||||
#define os_epoll_create epoll_create
|
||||
#define os_epoll_create epoll_create1
|
||||
#define os_epoll_ctl epoll_ctl
|
||||
#define os_epoll_wait epoll_wait
|
||||
|
||||
|
@ -163,11 +163,11 @@ static unsigned detect_epoll_support()
|
|||
return epoll_support;
|
||||
#endif
|
||||
|
||||
epfd = os_epoll_create(5);
|
||||
epfd = os_epoll_create(EPOLL_CLOEXEC);
|
||||
if (epfd < 0)
|
||||
goto on_error;
|
||||
|
||||
evfd = eventfd(0, 0);
|
||||
evfd = eventfd(0, EFD_CLOEXEC);
|
||||
if (evfd < 0)
|
||||
goto on_error;
|
||||
|
||||
|
@ -374,13 +374,13 @@ PJ_DEF(pj_status_t) pj_ioqueue_create2(pj_pool_t *pool,
|
|||
if (rc != PJ_SUCCESS)
|
||||
return rc;
|
||||
|
||||
ioqueue->epfd = os_epoll_create(max_fd);
|
||||
ioqueue->epfd = os_epoll_create(EPOLL_CLOEXEC);
|
||||
if (ioqueue->epfd < 0) {
|
||||
pj_lock_acquire(ioqueue->lock);
|
||||
ioqueue_destroy(ioqueue);
|
||||
return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
|
||||
}
|
||||
|
||||
|
||||
/*ioqueue->events = pj_pool_calloc(pool, max_fd, sizeof(struct epoll_event));
|
||||
PJ_ASSERT_RETURN(ioqueue->events != NULL, PJ_ENOMEM);
|
||||
|
||||
|
|
|
@ -196,6 +196,9 @@ PJ_DEF(pj_status_t) pj_ioqueue_create2(pj_pool_t *pool,
|
|||
return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
|
||||
}
|
||||
|
||||
/* set close-on-exec flag */
|
||||
pj_set_cloexec_flag(ioqueue->kfd);
|
||||
|
||||
PJ_LOG(4,
|
||||
("pjlib", "%s I/O Queue created (%p)", pj_ioqueue_name(), ioqueue));
|
||||
|
||||
|
|
|
@ -51,6 +51,10 @@
|
|||
#endif
|
||||
#include <pj/config.h>
|
||||
|
||||
#if defined(PJ_HAS_FCNTL_H) && PJ_HAS_FCNTL_H != 0
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#define THIS_FILE "os_core_unix.c"
|
||||
|
||||
#define SIGNATURE1 0xDEAFBEEF
|
||||
|
@ -2161,3 +2165,17 @@ PJ_DEF(int) pj_run_app(pj_main_func_ptr main_func, int argc, char *argv[],
|
|||
return (*main_func)(argc, argv);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set file descriptor close-on-exec flag
|
||||
*/
|
||||
PJ_DEF(pj_status_t) pj_set_cloexec_flag(int fd)
|
||||
{
|
||||
#if defined(FD_CLOEXEC)
|
||||
int flags = fcntl(fd, F_GETFD);
|
||||
if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
|
||||
return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
|
||||
}
|
||||
#endif
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -1619,3 +1619,12 @@ PJ_DEF(int) pj_run_app(pj_main_func_ptr main_func, int argc, char *argv[],
|
|||
PJ_UNUSED_ARG(flags);
|
||||
return (*main_func)(argc, argv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set file descriptor close-on-exec flag
|
||||
*/
|
||||
PJ_DEF(pj_status_t) pj_set_cloexec_flag(int fd)
|
||||
{
|
||||
PJ_UNUSED_ARG(fd);
|
||||
return PJ_ENOTSUP;
|
||||
}
|
||||
|
|
|
@ -55,6 +55,27 @@ const pj_uint16_t PJ_SOCK_DGRAM = SOCK_DGRAM;
|
|||
const pj_uint16_t PJ_SOCK_RAW = SOCK_RAW;
|
||||
const pj_uint16_t PJ_SOCK_RDM = SOCK_RDM;
|
||||
|
||||
#if defined(SOCK_CLOEXEC)
|
||||
const int PJ_SOCK_CLOEXEC = SOCK_CLOEXEC;
|
||||
#elif defined(PJ_WIN32) || defined(PJ_WIN64)
|
||||
const int PJ_SOCK_CLOEXEC = 0;
|
||||
#else
|
||||
/*
|
||||
* On some unix-like platforms (eg. macos), SOCK_CLOEXEC is not defined,
|
||||
* It can use #pj_set_cloexec_flag() to set socket close-on-exec flag.
|
||||
*
|
||||
* Set PJ_SOCK_CLOEXEC to a non-zero value,
|
||||
* together with the macro SOCK_CLOEXEC to determine whether it should
|
||||
* set socket close-on-exec flag.
|
||||
* #if !defined(SOCK_CLOEXEC)
|
||||
* if (type & pj_SOCK_CLOEXEC() == pj_SOCK_CLOEXEC()) {
|
||||
* // set close-on-exec flag
|
||||
* }
|
||||
* #endif
|
||||
*/
|
||||
const int PJ_SOCK_CLOEXEC = 02000000;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Socket level values.
|
||||
*/
|
||||
|
@ -531,6 +552,7 @@ PJ_DEF(pj_status_t) pj_sock_socket(int af,
|
|||
int proto,
|
||||
pj_sock_t *sock)
|
||||
{
|
||||
int type0 = type;
|
||||
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
|
@ -538,13 +560,20 @@ PJ_DEF(pj_status_t) pj_sock_socket(int af,
|
|||
PJ_ASSERT_RETURN(sock!=NULL, PJ_EINVAL);
|
||||
PJ_ASSERT_RETURN(PJ_INVALID_SOCKET==-1,
|
||||
(*sock=PJ_INVALID_SOCKET, PJ_EINVAL));
|
||||
|
||||
|
||||
#if !defined(SOCK_CLOEXEC)
|
||||
if ((type0 & pj_SOCK_CLOEXEC()) == pj_SOCK_CLOEXEC())
|
||||
type &= ~pj_SOCK_CLOEXEC();
|
||||
#else
|
||||
PJ_UNUSED_ARG(type0);
|
||||
#endif
|
||||
|
||||
*sock = socket(af, type, proto);
|
||||
if (*sock == PJ_INVALID_SOCKET)
|
||||
return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
|
||||
else {
|
||||
pj_int32_t val = 1;
|
||||
if (type == pj_SOCK_STREAM()) {
|
||||
if ((type & 0xF) == pj_SOCK_STREAM()) {
|
||||
pj_sock_setsockopt(*sock, pj_SOL_SOCKET(), pj_SO_NOSIGPIPE(),
|
||||
&val, sizeof(val));
|
||||
}
|
||||
|
@ -556,11 +585,16 @@ PJ_DEF(pj_status_t) pj_sock_socket(int af,
|
|||
#endif
|
||||
#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \
|
||||
PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0
|
||||
if (type == pj_SOCK_DGRAM()) {
|
||||
if ((type & 0xF) == pj_SOCK_DGRAM()) {
|
||||
pj_sock_setsockopt(*sock, pj_SOL_SOCKET(), SO_NOSIGPIPE,
|
||||
&val, sizeof(val));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(SOCK_CLOEXEC)
|
||||
if ((type0 & pj_SOCK_CLOEXEC()) == pj_SOCK_CLOEXEC())
|
||||
pj_set_cloexec_flag((int)(*sock));
|
||||
#endif
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1253,12 +1253,14 @@ static pj_status_t socketpair_imp(int family,
|
|||
pj_str_t loopback;
|
||||
pj_sockaddr sa;
|
||||
int salen;
|
||||
int type0 = type;
|
||||
|
||||
#if PJ_HAS_TCP
|
||||
PJ_ASSERT_RETURN(type == pj_SOCK_DGRAM() || type == pj_SOCK_STREAM(),
|
||||
PJ_ASSERT_RETURN((type & 0xF) == pj_SOCK_DGRAM() ||
|
||||
(type & 0xF) == pj_SOCK_STREAM(),
|
||||
PJ_EINVAL);
|
||||
#else
|
||||
PJ_ASSERT_RETURN(type == pj_SOCK_DGRAM(), PJ_EINVAL);
|
||||
PJ_ASSERT_RETURN((type & 0xF) == pj_SOCK_DGRAM(), PJ_EINVAL);
|
||||
#endif
|
||||
|
||||
PJ_ASSERT_RETURN(family == pj_AF_INET() || family == pj_AF_INET6(),
|
||||
|
@ -1266,6 +1268,13 @@ static pj_status_t socketpair_imp(int family,
|
|||
|
||||
loopback = family == pj_AF_INET() ? pj_str("127.0.0.1") : pj_str("::1");
|
||||
|
||||
#if !defined(SOCK_CLOEXEC)
|
||||
if ((type0 & pj_SOCK_CLOEXEC()) == pj_SOCK_CLOEXEC())
|
||||
type &= ~pj_SOCK_CLOEXEC();
|
||||
#else
|
||||
PJ_UNUSED_ARG(type0);
|
||||
#endif
|
||||
|
||||
/* listen */
|
||||
status = pj_sock_socket(family, type, protocol, &lfd);
|
||||
if (status != PJ_SUCCESS)
|
||||
|
@ -1282,7 +1291,7 @@ static pj_status_t socketpair_imp(int family,
|
|||
goto on_error;
|
||||
|
||||
#if PJ_HAS_TCP
|
||||
if (type == pj_SOCK_STREAM()) {
|
||||
if ((type & 0xF) == pj_SOCK_STREAM()) {
|
||||
status = pj_sock_listen(lfd, 1);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_error;
|
||||
|
@ -1297,7 +1306,7 @@ static pj_status_t socketpair_imp(int family,
|
|||
if (status != PJ_SUCCESS)
|
||||
goto on_error;
|
||||
|
||||
if (type == pj_SOCK_DGRAM()) {
|
||||
if ((type & 0xF) == pj_SOCK_DGRAM()) {
|
||||
status = pj_sock_getsockname(cfd, &sa, &salen);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_error;
|
||||
|
@ -1308,7 +1317,7 @@ static pj_status_t socketpair_imp(int family,
|
|||
sv[1] = cfd;
|
||||
}
|
||||
#if PJ_HAS_TCP
|
||||
else if (type == pj_SOCK_STREAM()) {
|
||||
else if ((type & 0xF) == pj_SOCK_STREAM()) {
|
||||
pj_sock_t newfd = PJ_INVALID_SOCKET;
|
||||
status = pj_sock_accept(lfd, &newfd, NULL, NULL);
|
||||
if (status != PJ_SUCCESS)
|
||||
|
@ -1319,6 +1328,13 @@ static pj_status_t socketpair_imp(int family,
|
|||
}
|
||||
#endif
|
||||
|
||||
#if !defined(SOCK_CLOEXEC)
|
||||
if ((type0 & pj_SOCK_CLOEXEC()) == pj_SOCK_CLOEXEC()) {
|
||||
pj_set_cloexec_flag((int)sv[0]);
|
||||
pj_set_cloexec_flag((int)sv[1]);
|
||||
}
|
||||
#endif
|
||||
|
||||
return PJ_SUCCESS;
|
||||
|
||||
on_error:
|
||||
|
@ -1337,13 +1353,19 @@ PJ_DEF(pj_status_t) pj_sock_socketpair(int family,
|
|||
{
|
||||
int status;
|
||||
int tmp_sv[2];
|
||||
int type0 = type;
|
||||
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
#if !defined(SOCK_CLOEXEC)
|
||||
if ((type0 & pj_SOCK_CLOEXEC()) == pj_SOCK_CLOEXEC())
|
||||
type &= ~pj_SOCK_CLOEXEC();
|
||||
#endif
|
||||
|
||||
status = socketpair(family, type, protocol, tmp_sv);
|
||||
if (status != PJ_SUCCESS) {
|
||||
if (errno == EOPNOTSUPP) {
|
||||
return socketpair_imp(family, type, protocol, sv);
|
||||
return socketpair_imp(family, type0, protocol, sv);
|
||||
}
|
||||
status = PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
|
||||
return status;
|
||||
|
@ -1417,6 +1439,11 @@ PJ_DEF(int) pj_SOCK_RDM(void)
|
|||
return PJ_SOCK_RDM;
|
||||
}
|
||||
|
||||
PJ_DEF(int) pj_SOCK_CLOEXEC(void)
|
||||
{
|
||||
return PJ_SOCK_CLOEXEC;
|
||||
}
|
||||
|
||||
PJ_DEF(pj_uint16_t) pj_SOL_SOCKET(void)
|
||||
{
|
||||
return PJ_SOL_SOCKET;
|
||||
|
|
|
@ -55,6 +55,7 @@ const pj_uint16_t PJ_SOCK_STREAM= SOCK_STREAM;
|
|||
const pj_uint16_t PJ_SOCK_DGRAM = SOCK_DGRAM;
|
||||
const pj_uint16_t PJ_SOCK_RAW = SOCK_RAW;
|
||||
const pj_uint16_t PJ_SOCK_RDM = SOCK_RDM;
|
||||
const int PJ_SOCK_CLOEXEC = 0;
|
||||
|
||||
/*
|
||||
* Socket level values.
|
||||
|
|
|
@ -47,6 +47,7 @@ PJ_DEF(void) pj_ssl_sock_param_default(pj_ssl_sock_param *param)
|
|||
param->qos_ignore_error = PJ_TRUE;
|
||||
|
||||
param->sockopt_ignore_error = PJ_TRUE;
|
||||
param->sock_cloexec = PJ_TRUE;
|
||||
|
||||
/* Security config */
|
||||
param->proto = PJ_SSL_SOCK_PROTO_DEFAULT;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <pj/errno.h>
|
||||
#include <pj/log.h>
|
||||
#include <pj/math.h>
|
||||
#include <pj/os.h>
|
||||
#include <pj/pool.h>
|
||||
#include <pj/string.h>
|
||||
|
||||
|
@ -953,6 +954,10 @@ static pj_bool_t ssock_on_accept_complete (pj_ssl_sock_t *ssock_parent,
|
|||
PJ_UNUSED_ARG(newconn);
|
||||
#endif
|
||||
|
||||
/* Set close-on-exec flag */
|
||||
if (ssock_parent->newsock_param.sock_cloexec)
|
||||
pj_set_cloexec_flag((int)newsock);
|
||||
|
||||
if (accept_status != PJ_SUCCESS) {
|
||||
if (ssock_parent->param.cb.on_accept_complete2) {
|
||||
(*ssock_parent->param.cb.on_accept_complete2)(ssock_parent, NULL,
|
||||
|
@ -1420,7 +1425,7 @@ PJ_DEF(pj_status_t) pj_ssl_sock_create (pj_pool_t *pool,
|
|||
pj_pool_t *info_pool;
|
||||
|
||||
PJ_ASSERT_RETURN(pool && param && p_ssock, PJ_EINVAL);
|
||||
PJ_ASSERT_RETURN(param->sock_type == pj_SOCK_STREAM(), PJ_ENOTSUP);
|
||||
PJ_ASSERT_RETURN((param->sock_type & 0xF) == pj_SOCK_STREAM(), PJ_ENOTSUP);
|
||||
|
||||
info_pool = pj_pool_create(pool->factory, "ssl_chain%p", 512, 512, NULL);
|
||||
pool = pj_pool_create(pool->factory, "ssl%p", 512, 512, NULL);
|
||||
|
@ -1945,6 +1950,8 @@ pj_ssl_sock_start_accept2(pj_ssl_sock_t *ssock,
|
|||
goto on_error;
|
||||
#else
|
||||
/* Create socket */
|
||||
if (ssock->param.sock_cloexec)
|
||||
ssock->param.sock_type |= pj_SOCK_CLOEXEC();
|
||||
status = pj_sock_socket(ssock->param.sock_af, ssock->param.sock_type, 0,
|
||||
&ssock->sock);
|
||||
if (status != PJ_SUCCESS)
|
||||
|
@ -2076,6 +2083,8 @@ PJ_DEF(pj_status_t) pj_ssl_sock_start_connect2(
|
|||
PJ_EINVAL);
|
||||
|
||||
/* Create socket */
|
||||
if (ssock->param.sock_cloexec)
|
||||
ssock->param.sock_type |= pj_SOCK_CLOEXEC();
|
||||
status = pj_sock_socket(ssock->param.sock_af, ssock->param.sock_type, 0,
|
||||
&ssock->sock);
|
||||
if (status != PJ_SUCCESS)
|
||||
|
|
|
@ -236,7 +236,8 @@ pjmedia_avi_player_create_streams(pj_pool_t *pool,
|
|||
}
|
||||
|
||||
/* Open file. */
|
||||
status = pj_file_open(pool, filename, PJ_O_RDONLY, &fport[0]->fd);
|
||||
status = pj_file_open(pool, filename, PJ_O_RDONLY | PJ_O_CLOEXEC,
|
||||
&fport[0]->fd);
|
||||
if (status != PJ_SUCCESS)
|
||||
return status;
|
||||
|
||||
|
@ -441,7 +442,7 @@ pjmedia_avi_player_create_streams(pj_pool_t *pool,
|
|||
}
|
||||
|
||||
/* Open file. */
|
||||
status = pj_file_open(pool, filename, PJ_O_RDONLY,
|
||||
status = pj_file_open(pool, filename, PJ_O_RDONLY | PJ_O_CLOEXEC,
|
||||
&fport[nstr]->fd);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_error;
|
||||
|
|
|
@ -236,7 +236,7 @@ PJ_DEF(pj_status_t) pjmedia_transport_udp_create3(pjmedia_endpt *endpt,
|
|||
si.rtp_sock = si.rtcp_sock = PJ_INVALID_SOCKET;
|
||||
|
||||
/* Create RTP socket */
|
||||
status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &si.rtp_sock);
|
||||
status = pj_sock_socket(af, pj_SOCK_DGRAM() | pj_SOCK_CLOEXEC(), 0, &si.rtp_sock);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_error;
|
||||
|
||||
|
@ -252,7 +252,7 @@ PJ_DEF(pj_status_t) pjmedia_transport_udp_create3(pjmedia_endpt *endpt,
|
|||
|
||||
|
||||
/* Create RTCP socket */
|
||||
status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &si.rtcp_sock);
|
||||
status = pj_sock_socket(af, pj_SOCK_DGRAM() | pj_SOCK_CLOEXEC(), 0, &si.rtcp_sock);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_error;
|
||||
|
||||
|
|
|
@ -268,7 +268,8 @@ PJ_DEF(pj_status_t) pjmedia_wav_player_port_create( pj_pool_t *pool,
|
|||
}
|
||||
|
||||
/* Open file. */
|
||||
status = pj_file_open( pool, filename, PJ_O_RDONLY, &fport->fd);
|
||||
status = pj_file_open(pool, filename, PJ_O_RDONLY | PJ_O_CLOEXEC,
|
||||
&fport->fd);
|
||||
if (status != PJ_SUCCESS)
|
||||
return status;
|
||||
|
||||
|
|
|
@ -436,7 +436,7 @@ PJ_DEF(pj_status_t) pjmedia_wav_playlist_create(pj_pool_t *pool,
|
|||
}
|
||||
|
||||
/* Open file. */
|
||||
status = pj_file_open( pool, filename, PJ_O_RDONLY,
|
||||
status = pj_file_open( pool, filename, PJ_O_RDONLY | PJ_O_CLOEXEC,
|
||||
&fport->fd_list[index]);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_error;
|
||||
|
|
|
@ -115,7 +115,8 @@ PJ_DEF(pj_status_t) pjmedia_wav_writer_port_create( pj_pool_t *pool,
|
|||
* We need the read mode because we'll modify the WAVE header once
|
||||
* the recording has completed.
|
||||
*/
|
||||
status = pj_file_open(pool, filename, PJ_O_WRONLY, &fport->fd);
|
||||
status = pj_file_open(pool, filename, PJ_O_WRONLY | PJ_O_CLOEXEC,
|
||||
&fport->fd);
|
||||
if (status != PJ_SUCCESS)
|
||||
return status;
|
||||
|
||||
|
|
|
@ -174,7 +174,8 @@ static pj_status_t get_local_interface(const pj_sockaddr *server,
|
|||
int addr_len;
|
||||
pj_status_t status;
|
||||
|
||||
status = pj_sock_socket(server->addr.sa_family, pj_SOCK_DGRAM(),
|
||||
status = pj_sock_socket(server->addr.sa_family,
|
||||
pj_SOCK_DGRAM() | pj_SOCK_CLOEXEC(),
|
||||
0, &sock);
|
||||
if (status != PJ_SUCCESS)
|
||||
return status;
|
||||
|
@ -274,7 +275,7 @@ PJ_DEF(pj_status_t) pj_stun_detect_nat_type2(const pj_sockaddr *server,
|
|||
* Initialize socket.
|
||||
*/
|
||||
af = server->addr.sa_family;
|
||||
status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &sess->sock);
|
||||
status = pj_sock_socket(af, pj_SOCK_DGRAM() | pj_SOCK_CLOEXEC(), 0, &sess->sock);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_error;
|
||||
|
||||
|
|
|
@ -226,7 +226,7 @@ PJ_DEF(pj_status_t) pj_stun_sock_create( pj_stun_config *stun_cfg,
|
|||
&stun_sock_destructor);
|
||||
|
||||
/* Create socket and bind socket */
|
||||
status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &stun_sock->sock_fd);
|
||||
status = pj_sock_socket(af, pj_SOCK_DGRAM() | pj_SOCK_CLOEXEC(), 0, &stun_sock->sock_fd);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_error;
|
||||
|
||||
|
|
|
@ -1229,6 +1229,7 @@ static void turn_on_state(pj_turn_session *sess,
|
|||
sock_type = pj_SOCK_DGRAM();
|
||||
else
|
||||
sock_type = pj_SOCK_STREAM();
|
||||
sock_type |= pj_SOCK_CLOEXEC();
|
||||
|
||||
cfg_bind_addr = &turn_sock->setting.bound_addr;
|
||||
max_bind_retry = MAX_BIND_RETRY;
|
||||
|
@ -1672,7 +1673,7 @@ static void turn_on_connection_attempt(pj_turn_session *sess,
|
|||
new_conn->state = DATACONN_STATE_INITSOCK;
|
||||
|
||||
/* Init socket */
|
||||
status = pj_sock_socket(turn_sock->af, pj_SOCK_STREAM(), 0, &sock);
|
||||
status = pj_sock_socket(turn_sock->af, pj_SOCK_STREAM() | pj_SOCK_CLOEXEC(), 0, &sock);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_return;
|
||||
|
||||
|
@ -1906,7 +1907,7 @@ static void turn_on_connect_complete(pj_turn_session *sess,
|
|||
new_conn->state = DATACONN_STATE_INITSOCK;
|
||||
|
||||
/* Init socket */
|
||||
status = pj_sock_socket(turn_sock->af, pj_SOCK_STREAM(), 0, &sock);
|
||||
status = pj_sock_socket(turn_sock->af, pj_SOCK_STREAM() | pj_SOCK_CLOEXEC(), 0, &sock);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_return;
|
||||
|
||||
|
|
|
@ -1006,7 +1006,8 @@ static pj_status_t lis_create_transport(pjsip_tpfactory *factory,
|
|||
listener = (struct tcp_listener*)factory;
|
||||
|
||||
/* Create socket */
|
||||
status = pj_sock_socket(rem_addr->addr.sa_family, pj_SOCK_STREAM(),
|
||||
status = pj_sock_socket(rem_addr->addr.sa_family,
|
||||
pj_SOCK_STREAM() | pj_SOCK_CLOEXEC(),
|
||||
0, &sock);
|
||||
if (status != PJ_SUCCESS)
|
||||
return status;
|
||||
|
@ -1146,6 +1147,9 @@ static pj_bool_t on_accept_complete(pj_activesock_t *asock,
|
|||
pj_sockaddr_print(src_addr, addr, sizeof(addr), 3),
|
||||
sock));
|
||||
|
||||
/* Set close-on-exec flag */
|
||||
pj_set_cloexec_flag((int)sock);
|
||||
|
||||
/* Apply QoS, if specified */
|
||||
status = pj_sock_apply_qos2(sock, listener->qos_type,
|
||||
&listener->qos_params,
|
||||
|
@ -1682,7 +1686,7 @@ PJ_DEF(pj_status_t) pjsip_tcp_transport_lis_start(pjsip_tpfactory *factory,
|
|||
af = pjsip_transport_type_get_af(listener->factory.type);
|
||||
|
||||
/* Create socket */
|
||||
status = pj_sock_socket(af, pj_SOCK_STREAM(), 0, &sock);
|
||||
status = pj_sock_socket(af, pj_SOCK_STREAM() | pj_SOCK_CLOEXEC(), 0, &sock);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_error;
|
||||
|
||||
|
|
|
@ -533,7 +533,7 @@ static pj_status_t create_socket(int af, const pj_sockaddr_t *local_a,
|
|||
pj_sockaddr_in6 tmp_addr6;
|
||||
pj_status_t status;
|
||||
|
||||
status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &sock);
|
||||
status = pj_sock_socket(af, pj_SOCK_DGRAM() | pj_SOCK_CLOEXEC(), 0, &sock);
|
||||
if (status != PJ_SUCCESS)
|
||||
return status;
|
||||
|
||||
|
|
|
@ -756,7 +756,7 @@ PJ_DEF(pj_status_t) pjsua_reconfigure_logging(const pjsua_logging_config *cfg)
|
|||
|
||||
/* If output log file is desired, create the file: */
|
||||
if (pjsua_var.log_cfg.log_filename.slen) {
|
||||
unsigned flags = PJ_O_WRONLY;
|
||||
unsigned flags = PJ_O_WRONLY | PJ_O_CLOEXEC;
|
||||
flags |= pjsua_var.log_cfg.log_file_flags;
|
||||
status = pj_file_open(pjsua_var.pool,
|
||||
pjsua_var.log_cfg.log_filename.ptr,
|
||||
|
@ -2374,7 +2374,7 @@ static pj_status_t create_sip_udp_sock(int af,
|
|||
}
|
||||
|
||||
/* Create socket */
|
||||
status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &sock);
|
||||
status = pj_sock_socket(af, pj_SOCK_DGRAM() | pj_SOCK_CLOEXEC(), 0, &sock);
|
||||
if (status != PJ_SUCCESS) {
|
||||
pjsua_perror(THIS_FILE, "socket() error", status);
|
||||
return status;
|
||||
|
|
|
@ -319,7 +319,7 @@ static pj_status_t create_rtp_rtcp_sock(pjsua_call_media *call_med,
|
|||
}
|
||||
|
||||
/* Create RTP socket. */
|
||||
status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &sock[0]);
|
||||
status = pj_sock_socket(af, pj_SOCK_DGRAM() | pj_SOCK_CLOEXEC(), 0, &sock[0]);
|
||||
if (status != PJ_SUCCESS) {
|
||||
pjsua_perror(THIS_FILE, "socket() error", status);
|
||||
return status;
|
||||
|
@ -362,7 +362,7 @@ static pj_status_t create_rtp_rtcp_sock(pjsua_call_media *call_med,
|
|||
}
|
||||
|
||||
/* Create RTCP socket. */
|
||||
status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &sock[1]);
|
||||
status = pj_sock_socket(af, pj_SOCK_DGRAM() | pj_SOCK_CLOEXEC(), 0, &sock[1]);
|
||||
if (status != PJ_SUCCESS) {
|
||||
pjsua_perror(THIS_FILE, "socket() error", status);
|
||||
pj_sock_close(sock[0]);
|
||||
|
|
|
@ -285,7 +285,8 @@ pjmedia_mp3_writer_port_create( pj_pool_t *pool,
|
|||
* We need the read mode because we'll modify the WAVE header once
|
||||
* the recording has completed.
|
||||
*/
|
||||
status = pj_file_open(pool, filename, PJ_O_WRONLY, &fport->fd);
|
||||
status = pj_file_open(pool, filename, PJ_O_WRONLY | PJ_O_CLOEXEC,
|
||||
&fport->fd);
|
||||
if (status != PJ_SUCCESS) {
|
||||
deinit_blade_dll();
|
||||
return status;
|
||||
|
|
Loading…
Reference in New Issue