2016-07-18 5 views
0

errnoにIは、Androidイオンの使用例を書かれている:アンドロイドイオン、ION_IOC_IMPORTリターン<0のIOCTL、= 9

父親プロセスがパイプを作成し、次に "/ devの/イオン" デバイス、ION_IOC_ALLOCのIOCTLを開き、ioctl of ION_IOC_MAPとmmapを呼び出し、最後にION_IOC_MAPによって返されたfdとパイプによる子プロセスの長さを渡しました。

子プロセスはパイプからfdとlengthを読み取り、読み取りはOKですが、ION_IOC_IMPORTを実行すると-1が返され、errnoは9で、perrorは「ファイル記述子が正しくありません」です。

2つのプロセスはrootユーザーであり、selinuxは許可されています。

父・プロセスのキーコード:

ion_fd = open("/dev/ion", O_RDONLY); 
if (ion_fd < 0) { 
    ALOGE("Failed to open ion device\n"); 
    return -EIO; 
} 

alloc_data.len = 0x1000; 
alloc_data.align = 0x1000; 
alloc_data.heap_id_mask = ION_HEAP(ION_SYSTEM_HEAP_ID); 
alloc_data.flags = ION_SECURE; 
rc = ioctl(ion_fd, ION_IOC_ALLOC, &alloc_data); 
if (rc) { 
    ALOGE("Failed to allocate uspace ion buffer\n"); 
    goto uimp_alloc_err; 
} 
fd_data.handle = alloc_data.handle; 
rc = ioctl(ion_fd, ION_IOC_MAP, &fd_data); 
if (rc < 0) { 
    ALOGE("unable to ion map buffer\n"); 
    goto uimp_map_err; 
} 
map_fd = fd_data.fd; 
addr = mmap(NULL, alloc_data.len, 
       PROT_READ | PROT_WRITE, 
       MAP_SHARED , map_fd, 0); 
if (!addr) { 
    ALOGE("mmap failed\n"); 
    rc = -EIO; 
    goto uimp_mmap_err; 
} 
write_pattern((unsigned long)addr, alloc_data.len); 
fd_data.handle = alloc_data.handle; 
rc = ioctl(ion_fd, ION_IOC_SHARE, &fd_data); 
if (rc < 0) { 
    ALOGE("unable to share ion buffer\n"); 
    goto uimp_share_err; 
} 

itoa(fd_data.fd, ubuf, sizeof(int) * 8); 
if (0 > sock_write(wr_fd, ubuf, sizeof(int) * 8)) 
    goto uimp_sock_err; 
itoa(alloc_data.len, ubuf, sizeof(int) * 8); 
if (0 > sock_write(wr_fd, ubuf, sizeof(int) * 8)) 
    goto uimp_sock_err; 

do { 
    tpid = wait(&child_status); 
} while (tpid != child_pid); 

子プロセスのキーコードは:

if (0 > sock_read(fd, cbuf, sizeof(int) * 8)) 
    return -EIO; 
fd_data.fd = atoi(cbuf); 
/* receive buf length */ 
if (0 > sock_read(fd, cbuf, sizeof(int) * 8)) 
    return -EIO; 
size = atoi(cbuf); 

ion_fd = open("/dev/ion", O_RDONLY); 
if (ion_fd < 0) { 
    rc = -EINVAL; 
    goto child_args_err; 
} 
rc = ioctl(ion_fd, ION_IOC_IMPORT, &fd_data); // it failed here 
if (rc) { 
    ALOGE("ION_IOC_IMPORT failed %d errno %d\n", rc, errno); 
    perror("ioctl"); 
    rc = -EIO; 
    goto child_imp_err; 
} 
addr = mmap(NULL, size, PROT_READ | PROT_WRITE, 
       MAP_SHARED, fd_data.fd, 0); 
if (!addr) { 
    perror("mmap"); 
    rc = -EIO; 
    goto child_mmap_err; 
} 

答えて

0

ファイルディスクリプタ(FDS)は、プロセスごとにあり、したがって、単に(簡単な整数である)のディスクリプタを渡すことによって、プロセス間で共有することはできません - あなたがエラーを取得している理由です。 Androidの場合、これを解決するには2つの方法があります: 1. Androidのバインダーを使用して、両方のプロセスがIInterfaceとそのすべてのジャズを継承するクラスを実現するようにします(例:https://github.com/gburca/BinderDemo参照)。しかし、私はfdをソケット経由で渡すと、fdを複製する手段を提供する良いol '形式のUnixを使うのが好きです。 SCM_RIGHTSという魔法の言葉を覚えておけば、たくさんの例が見つかります。