src: introduce a wrapper for the pipe2() system call

This hides the differences between Windows and UNIX,
and adds standard error reporting.

Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrangé 2020-01-24 15:21:00 +00:00
parent 4d61dd5abf
commit ab36f72947
4 changed files with 102 additions and 0 deletions

View File

@ -368,6 +368,7 @@ AC_CHECK_FUNCS_ONCE([\
newlocale \
posix_fallocate \
posix_memalign \
pipe2 \
prlimit \
sched_getaffinity \
sched_setscheduler \

View File

@ -3410,6 +3410,9 @@ virMemoryLimitTruncate;
virMemoryMaxValue;
virParseOwnershipIds;
virParseVersionString;
virPipe;
virPipeNonBlock;
virPipeQuiet;
virScaleInteger;
virSetBlocking;
virSetCloseExec;

View File

@ -1769,3 +1769,67 @@ char *virGetPassword(void)
return g_strdup(getpass(""));
#endif /* ! WIN32 */
}
static int
virPipeImpl(int fds[2], bool nonblock, bool errreport)
{
#ifdef HAVE_PIPE2
int flags = O_CLOEXEC;
if (nonblock)
flags |= O_NONBLOCK;
int rv = pipe2(fds, flags);
#else /* !HAVE_PIPE2 */
# ifdef WIN32
int rv = _pipe(fds, 4096, _O_BINARY);
# else /* !WIN32 */
int rv = pipe(fds);
# endif /* !WIN32 */
#endif /* !HAVE_PIPE2 */
if (rv < 0) {
if (errreport)
virReportSystemError(errno, "%s",
_("Unable to create pipes"));
return rv;
}
#ifndef HAVE_PIPE2
if (nonblock) {
if (virSetNonBlock(fds[0]) < 0 ||
virSetNonBlock(fds[1]) < 0) {
if (errreport)
virReportSystemError(errno, "%s",
_("Unable to set pipes to non-blocking"));
virReportSystemError(errno, "%s",
_("Unable to create pipes"));
VIR_FORCE_CLOSE(fds[0]);
VIR_FORCE_CLOSE(fds[1]);
return -1;
}
}
#endif /* !HAVE_PIPE2 */
return 0;
}
int
virPipe(int fds[2])
{
return virPipeImpl(fds, false, true);
}
int
virPipeQuiet(int fds[2])
{
return virPipeImpl(fds, false, false);
}
int
virPipeNonBlock(int fds[2])
{
return virPipeImpl(fds, true, true);
}

View File

@ -161,3 +161,37 @@ char *virHostGetDRMRenderNode(void) G_GNUC_NO_INLINE;
(((lvalue) = (rvalue)) != (rvalue))
char *virGetPassword(void);
/*
* virPipe:
*
* Open a pair of FDs which can be used to communicate
* with each other. The FDs will have O_CLOEXEC set.
* This will report a libvirt error on failure.
*
* Returns: -1 on error, 0 on success
*/
int virPipe(int fds[2]);
/*
* virPipeQuiet:
*
* Open a pair of FDs which can be used to communicate
* with each other. The FDs will have O_CLOEXEC set.
* This will set errno on failure.
*
* Returns: -1 on error, 0 on success
*/
int virPipeQuiet(int fds[2]);
/*
* virPipe:
*
* Open a pair of FDs which can be used to communicate
* with each other. The FDs will have O_CLOEXEC and
* O_NONBLOCK set.
* This will report a libvirt error on failure.
*
* Returns: -1 on error, 0 on success
*/
int virPipeNonBlock(int fds[2]);