1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * ionapp_export.c
4 *
5 * It is a user space utility to create and export android
6 * ion memory buffer fd to another process using unix domain socket as IPC.
7 * This acts like a server for ionapp_import(client).
8 * So, this server has to be started first before the client.
9 *
10 * Copyright (C) 2017 Pintu Kumar <pintu.ping@gmail.com>
11 */
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <unistd.h>
17 #include <errno.h>
18 #include <sys/time.h>
19 #include "ionutils.h"
20 #include "ipcsocket.h"
21
22
print_usage(int argc,char * argv[])23 void print_usage(int argc, char *argv[])
24 {
25 printf("Usage: %s [-h <help>] [-i <heap id>] [-s <size in bytes>]\n",
26 argv[0]);
27 }
28
main(int argc,char * argv[])29 int main(int argc, char *argv[])
30 {
31 int opt, ret, status, heapid;
32 int sockfd, client_fd, shared_fd;
33 unsigned char *map_buf;
34 unsigned long map_len, heap_type, heap_size, flags;
35 struct ion_buffer_info info;
36 struct socket_info skinfo;
37
38 if (argc < 2) {
39 print_usage(argc, argv);
40 return -1;
41 }
42
43 heap_size = 0;
44 flags = 0;
45 heap_type = ION_HEAP_TYPE_SYSTEM;
46
47 while ((opt = getopt(argc, argv, "hi:s:")) != -1) {
48 switch (opt) {
49 case 'h':
50 print_usage(argc, argv);
51 exit(0);
52 break;
53 case 'i':
54 heapid = atoi(optarg);
55 switch (heapid) {
56 case 0:
57 heap_type = ION_HEAP_TYPE_SYSTEM;
58 break;
59 case 1:
60 heap_type = ION_HEAP_TYPE_SYSTEM_CONTIG;
61 break;
62 default:
63 printf("ERROR: heap type not supported\n");
64 exit(1);
65 }
66 break;
67 case 's':
68 heap_size = atoi(optarg);
69 break;
70 default:
71 print_usage(argc, argv);
72 exit(1);
73 break;
74 }
75 }
76
77 if (heap_size <= 0) {
78 printf("heap_size cannot be 0\n");
79 print_usage(argc, argv);
80 exit(1);
81 }
82
83 printf("heap_type: %ld, heap_size: %ld\n", heap_type, heap_size);
84 info.heap_type = heap_type;
85 info.heap_size = heap_size;
86 info.flag_type = flags;
87
88 /* This is server: open the socket connection first */
89 /* Here; 1 indicates server or exporter */
90 status = opensocket(&sockfd, SOCKET_NAME, 1);
91 if (status < 0) {
92 fprintf(stderr, "<%s>: Failed opensocket.\n", __func__);
93 goto err_socket;
94 }
95 skinfo.sockfd = sockfd;
96
97 ret = ion_export_buffer_fd(&info);
98 if (ret < 0) {
99 fprintf(stderr, "FAILED: ion_get_buffer_fd\n");
100 goto err_export;
101 }
102 client_fd = info.ionfd;
103 shared_fd = info.buffd;
104 map_buf = info.buffer;
105 map_len = info.buflen;
106 write_buffer(map_buf, map_len);
107
108 /* share ion buf fd with other user process */
109 printf("Sharing fd: %d, Client fd: %d\n", shared_fd, client_fd);
110 skinfo.datafd = shared_fd;
111 skinfo.buflen = map_len;
112
113 ret = socket_send_fd(&skinfo);
114 if (ret < 0) {
115 fprintf(stderr, "FAILED: socket_send_fd\n");
116 goto err_send;
117 }
118
119 err_send:
120 err_export:
121 ion_close_buffer_fd(&info);
122
123 err_socket:
124 closesocket(sockfd, SOCKET_NAME);
125
126 return 0;
127 }
128