aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2018-02-16 11:19:37 +0000
committerPeter Maydell <peter.maydell@linaro.org>2018-02-16 11:19:37 +0000
commit0402ca3c70356e09e694fece39256790ff7755f2 (patch)
treee60eaec9d9f13e2b70a4704e58ebf23378211888
parent5e5432b766c424a5d1e1b81315ce6ac1dc0fa3ed (diff)
parent6809df1df036840d41a0cc9ca77cc6a0214fb1b5 (diff)
Merge remote-tracking branch 'remotes/berrange/tags/qio-next-pull-request' into staging
# gpg: Signature made Thu 15 Feb 2018 17:50:22 GMT # gpg: using RSA key BE86EBB415104FDF # gpg: Good signature from "Daniel P. Berrange <dan@berrange.com>" # gpg: aka "Daniel P. Berrange <berrange@redhat.com>" # Primary key fingerprint: DAF3 A6FD B26B 6291 2D0E 8E3F BE86 EBB4 1510 4FDF * remotes/berrange/tags/qio-next-pull-request: allow to build with older sed io/channel-command: Do not kill the child process after closing the pipe io: Add /dev/fdset/ support to QIOChannelFile io: Don't call close multiple times in QIOChannelFile io: Fix QIOChannelFile when creating and opening read-write io/channel-websock: handle continuous reads without any data io: fix QIONetListener memory leak Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--Makefile3
-rw-r--r--include/io/channel-file.h2
-rw-r--r--io/channel-command.c12
-rw-r--r--io/channel-file.c11
-rw-r--r--io/channel-websock.c7
-rw-r--r--io/net-listener.c1
-rw-r--r--tests/test-io-channel-file.c29
7 files changed, 48 insertions, 17 deletions
diff --git a/Makefile b/Makefile
index b5a6d602b2..90e05ac409 100644
--- a/Makefile
+++ b/Makefile
@@ -256,8 +256,7 @@ GENERATED_FILES += $(KEYCODEMAP_FILES)
ui/input-keymap-%.c: $(KEYCODEMAP_GEN) $(KEYCODEMAP_CSV) $(SRC_PATH)/ui/Makefile.objs
$(call quiet-command,\
- src=$$(echo $@ | sed -E -e "s,^ui/input-keymap-(.+)-to-(.+)\.c$$,\1,") && \
- dst=$$(echo $@ | sed -E -e "s,^ui/input-keymap-(.+)-to-(.+)\.c$$,\2,") && \
+ stem=$* && src=$${stem%-to-*} dst=$${stem#*-to-} && \
test -e $(KEYCODEMAP_GEN) && \
$(PYTHON) $(KEYCODEMAP_GEN) \
--lang glib2 \
diff --git a/include/io/channel-file.h b/include/io/channel-file.h
index 79245f1183..ebfe54ec70 100644
--- a/include/io/channel-file.h
+++ b/include/io/channel-file.h
@@ -73,7 +73,7 @@ qio_channel_file_new_fd(int fd);
* qio_channel_file_new_path:
* @path: the file path
* @flags: the open flags (O_RDONLY|O_WRONLY|O_RDWR, etc)
- * @mode: the file creation mode if O_WRONLY is set in @flags
+ * @mode: the file creation mode if O_CREAT is set in @flags
* @errp: pointer to initialized error object
*
* Create a new IO channel object for a file represented
diff --git a/io/channel-command.c b/io/channel-command.c
index 319c5ed50c..3e7eb17eff 100644
--- a/io/channel-command.c
+++ b/io/channel-command.c
@@ -301,6 +301,9 @@ static int qio_channel_command_close(QIOChannel *ioc,
{
QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc);
int rv = 0;
+#ifndef WIN32
+ pid_t wp;
+#endif
/* We close FDs before killing, because that
* gives a better chance of clean shutdown
@@ -315,11 +318,18 @@ static int qio_channel_command_close(QIOChannel *ioc,
rv = -1;
}
cioc->writefd = cioc->readfd = -1;
+
#ifndef WIN32
- if (qio_channel_command_abort(cioc, errp) < 0) {
+ do {
+ wp = waitpid(cioc->pid, NULL, 0);
+ } while (wp == (pid_t)-1 && errno == EINTR);
+ if (wp == (pid_t)-1) {
+ error_setg_errno(errp, errno, "Failed to wait for pid %llu",
+ (unsigned long long)cioc->pid);
return -1;
}
#endif
+
if (rv < 0) {
error_setg_errno(errp, errno, "%s",
"Unable to close command");
diff --git a/io/channel-file.c b/io/channel-file.c
index b383273201..db948abc3e 100644
--- a/io/channel-file.c
+++ b/io/channel-file.c
@@ -50,11 +50,7 @@ qio_channel_file_new_path(const char *path,
ioc = QIO_CHANNEL_FILE(object_new(TYPE_QIO_CHANNEL_FILE));
- if (flags & O_WRONLY) {
- ioc->fd = open(path, flags, mode);
- } else {
- ioc->fd = open(path, flags);
- }
+ ioc->fd = qemu_open(path, flags, mode);
if (ioc->fd < 0) {
object_unref(OBJECT(ioc));
error_setg_errno(errp, errno,
@@ -78,7 +74,7 @@ static void qio_channel_file_finalize(Object *obj)
{
QIOChannelFile *ioc = QIO_CHANNEL_FILE(obj);
if (ioc->fd != -1) {
- close(ioc->fd);
+ qemu_close(ioc->fd);
ioc->fd = -1;
}
}
@@ -177,11 +173,12 @@ static int qio_channel_file_close(QIOChannel *ioc,
{
QIOChannelFile *fioc = QIO_CHANNEL_FILE(ioc);
- if (close(fioc->fd) < 0) {
+ if (qemu_close(fioc->fd) < 0) {
error_setg_errno(errp, errno,
"Unable to close file");
return -1;
}
+ fioc->fd = -1;
return 0;
}
diff --git a/io/channel-websock.c b/io/channel-websock.c
index 7fd6bb68ba..ec48a305f0 100644
--- a/io/channel-websock.c
+++ b/io/channel-websock.c
@@ -499,9 +499,12 @@ static int qio_channel_websock_handshake_read(QIOChannelWebsock *ioc,
error_setg(errp,
"End of headers not found in first 4096 bytes");
return 1;
- } else {
- return 0;
+ } else if (ret == 0) {
+ error_setg(errp,
+ "End of headers not found before connection closed");
+ return -1;
}
+ return 0;
}
*handshake_end = '\0';
diff --git a/io/net-listener.c b/io/net-listener.c
index 77a4e2831c..de38dfae99 100644
--- a/io/net-listener.c
+++ b/io/net-listener.c
@@ -234,6 +234,7 @@ QIOChannelSocket *qio_net_listener_wait_client(QIONetListener *listener)
for (i = 0; i < listener->nsioc; i++) {
g_source_unref(sources[i]);
}
+ g_free(sources);
g_main_loop_unref(loop);
g_main_context_unref(ctxt);
diff --git a/tests/test-io-channel-file.c b/tests/test-io-channel-file.c
index 6bfede6bb7..2e94f638f2 100644
--- a/tests/test-io-channel-file.c
+++ b/tests/test-io-channel-file.c
@@ -24,16 +24,21 @@
#include "io-channel-helpers.h"
#include "qapi/error.h"
-static void test_io_channel_file(void)
+#define TEST_FILE "tests/test-io-channel-file.txt"
+#define TEST_MASK 0600
+
+static void test_io_channel_file_helper(int flags)
{
QIOChannel *src, *dst;
QIOChannelTest *test;
+ struct stat st;
+ mode_t mask;
+ int ret;
-#define TEST_FILE "tests/test-io-channel-file.txt"
unlink(TEST_FILE);
src = QIO_CHANNEL(qio_channel_file_new_path(
TEST_FILE,
- O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0600,
+ flags, TEST_MASK,
&error_abort));
dst = QIO_CHANNEL(qio_channel_file_new_path(
TEST_FILE,
@@ -45,18 +50,33 @@ static void test_io_channel_file(void)
qio_channel_test_run_reader(test, dst);
qio_channel_test_validate(test);
+ /* Check that the requested mode took effect. */
+ mask = umask(0);
+ umask(mask);
+ ret = stat(TEST_FILE, &st);
+ g_assert_cmpint(ret, >, -1);
+ g_assert_cmpuint(TEST_MASK & ~mask, ==, st.st_mode & 0777);
+
unlink(TEST_FILE);
object_unref(OBJECT(src));
object_unref(OBJECT(dst));
}
+static void test_io_channel_file(void)
+{
+ test_io_channel_file_helper(O_WRONLY | O_CREAT | O_TRUNC | O_BINARY);
+}
+
+static void test_io_channel_file_rdwr(void)
+{
+ test_io_channel_file_helper(O_RDWR | O_CREAT | O_TRUNC | O_BINARY);
+}
static void test_io_channel_fd(void)
{
QIOChannel *ioc;
int fd = -1;
-#define TEST_FILE "tests/test-io-channel-file.txt"
fd = open(TEST_FILE, O_CREAT | O_TRUNC | O_WRONLY, 0600);
g_assert_cmpint(fd, >, -1);
@@ -114,6 +134,7 @@ int main(int argc, char **argv)
g_test_init(&argc, &argv, NULL);
g_test_add_func("/io/channel/file", test_io_channel_file);
+ g_test_add_func("/io/channel/file/rdwr", test_io_channel_file_rdwr);
g_test_add_func("/io/channel/file/fd", test_io_channel_fd);
#ifndef _WIN32
g_test_add_func("/io/channel/pipe/sync", test_io_channel_pipe_sync);