I/O channels fixes 2016/01/20 v1
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABCAAGBQJWn3AjAAoJEL6G67QVEE/fzYIP/3KS3d5CF2345IlzL9dTizyP 1OzOXGHIRpg8CJ9gixfGuyS1jUlPTAe7ov2VizmmeJoocbSZDohbXMWFrGbfPwFj KAPDBeYwEdmdkV4Tc0ZYu2hqKxOtQgKPBErzkNugIz26qkp1M82mieUcO3dIol2Y vela8AePSK4vv/STDgwAWRudb04XtLvV6I+bTD5MwPF+84QZHEXm2iAj7O6ESGah q42kigp7frnozHQQBA5yg3QLTYLD+PM9M9qFqG1S+1OtsaFUDPphRhherm7A2g54 UsuH/ctThOEIB4JrC7+XGRkJIi9ZZoMZDpwCwS9OOmAb1CS/jvyAOaxbBnmIrLyJ F2y3bJBFITvqcXUfqCFcl7a6vWfKy1Gw9EcTysGKdY5EfHp4ESoWQGCQH5PE6I9N cE7xzn4rIr+dnKDsg5qlUR9ObbHEuv7iKWe7OSpGti+EBE4fXt+AASWyZiC0bFST dvC9jjlNzQC8DIvIEjtcSwLr9hOKBbGT6S4Qsqt4ddHzliXAx2wyPshDbz879ql2 eD4tODX0QVyYxnrc3YfwqsneSFG2AZytF/wqi1FFroiYCvYBianfAxKrtx91786W ZwNqTTanO8uDEEgYwjpRMMpC1LnjrwCCEbL6XG9oxuUFzKjeAC9s+pfx7P5NKVDC JwiLP41N7GgjsExO7xjv =eFG+ -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/berrange/tags/pull-io-next-2016-01-20-1' into staging I/O channels fixes 2016/01/20 v1 # gpg: Signature made Wed 20 Jan 2016 11:31:47 GMT using RSA key ID 15104FDF # gpg: Good signature from "Daniel P. Berrange <dan@berrange.com>" # gpg: aka "Daniel P. Berrange <berrange@redhat.com>" * remotes/berrange/tags/pull-io-next-2016-01-20-1: io: use memset instead of { 0 } for initializing array io: fix description of @errp parameter initialization io: some fixes to handling of /dev/null when running commands io: increment counter when killing off subcommand io: fix sign of errno value passed to error report Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
3ed0b659ca
@ -51,7 +51,7 @@ struct QIOChannelCommand {
|
||||
* @writefd: the FD connected to the command's stdin
|
||||
* @readfd: the FD connected to the command's stdout
|
||||
* @pid: the PID of the running child command
|
||||
* @errp: pointer to an uninitialized error object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Create a channel for performing I/O with the
|
||||
* previously spawned command identified by @pid.
|
||||
@ -75,7 +75,7 @@ qio_channel_command_new_pid(int writefd,
|
||||
* qio_channel_command_new_spawn:
|
||||
* @argv: the NULL terminated list of command arguments
|
||||
* @flags: the I/O mode, one of O_RDONLY, O_WRONLY, O_RDWR
|
||||
* @errp: pointer to an uninitialized error object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Create a channel for performing I/O with the
|
||||
* command to be spawned with arguments @argv.
|
||||
|
@ -67,7 +67,7 @@ qio_channel_socket_new(void);
|
||||
/**
|
||||
* qio_channel_socket_new_fd:
|
||||
* @fd: the socket file descriptor
|
||||
* @errp: pointer to an uninitialized error object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Create a channel for performing I/O on the socket
|
||||
* connection represented by the file descriptor @fd.
|
||||
@ -83,7 +83,7 @@ qio_channel_socket_new_fd(int fd,
|
||||
* qio_channel_socket_connect_sync:
|
||||
* @ioc: the socket channel object
|
||||
* @addr: the address to connect to
|
||||
* @errp: pointer to an uninitialized error object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Attempt to connect to the address @addr. This method
|
||||
* will run in the foreground so the caller will not regain
|
||||
@ -118,7 +118,7 @@ void qio_channel_socket_connect_async(QIOChannelSocket *ioc,
|
||||
* qio_channel_socket_listen_sync:
|
||||
* @ioc: the socket channel object
|
||||
* @addr: the address to listen to
|
||||
* @errp: pointer to an uninitialized error object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Attempt to listen to the address @addr. This method
|
||||
* will run in the foreground so the caller will not regain
|
||||
@ -154,7 +154,7 @@ void qio_channel_socket_listen_async(QIOChannelSocket *ioc,
|
||||
* @ioc: the socket channel object
|
||||
* @localAddr: the address to local bind address
|
||||
* @remoteAddr: the address to remote peer address
|
||||
* @errp: pointer to an uninitialized error object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Attempt to initialize a datagram socket bound to
|
||||
* @localAddr and communicating with peer @remoteAddr.
|
||||
@ -193,7 +193,7 @@ void qio_channel_socket_dgram_async(QIOChannelSocket *ioc,
|
||||
/**
|
||||
* qio_channel_socket_get_local_address:
|
||||
* @ioc: the socket channel object
|
||||
* @errp: pointer to an uninitialized error object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Get the string representation of the local socket
|
||||
* address. A pointer to the allocated address information
|
||||
@ -210,7 +210,7 @@ qio_channel_socket_get_local_address(QIOChannelSocket *ioc,
|
||||
/**
|
||||
* qio_channel_socket_get_remote_address:
|
||||
* @ioc: the socket channel object
|
||||
* @errp: pointer to an uninitialized error object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Get the string representation of the local socket
|
||||
* address. A pointer to the allocated address information
|
||||
@ -228,7 +228,7 @@ qio_channel_socket_get_remote_address(QIOChannelSocket *ioc,
|
||||
/**
|
||||
* qio_channel_socket_accept:
|
||||
* @ioc: the socket channel object
|
||||
* @errp: pointer to an uninitialized error object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* If the socket represents a server, then this accepts
|
||||
* a new client connection. The returned channel will
|
||||
|
@ -55,7 +55,7 @@ struct QIOChannelTLS {
|
||||
* @master: the underlying channel object
|
||||
* @creds: the credentials to use for TLS handshake
|
||||
* @aclname: the access control list for validating clients
|
||||
* @errp: pointer to an uninitialized error object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Create a new TLS channel that runs the server side of
|
||||
* a TLS session. The TLS session handshake will use the
|
||||
@ -85,7 +85,7 @@ qio_channel_tls_new_server(QIOChannel *master,
|
||||
* @master: the underlying channel object
|
||||
* @creds: the credentials to use for TLS handshake
|
||||
* @hostname: the user specified server hostname
|
||||
* @errp: pointer to an uninitialized error object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Create a new TLS channel that runs the client side of
|
||||
* a TLS session. The TLS session handshake will use the
|
||||
|
@ -152,7 +152,7 @@ bool qio_channel_has_feature(QIOChannel *ioc,
|
||||
* @niov: the length of the @iov array
|
||||
* @fds: pointer to an array that will received file handles
|
||||
* @nfds: pointer filled with number of elements in @fds on return
|
||||
* @errp: pointer to an uninitialized error object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Read data from the IO channel, storing it in the
|
||||
* memory regions referenced by @iov. Each element
|
||||
@ -198,7 +198,7 @@ ssize_t qio_channel_readv_full(QIOChannel *ioc,
|
||||
* @niov: the length of the @iov array
|
||||
* @fds: an array of file handles to send
|
||||
* @nfds: number of file handles in @fds
|
||||
* @errp: pointer to an uninitialized error object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Write data to the IO channel, reading it from the
|
||||
* memory regions referenced by @iov. Each element
|
||||
@ -237,7 +237,7 @@ ssize_t qio_channel_writev_full(QIOChannel *ioc,
|
||||
* @ioc: the channel object
|
||||
* @iov: the array of memory regions to read data into
|
||||
* @niov: the length of the @iov array
|
||||
* @errp: pointer to an uninitialized error object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Behaves as qio_channel_readv_full() but does not support
|
||||
* receiving of file handles.
|
||||
@ -252,7 +252,7 @@ ssize_t qio_channel_readv(QIOChannel *ioc,
|
||||
* @ioc: the channel object
|
||||
* @iov: the array of memory regions to write data from
|
||||
* @niov: the length of the @iov array
|
||||
* @errp: pointer to an uninitialized error object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Behaves as qio_channel_writev_full() but does not support
|
||||
* sending of file handles.
|
||||
@ -267,7 +267,7 @@ ssize_t qio_channel_writev(QIOChannel *ioc,
|
||||
* @ioc: the channel object
|
||||
* @buf: the memory region to read data into
|
||||
* @buflen: the length of @buf
|
||||
* @errp: pointer to an uninitialized error object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Behaves as qio_channel_readv_full() but does not support
|
||||
* receiving of file handles, and only supports reading into
|
||||
@ -283,7 +283,7 @@ ssize_t qio_channel_read(QIOChannel *ioc,
|
||||
* @ioc: the channel object
|
||||
* @buf: the memory regions to send data from
|
||||
* @buflen: the length of @buf
|
||||
* @errp: pointer to an uninitialized error object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Behaves as qio_channel_writev_full() but does not support
|
||||
* sending of file handles, and only supports writing from a
|
||||
@ -298,7 +298,7 @@ ssize_t qio_channel_write(QIOChannel *ioc,
|
||||
* qio_channel_set_blocking:
|
||||
* @ioc: the channel object
|
||||
* @enabled: the blocking flag state
|
||||
* @errp: pointer to an uninitialized error object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* If @enabled is true, then the channel is put into
|
||||
* blocking mode, otherwise it will be non-blocking.
|
||||
@ -314,7 +314,7 @@ int qio_channel_set_blocking(QIOChannel *ioc,
|
||||
/**
|
||||
* qio_channel_close:
|
||||
* @ioc: the channel object
|
||||
* @errp: pointer to an uninitialized error object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Close the channel, flushing any pending I/O
|
||||
*
|
||||
@ -327,7 +327,7 @@ int qio_channel_close(QIOChannel *ioc,
|
||||
* qio_channel_shutdown:
|
||||
* @ioc: the channel object
|
||||
* @how: the direction to shutdown
|
||||
* @errp: pointer to an uninitialized error object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Shutdowns transmission and/or receiving of data
|
||||
* without closing the underlying transport.
|
||||
@ -403,7 +403,7 @@ void qio_channel_set_cork(QIOChannel *ioc,
|
||||
* @ioc: the channel object
|
||||
* @offset: the position to seek to, relative to @whence
|
||||
* @whence: one of the (POSIX) SEEK_* constants listed below
|
||||
* @errp: pointer to an uninitialized error object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Moves the current I/O position within the channel
|
||||
* @ioc, to be @offset. The value of @offset is
|
||||
|
@ -66,7 +66,7 @@ qio_channel_command_new_spawn(const char *const argv[],
|
||||
|
||||
if (stdinnull || stdoutnull) {
|
||||
devnull = open("/dev/null", O_RDWR);
|
||||
if (!devnull) {
|
||||
if (devnull < 0) {
|
||||
error_setg_errno(errp, errno,
|
||||
"Unable to open /dev/null");
|
||||
goto error;
|
||||
@ -98,6 +98,9 @@ qio_channel_command_new_spawn(const char *const argv[],
|
||||
close(stdoutfd[0]);
|
||||
close(stdoutfd[1]);
|
||||
}
|
||||
if (devnull != -1) {
|
||||
close(devnull);
|
||||
}
|
||||
|
||||
execv(argv[0], (char * const *)argv);
|
||||
_exit(1);
|
||||
@ -117,6 +120,9 @@ qio_channel_command_new_spawn(const char *const argv[],
|
||||
return ioc;
|
||||
|
||||
error:
|
||||
if (devnull != -1) {
|
||||
close(devnull);
|
||||
}
|
||||
if (stdinfd[0] != -1) {
|
||||
close(stdinfd[0]);
|
||||
}
|
||||
@ -179,6 +185,7 @@ static int qio_channel_command_abort(QIOChannelCommand *ioc,
|
||||
(unsigned long long)ioc->pid);
|
||||
return -1;
|
||||
}
|
||||
step++;
|
||||
usleep(10 * 1000);
|
||||
goto rewait;
|
||||
}
|
||||
@ -201,12 +208,12 @@ static void qio_channel_command_finalize(Object *obj)
|
||||
QIOChannelCommand *ioc = QIO_CHANNEL_COMMAND(obj);
|
||||
if (ioc->readfd != -1) {
|
||||
close(ioc->readfd);
|
||||
ioc->readfd = -1;
|
||||
}
|
||||
if (ioc->writefd != -1) {
|
||||
if (ioc->writefd != -1 &&
|
||||
ioc->writefd != ioc->readfd) {
|
||||
close(ioc->writefd);
|
||||
ioc->writefd = -1;
|
||||
}
|
||||
ioc->writefd = ioc->readfd = -1;
|
||||
if (ioc->pid > 0) {
|
||||
#ifndef WIN32
|
||||
qio_channel_command_abort(ioc, NULL);
|
||||
@ -298,12 +305,16 @@ static int qio_channel_command_close(QIOChannel *ioc,
|
||||
/* We close FDs before killing, because that
|
||||
* gives a better chance of clean shutdown
|
||||
*/
|
||||
if (close(cioc->writefd) < 0) {
|
||||
if (cioc->readfd != -1 &&
|
||||
close(cioc->readfd) < 0) {
|
||||
rv = -1;
|
||||
}
|
||||
if (close(cioc->readfd) < 0) {
|
||||
if (cioc->writefd != -1 &&
|
||||
cioc->writefd != cioc->readfd &&
|
||||
close(cioc->writefd) < 0) {
|
||||
rv = -1;
|
||||
}
|
||||
cioc->writefd = cioc->readfd = -1;
|
||||
#ifndef WIN32
|
||||
if (qio_channel_command_abort(cioc, errp) < 0) {
|
||||
return -1;
|
||||
|
@ -449,6 +449,8 @@ static ssize_t qio_channel_socket_readv(QIOChannel *ioc,
|
||||
char control[CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS)];
|
||||
int sflags = 0;
|
||||
|
||||
memset(control, 0, CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS));
|
||||
|
||||
#ifdef MSG_CMSG_CLOEXEC
|
||||
sflags |= MSG_CMSG_CLOEXEC;
|
||||
#endif
|
||||
@ -493,16 +495,18 @@ static ssize_t qio_channel_socket_writev(QIOChannel *ioc,
|
||||
QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
|
||||
ssize_t ret;
|
||||
struct msghdr msg = { NULL, };
|
||||
char control[CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS)] = { 0 };
|
||||
char control[CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS)];
|
||||
size_t fdsize = sizeof(int) * nfds;
|
||||
struct cmsghdr *cmsg;
|
||||
|
||||
memset(control, 0, CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS));
|
||||
|
||||
msg.msg_iov = (struct iovec *)iov;
|
||||
msg.msg_iovlen = niov;
|
||||
|
||||
if (nfds) {
|
||||
if (nfds > SOCKET_MAX_FDS) {
|
||||
error_setg_errno(errp, -EINVAL,
|
||||
error_setg_errno(errp, EINVAL,
|
||||
"Only %d FDs can be sent, got %zu",
|
||||
SOCKET_MAX_FDS, nfds);
|
||||
return -1;
|
||||
|
Loading…
Reference in New Issue
Block a user