Files
xen/tools/libs/foreignmemory/core.c
T
Ian Campbell bd1c1ea440 tools/libs/foreignmemory: Support err == NULL to map.
The existing xc_map_foreign_bulk-like interface encourages callers to
miss error checking for partial failure (by forgetting to scan the err
array).

Add support for passing err==NULL which behaves in a
xc_map_foreign_pages-like manner and returns a global error for any
failure.

While documenting this also clarify the overall behaviour and the
behaviour with err!=NULL.

With this the compat wrapper of xc_map_foreign_pages() can be
simplified.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
2016-01-22 12:24:18 +00:00

116 lines
2.7 KiB
C

/*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include "private.h"
xenforeignmemory_handle *xenforeignmemory_open(xentoollog_logger *logger,
unsigned open_flags)
{
xenforeignmemory_handle *fmem = malloc(sizeof(*fmem));
int rc;
if (!fmem) return NULL;
fmem->logger = logger;
fmem->logger_tofree = NULL;
if (!fmem->logger) {
fmem->logger = fmem->logger_tofree =
(xentoollog_logger*)
xtl_createlogger_stdiostream(stderr, XTL_PROGRESS, 0);
if (!fmem->logger) goto err;
}
rc = osdep_xenforeignmemory_open(fmem);
if ( rc < 0 ) goto err;
return fmem;
err:
osdep_xenforeignmemory_close(fmem);
xtl_logger_destroy(fmem->logger_tofree);
free(fmem);
return NULL;
}
int xenforeignmemory_close(xenforeignmemory_handle *fmem)
{
int rc;
if ( !fmem )
return 0;
rc = osdep_xenforeignmemory_close(fmem);
xtl_logger_destroy(fmem->logger_tofree);
free(fmem);
return rc;
}
void *xenforeignmemory_map(xenforeignmemory_handle *fmem,
uint32_t dom, int prot,
const xen_pfn_t *arr, int *err, size_t num)
{
void *ret;
int *err_to_free = NULL;
if ( err == NULL )
err = err_to_free = malloc(num * sizeof(int));
if ( err == NULL )
return NULL;
ret = osdep_xenforeignmemory_map(fmem, dom, prot, arr, err, num);
if ( ret == 0 && err_to_free )
{
int i;
for ( i = 0 ; i < num ; i++ )
{
if ( err[i] )
{
errno = -err[i];
(void)osdep_xenforeignmemory_unmap(fmem, ret, num);
ret = NULL;
break;
}
}
}
free(err_to_free);
return ret;
}
int xenforeignmemory_unmap(xenforeignmemory_handle *fmem,
void *addr, size_t num)
{
return osdep_xenforeignmemory_unmap(fmem, addr, num);
}
/*
* Local variables:
* mode: C
* c-file-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/