Instantly share code, notes, and snippets.

Embed
What would you like to do?
Termux に移植された libandroid-shmem.so を Debian noroot 環境に再移植するための差分ファイル

Termux に移植された libandroid-shmem.so を Debian noroot 環境に再移植するための差分ファイル

概要

この差分ファイルは、Debian noroot 環境 の作者である pelya 氏によって作成された、 共有メモリ関連の標準 C ライブラリ関数を /dev/ashmem によってエミュレートする Debian noroot 環境のための動的ライブラリである libandroid-shmem.sotermux の開発コミュニティTermux 環境に対応するよう移植したものを、再度 Debian noroot 環境上で動作するように修正した差分ファイルです。

pelya 氏による libandroid-shmem.so と異なり、 termux の開発コミュニティによる libandroid-shmem.so は、関数 shmget(2) の第一引数 keyIPC_PRIVATE 以外の値を指定出来るために、 termux の開発コミュニティによる libandroid-shmem.so の導入によって Debian noroot 環境上で動作する各種ソフトウェアが正常かつ安定に動作することが可能となります。

差分ファイルの適用とソースコードのコンパイル

まず、 termux の開発コミュニティによる libandroid-shmem.sogithub 版若しくは v0.2 版を以下の URL から入手し、 tarball の場合は適当なディレクトリに展開します。

そして、入手したソースコードが置かれているディレクトリに、以下のようにして、差分ファイル libandroid-shmem-termux-0.2_3-fix.diff を適用して通常通りに make コマンドによってコンパイルすると、動的ライブラリ libandroid-shmem-termux.so が生成されます。

 $ patch -p1 < /path/to/diff/libandroid-shmem-termux-0.2_3-fix.diff
 (ここに、 /path/to/diff は、 libandroid-shmem-termux-0.2_3-fix.diff が置かれているディレクトリのパス名)
 $ make ... (オプションを適宜設定すること。)

この動的ファイルを使用するには、まず最初に生成された動的ライブラリを Debian noroot 環境のルートディレクトリにインストールします。

 # install -v -m 0755 libandroid-shmem-termux.so /

次に、 Debian noroot 環境 の初期化ファイルである /proot.sh において、環境変数 LD_PRELOAD が定義されている行を以下のように修正します。

# LD_PRELOAD="... /libandroid-shmem.so ..."
LD_PRELOAD="... /libandroid-shmem-termux.so ..."    # /libandroid-shmem.so を /libandroid-shmem-termux.so に修正。

初期化ファイル /proot.sh の修正後は、 Debian noroot 環境を再起動して設定を有効にします。

libandroid-shmem-termux.so で使用する環境変数

ここに、本差分ファイルを適用して生成した動的ライブラリ libandroid-shmem-termux.so において使用する環境変数について述べます。

LIBANDROID_SHMEM_QUIET

環境変数 LIBANDROID_SHMEM_QUIET の値を 1 に設定すると、動的ライブラリ libandroid-shmem-termux.sostderr に出力するデバッグ用のログの出力を抑止します。

LIBANDROID_SHMEM_DISABLE

環境変数 LIBANDROID_SHMEM_DISABLE の値を 1 に設定すると、共有メモリ関連の標準ライブラリ関数である shmget(2), shmat(2), shmdt(2), shmctl(2) を一時的に無効化します。一部のソフトウェアについて、この動的ライブラリの為に動作が不安定になる場合は、この環境変数の設定を試みて下さい。

謝辞

まず最初に、 Debian noroot 環境及びそれに伴う libandroid-shmem.so を開発した pelya 氏に心より感謝致します。また、 libandroid-shmem.so の機能を強化して Termux 環境に移植した termux の開発コミュニティに心より感謝致します。

そして、 Debian noroot 環境及び Termux 環境に関わる全ての人々に心より感謝致します。

追記

2017/09/06 現在の追記

libandroid-shmem.so のデバッグ用ログ出力の変更に伴い、差分ファイルを修正しました。以降は、差分ファイルは libandroid-shmem-termux-0.2_1-fix.diff を適用して下さい。

2018/11/09 現在の追記

libandroid-shmem.so の一部動作の不具合を修正しました。以降は、差分ファイルは libandroid-shmem-termux-0.2_2-fix.diff を適用して下さい。

