128 lines
2.7 KiB
C
128 lines
2.7 KiB
C
|
// SPDX-License-Identifier: GPL-2.0-only
|
||
|
/*
|
||
|
* ionapp_export.c
|
||
|
*
|
||
|
* It is a user space utility to create and export android
|
||
|
* ion memory buffer fd to another process using unix domain socket as IPC.
|
||
|
* This acts like a server for ionapp_import(client).
|
||
|
* So, this server has to be started first before the client.
|
||
|
*
|
||
|
* Copyright (C) 2017 Pintu Kumar <pintu.ping@gmail.com>
|
||
|
*/
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <unistd.h>
|
||
|
#include <errno.h>
|
||
|
#include <sys/time.h>
|
||
|
#include "ionutils.h"
|
||
|
#include "ipcsocket.h"
|
||
|
|
||
|
|
||
|
void print_usage(int argc, char *argv[])
|
||
|
{
|
||
|
printf("Usage: %s [-h <help>] [-i <heap id>] [-s <size in bytes>]\n",
|
||
|
argv[0]);
|
||
|
}
|
||
|
|
||
|
int main(int argc, char *argv[])
|
||
|
{
|
||
|
int opt, ret, status, heapid;
|
||
|
int sockfd, client_fd, shared_fd;
|
||
|
unsigned char *map_buf;
|
||
|
unsigned long map_len, heap_type, heap_size, flags;
|
||
|
struct ion_buffer_info info;
|
||
|
struct socket_info skinfo;
|
||
|
|
||
|
if (argc < 2) {
|
||
|
print_usage(argc, argv);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
heap_size = 0;
|
||
|
flags = 0;
|
||
|
heap_type = ION_HEAP_TYPE_SYSTEM;
|
||
|
|
||
|
while ((opt = getopt(argc, argv, "hi:s:")) != -1) {
|
||
|
switch (opt) {
|
||
|
case 'h':
|
||
|
print_usage(argc, argv);
|
||
|
exit(0);
|
||
|
break;
|
||
|
case 'i':
|
||
|
heapid = atoi(optarg);
|
||
|
switch (heapid) {
|
||
|
case 0:
|
||
|
heap_type = ION_HEAP_TYPE_SYSTEM;
|
||
|
break;
|
||
|
case 1:
|
||
|
heap_type = ION_HEAP_TYPE_SYSTEM_CONTIG;
|
||
|
break;
|
||
|
default:
|
||
|
printf("ERROR: heap type not supported\n");
|
||
|
exit(1);
|
||
|
}
|
||
|
break;
|
||
|
case 's':
|
||
|
heap_size = atoi(optarg);
|
||
|
break;
|
||
|
default:
|
||
|
print_usage(argc, argv);
|
||
|
exit(1);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (heap_size <= 0) {
|
||
|
printf("heap_size cannot be 0\n");
|
||
|
print_usage(argc, argv);
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
printf("heap_type: %ld, heap_size: %ld\n", heap_type, heap_size);
|
||
|
info.heap_type = heap_type;
|
||
|
info.heap_size = heap_size;
|
||
|
info.flag_type = flags;
|
||
|
|
||
|
/* This is server: open the socket connection first */
|
||
|
/* Here; 1 indicates server or exporter */
|
||
|
status = opensocket(&sockfd, SOCKET_NAME, 1);
|
||
|
if (status < 0) {
|
||
|
fprintf(stderr, "<%s>: Failed opensocket.\n", __func__);
|
||
|
goto err_socket;
|
||
|
}
|
||
|
skinfo.sockfd = sockfd;
|
||
|
|
||
|
ret = ion_export_buffer_fd(&info);
|
||
|
if (ret < 0) {
|
||
|
fprintf(stderr, "FAILED: ion_get_buffer_fd\n");
|
||
|
goto err_export;
|
||
|
}
|
||
|
client_fd = info.ionfd;
|
||
|
shared_fd = info.buffd;
|
||
|
map_buf = info.buffer;
|
||
|
map_len = info.buflen;
|
||
|
write_buffer(map_buf, map_len);
|
||
|
|
||
|
/* share ion buf fd with other user process */
|
||
|
printf("Sharing fd: %d, Client fd: %d\n", shared_fd, client_fd);
|
||
|
skinfo.datafd = shared_fd;
|
||
|
skinfo.buflen = map_len;
|
||
|
|
||
|
ret = socket_send_fd(&skinfo);
|
||
|
if (ret < 0) {
|
||
|
fprintf(stderr, "FAILED: socket_send_fd\n");
|
||
|
goto err_send;
|
||
|
}
|
||
|
|
||
|
err_send:
|
||
|
err_export:
|
||
|
ion_close_buffer_fd(&info);
|
||
|
|
||
|
err_socket:
|
||
|
closesocket(sockfd, SOCKET_NAME);
|
||
|
|
||
|
return 0;
|
||
|
}
|