s->open_flags |= O_DSYNC;
s->fd = -1;
- fd = open(filename, s->open_flags, 0644);
+ fd = qemu_open(filename, s->open_flags, 0644);
if (fd < 0) {
ret = -errno;
if (ret == -EROFS)
pipe2=yes
fi
+# check if accept4 is there
+accept4=no
+cat > $TMPC << EOF
+#define _GNU_SOURCE
+#include <sys/socket.h>
+#include <stddef.h>
+
+int main(void)
+{
+ accept4(0, NULL, NULL, SOCK_CLOEXEC);
+ return 0;
+}
+EOF
+if compile_prog "" "" ; then
+ accept4=yes
+fi
+
# check if tee/splice is there. vmsplice was added same time.
splice=no
cat > $TMPC << EOF
if test "$pipe2" = "yes" ; then
echo "CONFIG_PIPE2=y" >> $config_host_mak
fi
+if test "$accept4" = "yes" ; then
+ echo "CONFIG_ACCEPT4=y" >> $config_host_mak
+fi
if test "$splice" = "yes" ; then
echo "CONFIG_SPLICE=y" >> $config_host_mak
fi
perror("accept");
return;
} else if (fd >= 0) {
+#ifndef _WIN32
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
+#endif
break;
}
}
perror("socket");
return -1;
}
+#ifndef _WIN32
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
+#endif
/* allow fast reuse */
val = 1;
s->slots[i].slot = i;
s->vmfd = -1;
- s->fd = open("/dev/kvm", O_RDWR);
+ s->fd = qemu_open("/dev/kvm", O_RDWR);
if (s->fd == -1) {
fprintf(stderr, "Could not access KVM kernel module: %m\n");
ret = -errno;
s->state = MIG_STATE_ACTIVE;
s->mon = NULL;
s->bandwidth_limit = bandwidth_limit;
- s->fd = socket(PF_INET, SOCK_STREAM, 0);
+ s->fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
if (s->fd == -1) {
qemu_free(s);
return NULL;
int c, ret;
do {
- c = accept(s, (struct sockaddr *)&addr, &addrlen);
+ c = qemu_accept(s, (struct sockaddr *)&addr, &addrlen);
} while (c == -1 && socket_error() == EINTR);
dprintf("accepted migration\n");
return -EINVAL;
}
- s = socket(PF_INET, SOCK_STREAM, 0);
+ s = qemu_socket(PF_INET, SOCK_STREAM, 0);
if (s == -1)
return -socket_error();
s->state = MIG_STATE_ACTIVE;
s->mon = NULL;
s->bandwidth_limit = bandwidth_limit;
- s->fd = socket(PF_UNIX, SOCK_STREAM, 0);
+ s->fd = qemu_socket(PF_UNIX, SOCK_STREAM, 0);
if (s->fd < 0) {
dprintf("Unable to open socket");
goto err_after_alloc;
int c, ret;
do {
- c = accept(s, (struct sockaddr *)&addr, &addrlen);
+ c = qemu_accept(s, (struct sockaddr *)&addr, &addrlen);
} while (c == -1 && socket_error() == EINTR);
dprintf("accepted migration\n");
dprintf("Attempting to start an incoming migration\n");
- sock = socket(PF_UNIX, SOCK_STREAM, 0);
+ sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
fprintf(stderr, "Could not open unix socket: %s\n", strerror(errno));
return -EINVAL;
return -1;
}
- fd = socket(PF_INET, SOCK_DGRAM, 0);
+ fd = qemu_socket(PF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
perror("socket(PF_INET, SOCK_DGRAM)");
return -1;
for(;;) {
len = sizeof(saddr);
- fd = accept(s->fd, (struct sockaddr *)&saddr, &len);
+ fd = qemu_accept(s->fd, (struct sockaddr *)&saddr, &len);
if (fd < 0 && errno != EINTR) {
return;
} else if (fd >= 0) {
s = qemu_mallocz(sizeof(NetSocketListenState));
- fd = socket(PF_INET, SOCK_STREAM, 0);
+ fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
if (fd < 0) {
perror("socket");
return -1;
if (parse_host_port(&saddr, host_str) < 0)
return -1;
- fd = socket(PF_INET, SOCK_STREAM, 0);
+ fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
if (fd < 0) {
perror("socket");
return -1;
#ifndef _WIN32
int fd;
- fd = open(filename, O_RDWR | O_CREAT, 0600);
+ fd = qemu_open(filename, O_RDWR | O_CREAT, 0600);
if (fd == -1)
return -1;
ia->s_addr = addr;
return 1;
}
+
+void qemu_set_cloexec(int fd)
+{
+}
+
#else
+
void socket_set_nonblock(int fd)
{
int f;
f = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, f | O_NONBLOCK);
}
+
+void qemu_set_cloexec(int fd)
+{
+ int f;
+ f = fcntl(fd, F_GETFD);
+ fcntl(fd, F_SETFD, f | FD_CLOEXEC);
+}
+
+#endif
+
+/*
+ * Opens a file with FD_CLOEXEC set
+ */
+int qemu_open(const char *name, int flags, ...)
+{
+ int ret;
+ int mode = 0;
+
+ if (flags & O_CREAT) {
+ va_list ap;
+
+ va_start(ap, flags);
+ mode = va_arg(ap, int);
+ va_end(ap);
+ }
+
+#ifdef O_CLOEXEC
+ ret = open(name, flags | O_CLOEXEC, mode);
+#else
+ ret = open(name, flags, mode);
+ if (ret >= 0) {
+ qemu_set_cloexec(ret);
+ }
#endif
+
+ return ret;
+}
+
+#ifndef _WIN32
+/*
+ * Creates a pipe with FD_CLOEXEC set on both file descriptors
+ */
+int qemu_pipe(int pipefd[2])
+{
+ int ret;
+
+#ifdef CONFIG_PIPE2
+ ret = pipe2(pipefd, O_CLOEXEC);
+#else
+ ret = pipe(pipefd);
+ if (ret == 0) {
+ qemu_set_cloexec(pipefd[0]);
+ qemu_set_cloexec(pipefd[1]);
+ }
+#endif
+
+ return ret;
+}
+#endif
+
+/*
+ * Opens a socket with FD_CLOEXEC set
+ */
+int qemu_socket(int domain, int type, int protocol)
+{
+ int ret;
+
+#ifdef SOCK_CLOEXEC
+ ret = socket(domain, type | SOCK_CLOEXEC, protocol);
+#else
+ ret = socket(domain, type, protocol);
+ if (ret >= 0) {
+ qemu_set_cloexec(ret);
+ }
+#endif
+
+ return ret;
+}
+
+/*
+ * Accept a connection and set FD_CLOEXEC
+ */
+int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
+{
+ int ret;
+
+#ifdef CONFIG_ACCEPT4
+ ret = accept4(s, addr, addrlen, SOCK_CLOEXEC);
+#else
+ ret = accept(s, addr, addrlen);
+ if (ret >= 0) {
+ qemu_set_cloexec(ret);
+ }
+#endif
+
+ return ret;
+}
sigaction(SIGUSR2, &act, NULL);
s->first_aio = NULL;
- if (pipe(fds) == -1) {
+ if (qemu_pipe(fds) == -1) {
fprintf(stderr, "failed to create pipe\n");
return -1;
}
{
int fd_out;
- TFR(fd_out = open(qemu_opt_get(opts, "path"),
+ TFR(fd_out = qemu_open(qemu_opt_get(opts, "path"),
O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666));
if (fd_out < 0)
return NULL;
snprintf(filename_in, 256, "%s.in", filename);
snprintf(filename_out, 256, "%s.out", filename);
- TFR(fd_in = open(filename_in, O_RDWR | O_BINARY));
- TFR(fd_out = open(filename_out, O_RDWR | O_BINARY));
+ TFR(fd_in = qemu_open(filename_in, O_RDWR | O_BINARY));
+ TFR(fd_out = qemu_open(filename_out, O_RDWR | O_BINARY));
if (fd_in < 0 || fd_out < 0) {
if (fd_in >= 0)
close(fd_in);
len = sizeof(saddr);
addr = (struct sockaddr *)&saddr;
}
- fd = accept(s->listen_fd, addr, &len);
+ fd = qemu_accept(s->listen_fd, addr, &len);
if (fd < 0 && errno != EINTR) {
return;
} else if (fd >= 0) {
void qemu_mutex_lock_iothread(void);
void qemu_mutex_unlock_iothread(void);
+int qemu_open(const char *name, int flags, ...);
+void qemu_set_cloexec(int fd);
+
+#ifndef _WIN32
+int qemu_pipe(int pipefd[2]);
+#endif
+
/* Error handling. */
void QEMU_NORETURN hw_error(const char *fmt, ...)
getnameinfo((struct sockaddr*)e->ai_addr,e->ai_addrlen,
uaddr,INET6_ADDRSTRLEN,uport,32,
NI_NUMERICHOST | NI_NUMERICSERV);
- slisten = socket(e->ai_family, e->ai_socktype, e->ai_protocol);
+ slisten = qemu_socket(e->ai_family, e->ai_socktype, e->ai_protocol);
if (slisten < 0) {
fprintf(stderr,"%s: socket(%s): %s\n", __FUNCTION__,
inet_strfamily(e->ai_family), strerror(errno));
fprintf(stderr,"%s: getnameinfo: oops\n", __FUNCTION__);
continue;
}
- sock = socket(e->ai_family, e->ai_socktype, e->ai_protocol);
+ sock = qemu_socket(e->ai_family, e->ai_socktype, e->ai_protocol);
if (sock < 0) {
fprintf(stderr,"%s: socket(%s): %s\n", __FUNCTION__,
inet_strfamily(e->ai_family), strerror(errno));
}
/* create socket */
- sock = socket(peer->ai_family, peer->ai_socktype, peer->ai_protocol);
+ sock = qemu_socket(peer->ai_family, peer->ai_socktype, peer->ai_protocol);
if (sock < 0) {
fprintf(stderr,"%s: socket(%s): %s\n", __FUNCTION__,
inet_strfamily(peer->ai_family), strerror(errno));
const char *path = qemu_opt_get(opts, "path");
int sock, fd;
- sock = socket(PF_UNIX, SOCK_STREAM, 0);
+ sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
perror("socket(unix)");
return -1;
return -1;
}
- sock = socket(PF_UNIX, SOCK_STREAM, 0);
+ sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
perror("socket(unix)");
return -1;
#include "qemu-option.h"
/* misc helpers */
+int qemu_socket(int domain, int type, int protocol);
+int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
void socket_set_nonblock(int fd);
int send_all(int fd, const void *buf, int len1);
addr.sin_port = 0;
addr.sin_addr.s_addr = INADDR_ANY;
- if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0 ||
+ if ((s = qemu_socket(AF_INET, SOCK_STREAM, 0)) < 0 ||
bind(s, (struct sockaddr *)&addr, addrlen) < 0 ||
listen(s, 1) < 0) {
lprint("Error: inet socket: %s\n", strerror(errno));
* Connect to the socket
* XXX If any of these fail, we're in trouble!
*/
- s = socket(AF_INET, SOCK_STREAM, 0);
+ s = qemu_socket(AF_INET, SOCK_STREAM, 0);
addr.sin_addr = loopback_addr;
do {
ret = connect(s, (struct sockaddr *)&addr, addrlen);
#include "bootp.h"
#include "tftp.h"
+/* osdep.c */
+int qemu_socket(int domain, int type, int protocol);
+
+
struct Slirp {
QTAILQ_ENTRY(Slirp) entry;
addr.sin_addr.s_addr = haddr;
addr.sin_port = hport;
- if (((s = socket(AF_INET,SOCK_STREAM,0)) < 0) ||
+ if (((s = qemu_socket(AF_INET,SOCK_STREAM,0)) < 0) ||
(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) ||
(bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) ||
(listen(s,1) < 0)) {
DEBUG_CALL("tcp_fconnect");
DEBUG_ARG("so = %lx", (long )so);
- if( (ret=so->s=socket(AF_INET,SOCK_STREAM,0)) >= 0) {
+ if( (ret = so->s = qemu_socket(AF_INET,SOCK_STREAM,0)) >= 0) {
int opt, s=so->s;
struct sockaddr_in addr;
int
udp_attach(struct socket *so)
{
- if((so->s = socket(AF_INET,SOCK_DGRAM,0)) != -1) {
+ if((so->s = qemu_socket(AF_INET,SOCK_DGRAM,0)) != -1) {
so->so_expire = curtime + SO_EXPIRE;
insque(so, &so->slirp->udb);
}
if (!so) {
return NULL;
}
- so->s = socket(AF_INET,SOCK_DGRAM,0);
+ so->s = qemu_socket(AF_INET,SOCK_DGRAM,0);
so->so_expire = curtime + SO_EXPIRE;
insque(so, &slirp->udb);
struct hpet_info info;
int r, fd;
- fd = open("/dev/hpet", O_RDONLY);
+ fd = qemu_open("/dev/hpet", O_RDONLY);
if (fd < 0)
return -1;
int rtc_fd;
unsigned long current_rtc_freq = 0;
- TFR(rtc_fd = open("/dev/rtc", O_RDONLY));
+ TFR(rtc_fd = qemu_open("/dev/rtc", O_RDONLY));
if (rtc_fd < 0)
return -1;
ioctl(rtc_fd, RTC_IRQP_READ, ¤t_rtc_freq);
int err;
int fds[2];
- err = pipe(fds);
+ err = qemu_pipe(fds);
if (err == -1)
return -errno;
} else if (pid < 0)
exit(1);
+ close(fds[0]);
+ qemu_set_cloexec(fds[1]);
+
setsid();
pid = fork();
exit(1);
chdir("/");
- TFR(fd = open("/dev/null", O_RDWR));
+ TFR(fd = qemu_open("/dev/null", O_RDWR));
if (fd == -1)
exit(1);
}
/* Catch-up */
vga_hw_update();
- int csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
+ int csock = qemu_accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
if (csock != -1) {
vnc_connect(vs, csock);
}