2018/12/13 現在の追記

クロスコンパイル環境で生成した libandroid-shmem.so の動作の不具合を修正しました。以降は、差分ファイルは libandroid-shmem-termux-0.2_3-fix.diff を適用して下さい。

これに伴い、差分ファイル libandroid-shmem-termux-0.2_1-fix.diff, libandroid-shmem-termux-0.2_2-fix.diff を削除致しました。どうか御了承下さい。

diff --git a/LICENSE b/LICENSE
index e741c3e..bb94806 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,5 +1,6 @@
Copyright (c) 2013, Sergii Pylypenko
Copyright (c) 2017, Fredrik Fornwall
+Copyright (c) 2018, NAKATSUKA, Yukitaka (mailto:zool@zool.jpn.org)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
diff --git a/Makefile b/Makefile
index 4082546..6d401e4 100644
--- a/Makefile
+++ b/Makefile
@@ -1,13 +1,30 @@
-CFLAGS += -fpic -shared -std=c11 -Wall -Wextra -Wl,--version-script=exports.txt
+CC = gcc
+STRIP = strip
-libandroid-shmem.so: shmem.c shm.h
- $(CC) $(CFLAGS) $(LDFLAGS) shmem.c -llog -o $@
+LIBANDROID_SHMEM_SO = libandroid-shmem.so
+TYPE = debian-noroot
-install: libandroid-shmem.so shm.h
- install -D libandroid-shmem.so $(PREFIX)/lib/libandroid-shmem.so
+CFLAGS += -fPIC -shared -std=gnu99 -Wall -Wextra -Wl,--version-script=exports.txt
+LDFLAGS +=
+
+ifeq ($(TYPE), debian-noroot)
+LIBANDROID_SHMEM_SO = libandroid-shmem-termux.so
+CFLAGS += -DDEBIAN_NOROOT
+LDFLAGS += -lc -lpthread
+else
+LIBANDROID_SHMEM_SO = libandroid-shmem.so
+LDFLAGS += -llog
+endif
+
+$(LIBANDROID_SHMEM_SO): shmem.c shm.h
+ $(CC) $(CFLAGS) shmem.c -o $@ $(LDFLAGS)
+ $(STRIP) $@
+
+install: $(LIBANDROID_SHMEM_SO) shm.h
+ install -D $(LIBANDROID_SHMEM_SO) $(PREFIX)/lib/$(LIBANDROID_SHMEM_SO)
install -D shm.h $(PREFIX)/include/sys/shm.h
clean:
- rm -f libandroid-shmem.so
+ rm -f libandroid-shmem.so libandroid-shmem-termux.so
.PHONY: install
diff --git a/README.md b/README.md
index 475cf3e..18cf6a2 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,73 @@
+# libandroid-shmem-termux.so -- Termux の開発コミュニティよって移植された libandroid-shmem.so を Debian noroot 環境に再移植した動的ライブラリ
+
+## 概要
+
+動的ライブラリ ```libandroid-shmem-termux.so``` は、 [Debian noroot 環境][DBNR] の作者である [pelya 氏][PELY]によって作成された、 共有メモリ関連の標準ライブラリ関数を ```/dev/ashmem``` によってエミュレートする [Debian noroot 環境][DBNR]のための動的ライブラリである [libandroid-shmem.so][PSHM] について、 [Termux の開発コミュニティ][TMUX]が [Termux 環境に対応するように移植したもの][TSHM]を、更に [Debian noroot 環境][DBNR]上で動作するように再移植した動的ライブラリです。
+
+即ち、動的ライブラリ ```libandroid-shmem-termux.so``` は、 [Termux の開発コミュニティ][TMUX]によって作成された [Termux 環境に対応するよう移植した ```libandroid-shmem.so```][TSHM] に、 "[Termux に移植された ```libandroid-shmem.so``` を Debian noroot 環境に再移植するための差分ファイル][GST1]" を適用したものです。
+
+## ビルド及びインストール
+
+```libandroid-shmem-termux.so``` のビルドには通常の make を使用します。先ずは、カレントディレクトリを Makefile が置かれているディレクトリに移動します。そして、以下の通りに make コマンドを実行します。
+
+```
+ $ cd /path/to/libandroid-shmem-termux # (ここに、/path/to/libandroid-shmem-termux は、 libandroid-shmem-termux.so のソースコードが置かれているディレクトリ)
+ $ make
+```
+
+ここで、以下のように ```make``` コマンドの引数に ```CC=...``` を指定すると、 ```libandroid-shmem-termux.so``` のビルドの際に使用する C コンパイラを指定できます。これは、クロスコンパイルを行う際に有用です。
+
+```
+ $ make CC=/path/to/x86_64-linux-gnu-gcc # (ここに、/path/to/x86_64-linux-gnu-gcc は、 libandroid-shmem-termux.so をビルドする際に使用する C コンパイラが置かれているパス)
+```
+
+そして、 ```libandroid-shmem-termux.so``` のビルドが完了した後は、以下のようにして、 ```libandroid-shmem-termux.so``` を [Debian noroot 環境][DBNR]のルートディレクトリにインストールします。
+
+```
+ $ sudo install -v -m 0755 libandroid-shmem-termux.so /
+```
+## Debian noroot 環境への設定方法
+
+```libandroid-shmem-termux.so``` 内のライブラリ関数を [Debian noroot 環境][DBNR]にて使用するには、以下のように、環境変数 ```LD_PRELOAD``` に ```libandroid-shmem-termux.so``` の置かれているパスを設定し、各種アプリケーションを起動します。
+
+即ち、 [Debian noroot 環境][DBNR] の初期化ファイルである ```/proot.sh``` において、環境変数 ```LD_PRELOAD``` が定義されている行を以下のように修正します。
+
+```
+# LD_PRELOAD="... /libandroid-shmem.so ..."
+LD_PRELOAD="... /libandroid-shmem-termux.so ..." # /libandroid-shmem.so を /libandroid-shmem-termux.so に修正。
+```
+初期化ファイル ```/proot.sh``` の修正後は、 [Debian noroot 環境][DBNR]を再起動して設定を有効にします。
+
+## libandroid-shmem-termux.so で使用する環境変数
+
+ここに、本差分ファイルを適用して生成した動的ライブラリ ```libandroid-shmem-termux.so``` において使用する環境変数について述べます。
+
+### ```LIBANDROID_SHMEM_QUIET```
+
+環境変数 ```LIBANDROID_SHMEM_QUIET``` の値を 1 に設定すると、動的ライブラリ ```libandroid-shmem-termux.so``` が ```stderr``` に出力するデバッグ用のログの出力を抑止します。
+
+### ```LIBANDROID_SHMEM_DISABLE```
+
+環境変数 ```LIBANDROID_SHMEM_DISABLE``` の値を 1 に設定すると、共有メモリ関連の標準ライブラリ関数である ```shmget(), shmat(), shmdt(), shmctl()``` を一時的に無効化します。一部のソフトウェアについて、この動的ライブラリの為に動作が不安定になる場合は、この環境変数の設定を試みて下さい。
+
+## 謝辞
+
+まず最初に、 [Debian noroot 環境][DBNR]及びそれに伴う ```libandroid-shmem.so``` を開発した [pelya 氏][PELY]に心より感謝致します。また、 ```libandroid-shmem.so``` の機能を強化して Termux 環境に移植した [termux の開発コミュニティの関係各位][TMUX]に心より感謝致します。
+
+そして、 [Debian noroot 環境][DBNR]及び [Termux 環境][TMUX]に関わる全ての人々に心より感謝致します。
+
+## 配布条件
+
+本リポジトリは、 [pelya 氏][PELY]によって作成された、 共有メモリ関連の標準ライブラリ関数を ```/dev/ashmem``` によってエミュレートする [Debian noroot 環境][DBNR]のための動的ライブラリである [libandroid-shmem.so][PSHM] を基に、 [Termux の開発コミュニティ][TMUX]が [Termux 環境に対応するように移植したもの][TSHM]を、更に [Z.OOL. (mailto:zool@zool.jpn.org)][ZOOL] によって [Debian noroot 環境][DBNR]上で動作するように再移植したものです。
+
+従って、本リポジトリ及び本リポジトリによって生成される動的ライブラリ ```libandroid-shmem-terux.so``` は、 [pelya 氏][PELY]と [Termux の開発コミュニティの関係各位][TMUX]及び [Z.OOL. (mailto:zool@zool.jpn.org)][ZOOL] が著作権を有し、 [Termux の開発コミュニティによる ```libandroid-shmem.so```][TSHM] と同様に [BSD 3-Clause License][BSD3] に基づいて配布されるものとします。詳細については、本リポジトリに同梱する ```LICENSE``` を参照して下さい。
+
+## 追記
+
+下記に、 [Termux の開発コミュニティによる ```libandroid-shmem.so```][TSHM] の README.md の原文を示します。
+
+----
+
libandroid-shmem
================
System V shared memory (shmget, shmat, shmdt and shmctl) emulation on Android using ashmem for use in [Termux](https://termux.com/).
@@ -9,3 +79,16 @@ Based on previous work in https://github.com/pelya/android-shmem.
Hacking
=======
The project can be developed on Android devices using Termux. Clone the repo and run `make` in the `tests/` folder after editing the library or test cases.
+
+<!-- 外部リンク一覧 -->
+
+[DBNR]:https://play.google.com/store/apps/details?id=com.cuntubuntu&hl=ja
+[ANDR]:https://www.android.com/intl/ja_jp/
+[DEBI]:https://www.debian.org/index.ja.html
+[PELY]:https://github.com/pelya
+[TMUX]:https://termux.com/
+[PSHM]:https://github.com/pelya/android-shmem
+[TSHM]:https://github.com/termux/libandroid-shmem
+[GST1]:https://gist.github.com/z80oolong/247dbbb0a7d83a1dea98de2939327432
+[ZOOL]:http://zool.jpn.org/
+[BSD3]:https://opensource.org/licenses/BSD-3-Clause
diff --git a/linux/ashmem.h b/linux/ashmem.h
new file mode 100644
index 0000000..9f537ac
--- /dev/null
+++ b/linux/ashmem.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+
+#ifdef DEBIAN_NOROOT
+#ifndef _LINUX_ASHMEM_H
+#define _LINUX_ASHMEM_H
+
+#include <linux/limits.h>
+#include <linux/ioctl.h>
+#include <stdint.h>
+
+#define ASHMEM_NAME_LEN 256
+
+#define ASHMEM_NAME_DEF "dev/ashmem"
+
+#define ASHMEM_NOT_PURGED 0
+#define ASHMEM_WAS_PURGED 1
+
+#define ASHMEM_IS_UNPINNED 0
+#define ASHMEM_IS_PINNED 1
+
+struct ashmem_pin {
+ uint32_t offset;
+ uint32_t len;
+};
+
+#define __ASHMEMIOC 0x77
+
+#define ASHMEM_SET_NAME _IOW(__ASHMEMIOC, 1, char[ASHMEM_NAME_LEN])
+#define ASHMEM_GET_NAME _IOR(__ASHMEMIOC, 2, char[ASHMEM_NAME_LEN])
+#define ASHMEM_SET_SIZE _IOW(__ASHMEMIOC, 3, size_t)
+#define ASHMEM_GET_SIZE _IO(__ASHMEMIOC, 4)
+#define ASHMEM_SET_PROT_MASK _IOW(__ASHMEMIOC, 5, unsigned long)
+#define ASHMEM_GET_PROT_MASK _IO(__ASHMEMIOC, 6)
+#define ASHMEM_PIN _IOW(__ASHMEMIOC, 7, struct ashmem_pin)
+#define ASHMEM_UNPIN _IOW(__ASHMEMIOC, 8, struct ashmem_pin)
+#define ASHMEM_GET_PIN_STATUS _IO(__ASHMEMIOC, 9)
+#define ASHMEM_PURGE_ALL_CACHES _IO(__ASHMEMIOC, 10)
+
+#endif
+#endif /* DEBIAN_NOROOT */
diff --git a/shm.h b/shm.h
index f780a28..56600d1 100644
--- a/shm.h
+++ b/shm.h
@@ -11,6 +11,12 @@ __BEGIN_DECLS
# define shmid_ds shmid64_ds
#endif
+#ifdef DEBIAN_NOROOT
+typedef __key_t key_t;
+#define shmid_ds shmid64_ds
+#define ipc_perm ipc64_perm
+#endif
+
/* Shared memory control operations. */
extern int shmctl(int shmid, int cmd, struct shmid_ds* buf);
diff --git a/shmem.c b/shmem.c
index d474535..923ebb5 100644
--- a/shmem.c
+++ b/shmem.c
@@ -1,4 +1,8 @@
+#ifdef DEBIAN_NOROOT
+#define _GNU_SOURCE
+#else
#include <android/log.h>
+#endif
#include <errno.h>
#include <pthread.h>
#include <stdbool.h>
@@ -10,13 +14,26 @@
#include <sys/un.h>
#include <unistd.h>
#include <paths.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdarg.h>
#define __u32 uint32_t
+#ifdef DEBIAN_NOROOT
+#include "linux/ashmem.h"
+#else
#include <linux/ashmem.h>
+#endif
#include "shm.h"
+#ifdef DEBIAN_NOROOT
+#define DBG(fmt, ...) debug_message("[shmem] " fmt "\n", __VA_ARGS__)
+#else
#define DBG(...) __android_log_print(ANDROID_LOG_INFO, "shmem", __VA_ARGS__)
+#endif
#define ASHV_KEY_SYMLINK_PATH _PATH_TMP "ashv_key_%d"
#define ANDROID_SHMEM_SOCKNAME "/dev/shm/%08x"
#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
@@ -45,6 +62,42 @@ static int ashv_local_socket_id = 0;
static int ashv_pid_setup = 0;
static pthread_t ashv_listening_thread_id = 0;
+#ifdef DEBIAN_NOROOT
+static void debug_message(const char *format, ...)
+{
+ static int verbose = -1;
+ va_list ap;
+
+ if (verbose < 0) {
+ const char *quiet_env = (const char *)getenv("LIBANDROID_SHMEM_QUIET");
+ if ((quiet_env == NULL) || strncmp(quiet_env, "1", 1)) {
+ verbose = 1;
+ } else {
+ verbose = 0;
+ }
+ } else if (verbose) {
+ va_start(ap, format);
+ (void)vfprintf(stderr, format, ap);
+ va_end(ap);
+ }
+}
+
+static int shmem_disabled(void)
+{
+ static int disabled = -1;
+
+ if (disabled < 0) {
+ const char *disable_env = (const char *)getenv("LIBANDROID_SHMEM_DISABLE");
+ if ((disable_env == NULL) || strncmp(disable_env, "1", 1)) {
+ disabled = 0;
+ } else {
+ disabled = 1;
+ }
+ }
+ return disabled;
+}
+#endif
+
static int ancil_send_fd(int sock, int fd)
{
char nothing = '!';
@@ -127,11 +180,15 @@ static int ashmem_create_region(char const* name, size_t size)
if (fd < 0) return fd;
char name_buffer[ASHMEM_NAME_LEN] = {0};
- strncpy(name_buffer, name, sizeof(name_buffer));
- name_buffer[sizeof(name_buffer)-1] = 0;
-
- int ret = ioctl(fd, ASHMEM_SET_NAME, name_buffer);
- if (ret < 0) goto error;
+ DBG("%s: name `%s` size %d", __PRETTY_FUNCTION__, name, size);
+ int ret;
+ if(name) {
+ strncpy(name_buffer, name, sizeof(name_buffer));
+ name_buffer[sizeof(name_buffer)-1] = 0;
+
+ ret = ioctl(fd, ASHMEM_SET_NAME, name_buffer);
+ if (ret < 0) goto error;
+ }
ret = ioctl(fd, ASHMEM_SET_SIZE, size);
if (ret < 0) goto error;
@@ -176,9 +233,13 @@ static int ashv_socket_id_from_shmid(int shmid)
static int ashv_find_local_index(int shmid)
{
- for (size_t i = 0; i < shmem_amount; i++)
- if (shmem[i].id == shmid)
+ for (size_t i = 0; i < shmem_amount; i++) {
+ if (shmem[i].id == shmid) {
+ //DBG ("%s: index of shmid %08x is %d", __PRETTY_FUNCTION__, shmid, i);
return i;
+ }
+ }
+ DBG ("%s: cannot find shmid %x", __PRETTY_FUNCTION__, shmid);
return -1;
}
@@ -189,7 +250,7 @@ static void* ashv_thread_function(void* arg)
struct sockaddr_un addr;
socklen_t len = sizeof(addr);
int sendsock;
- //DBG("%s: thread started", __PRETTY_FUNCTION__);
+ DBG("%s: thread started", __PRETTY_FUNCTION__);
while ((sendsock = accept(sock, (struct sockaddr *)&addr, &len)) != -1) {
int shmid;
if (recv(sendsock, &shmid, sizeof(shmid), 0) != sizeof(shmid)) {
@@ -197,15 +258,20 @@ static void* ashv_thread_function(void* arg)
close(sendsock);
continue;
}
+ if (shmid < 0x10000) {
+ shmid = ashv_shmid_from_counter(shmid);
+ }
+ DBG("%s: recv shmid %08x", __PRETTY_FUNCTION__, shmid);
pthread_mutex_lock(&mutex);
int idx = ashv_find_local_index(shmid);
if (idx != -1) {
- if (write(sendsock, &shmem[idx].key, sizeof(key_t)) != sizeof(key_t)) {
- DBG("%s: ERROR: write failed: %s", __PRETTY_FUNCTION__, strerror(errno));
- }
if (ancil_send_fd(sendsock, shmem[idx].descriptor) != 0) {
DBG("%s: ERROR: ancil_send_fd() failed: %s", __PRETTY_FUNCTION__, strerror(errno));
}
+ if (send(sendsock, &shmem[idx].key, sizeof(key_t), 0) != sizeof(key_t)) {
+ DBG("%s: ERROR: send() returned not %zu bytes: %s", __PRETTY_FUNCTION__, sizeof(key_t), strerror(errno));
+ }
+ DBG("%s: send FD %d key %08x", __PRETTY_FUNCTION__, shmem[idx].descriptor, shmem[idx].key);
} else {
DBG("%s: ERROR: cannot find shmid 0x%x", __PRETTY_FUNCTION__, shmid);
}
@@ -227,6 +293,7 @@ static void android_shmem_delete(int idx)
static int ashv_read_remote_segment(int shmid)
{
struct sockaddr_un addr;
+ DBG ("%s: call shmid = %08x", __PRETTY_FUNCTION__, shmid);
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
sprintf(&addr.sun_path[1], ANDROID_SHMEM_SOCKNAME, ashv_socket_id_from_shmid(shmid));
@@ -242,26 +309,27 @@ static int ashv_read_remote_segment(int shmid)
close(recvsock);
return -1;
}
-
if (send(recvsock, &shmid, sizeof(shmid), 0) != sizeof(shmid)) {
DBG ("%s: send() failed on socket %s: %s", __PRETTY_FUNCTION__, addr.sun_path + 1, strerror(errno));
close(recvsock);
return -1;
}
- key_t key;
- if (read(recvsock, &key, sizeof(key_t)) != sizeof(key_t)) {
- DBG("%s: ERROR: failed read", __PRETTY_FUNCTION__);
+ int descriptor = ancil_recv_fd(recvsock);
+ if (descriptor < 0) {
+ DBG("%s: ERROR: ancil_recv_fd() failed on socket %s: %s", __PRETTY_FUNCTION__, addr.sun_path + 1, strerror(errno));
close(recvsock);
return -1;
}
- int descriptor = ancil_recv_fd(recvsock);
- if (descriptor < 0) {
- DBG("%s: ERROR: ancil_recv_fd() failed on socket %s: %s", __PRETTY_FUNCTION__, addr.sun_path + 1, strerror(errno));
+ key_t key;
+ if (recv(recvsock, &key, sizeof(key_t), 0) != sizeof(key_t)) {
+ DBG("%s: ERROR: recv() returned not %zu bytes: %s", __PRETTY_FUNCTION__, sizeof(key_t), strerror(errno));
close(recvsock);
return -1;
}
+
+ DBG("%s: recv FD %d key %08x", __PRETTY_FUNCTION__, descriptor, key);
close(recvsock);
int size = ashmem_get_size_region(descriptor);
@@ -279,12 +347,20 @@ static int ashv_read_remote_segment(int shmid)
shmem[idx].addr = NULL;
shmem[idx].markedForDeletion = false;
shmem[idx].key = key;
+ DBG ("%s: created new remote shmem ID %d shmid %x FD %d size %zu", __PRETTY_FUNCTION__, idx, shmid, shmem[idx].descriptor, shmem[idx].size);
return idx;
}
/* Get shared memory area identifier. */
int shmget(key_t key, size_t size, int flags)
{
+ if (shmem_disabled()) {
+ DBG ("%s: function %s() is disabled.", __PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
+ errno = EACCES;
+ return -1;
+ }
+
+ DBG ("%s: key %08x size %zu flags 0%o (flags are ignored)", __PRETTY_FUNCTION__, key, size, flags);
(void) flags;
ashv_check_pid();
@@ -308,7 +384,10 @@ int shmget(key_t key, size_t size, int flags)
ashv_local_socket_id = (getpid() + i) & 0xffff;
sprintf(&addr.sun_path[1], ANDROID_SHMEM_SOCKNAME, ashv_local_socket_id);
len = sizeof(addr.sun_family) + strlen(&addr.sun_path[1]) + 1;
- if (bind(sock, (struct sockaddr *)&addr, len) != 0) continue;
+ if (bind(sock, (struct sockaddr *)&addr, len) != 0) {
+ DBG ("%s: cannot bind UNIX socket %s: %s, trying next one, len %d", __PRETTY_FUNCTION__, &addr.sun_path[1], strerror(errno), len);
+ continue;
+ }
DBG("%s: bound UNIX socket %s in pid=%d", __PRETTY_FUNCTION__, addr.sun_path + 1, getpid());
break;
}
@@ -333,6 +412,7 @@ int shmget(key_t key, size_t size, int flags)
pthread_mutex_lock(&mutex);
char symlink_path[256];
if (key != IPC_PRIVATE) {
+ DBG ("%s: key = %08x (is not IPC_PRIVATE)", __PRETTY_FUNCTION__, key);
// (1) Check if symlink exists telling us where to connect.
// (2) If so, try to connect and open.
// (3) If connected and opened, done. If connection refused
@@ -367,9 +447,10 @@ int shmget(key_t key, size_t size, int flags)
}
if (symlink(num_buffer, symlink_path) == 0) break;
}
+ } else {
+ DBG ("%s: key = %08x (is IPC_PRIVATE)", __PRETTY_FUNCTION__, key);
}
-
int idx = shmem_amount;
char buf[256];
sprintf(buf, ANDROID_SHMEM_SOCKNAME "-%d", ashv_local_socket_id, idx);
@@ -396,7 +477,7 @@ int shmget(key_t key, size_t size, int flags)
pthread_mutex_unlock (&mutex);
return -1;
}
- //DBG("%s: ID %d shmid %x FD %d size %zu", __PRETTY_FUNCTION__, idx, shmid, shmem[idx].descriptor, shmem[idx].size);
+ DBG("%s: ID %d shmid %x FD %d size %zu", __PRETTY_FUNCTION__, idx, shmid, shmem[idx].descriptor, shmem[idx].size);
/*
status = ashmem_set_prot_region (shmem[idx].descriptor, 0666);
if (status < 0) {
@@ -425,20 +506,28 @@ int shmget(key_t key, size_t size, int flags)
/* Attach shared memory segment. */
void* shmat(int shmid, void const* shmaddr, int shmflg)
{
+ if (shmem_disabled()) {
+ DBG ("%s: function %s() is disabled.", __PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
+ errno = EACCES;
+ return NULL;
+ }
+
ashv_check_pid();
int socket_id = ashv_socket_id_from_shmid(shmid);
void *addr;
+ DBG ("%s: shmid %08x shmaddr %p shmflg %d", __PRETTY_FUNCTION__, shmid, shmaddr, shmflg);
+
pthread_mutex_lock(&mutex);
int idx = ashv_find_local_index(shmid);
- if (idx == -1 && socket_id != ashv_local_socket_id) {
+ if ((idx == -1) && (socket_id != ashv_local_socket_id)) {
idx = ashv_read_remote_segment(shmid);
}
if (idx == -1) {
- DBG ("%s: shmid %x does not exist", __PRETTY_FUNCTION__, shmid);
+ DBG ("%s: shmid %08x does not exist", __PRETTY_FUNCTION__, shmid);
pthread_mutex_unlock(&mutex);
errno = EINVAL;
return (void*) -1;
@@ -447,7 +536,7 @@ void* shmat(int shmid, void const* shmaddr, int shmflg)
if (shmem[idx].addr == NULL) {
shmem[idx].addr = mmap((void*) shmaddr, shmem[idx].size, PROT_READ | (shmflg == 0 ? PROT_WRITE : 0), MAP_SHARED, shmem[idx].descriptor, 0);
if (shmem[idx].addr == MAP_FAILED) {
- DBG ("%s: mmap() failed for ID %x FD %d: %s", __PRETTY_FUNCTION__, idx, shmem[idx].descriptor, strerror(errno));
+ DBG ("%s: mmap() failed for ID %d FD %d: %s", __PRETTY_FUNCTION__, idx, shmem[idx].descriptor, strerror(errno));
shmem[idx].addr = NULL;
}
}
@@ -461,17 +550,25 @@ void* shmat(int shmid, void const* shmaddr, int shmflg)
/* Detach shared memory segment. */
int shmdt(void const* shmaddr)
{
+ if (shmem_disabled()) {
+ DBG ("%s: function %s() is disabled.", __PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
+ errno = EINVAL;
+ return -1;
+ }
+
ashv_check_pid();
+ DBG ("%s: shmaddr %p", __PRETTY_FUNCTION__, shmaddr);
+
pthread_mutex_lock(&mutex);
for (size_t i = 0; i < shmem_amount; i++) {
if (shmem[i].addr == shmaddr) {
if (munmap(shmem[i].addr, shmem[i].size) != 0) {
- DBG("%s: munmap %p failed", __PRETTY_FUNCTION__, shmaddr);
+ DBG("%s: unmap %p failed", __PRETTY_FUNCTION__, shmaddr);
}
shmem[i].addr = NULL;
DBG("%s: unmapped addr %p for FD %d ID %zu shmid %x", __PRETTY_FUNCTION__, shmaddr, shmem[i].descriptor, i, shmem[i].id);
- if (shmem[i].markedForDeletion || ashv_socket_id_from_shmid(shmem[i].id) != ashv_local_socket_id) {
+ if (shmem[i].markedForDeletion || (ashv_socket_id_from_shmid(shmem[i].id) != ashv_local_socket_id)) {
DBG ("%s: deleting shmid %x", __PRETTY_FUNCTION__, shmem[i].id);
android_shmem_delete(i);
}
@@ -489,6 +586,12 @@ int shmdt(void const* shmaddr)
/* Shared memory control operation. */
int shmctl(int shmid, int cmd, struct shmid_ds *buf)
{
+ if (shmem_disabled()) {
+ DBG ("%s: function %s() is disabled.", __PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
+ errno = EACCES;
+ return -1;
+ }
+
ashv_check_pid();
if (cmd == IPC_RMID) {
@lordbryan

This comment has been minimized.

Copy link

lordbryan commented Oct 24, 2017

Hi, just want thanks, you really saved me a lot of trouble. I have been trying to get shm to work in a chrooted Linux container, but i have been running into some sort of permissions [ failure to access private resources ] when using pelya's version . But it seems like the changes the termux team made , made it work without troubles. You will have to use google translate to read this.

@z80oolong

This comment has been minimized.

Copy link
Owner

z80oolong commented Feb 22, 2018

I'm sorry my response to your comment has been delayed so much. I sincerely thank you for using this patch file. I am glad that this patch file is useful for you.

@Anonymous1p

This comment has been minimized.

Copy link

Anonymous1p commented Sep 21, 2018

how can i use it in gnuroot debian plz tell me

@z80oolong

This comment has been minimized.

Copy link
Owner

z80oolong commented Sep 27, 2018

Thank you very much for your comment. In order to use libandroid-shmem-termux.so created with my diff file in Gnuroot Debian, you need to specify the path name of libandroid-shmem-termux.so in the environment variable LD_PRELOAD as follows.

  $ /usr/bin/env LD_PRELOAD="/libandroid-shmem-termux.so" linux_command

For details, please see the following web page by Mr. pelya -- https://github.com/pelya/android-shmem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment