6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

iOSアプリに実行バイナリを同梱して実行できるのか試した

Last updated at Posted at 2016-06-26

やりたかったこと

Unix環境を想定したライブラリをiOSプログラミングで利用したい場合は静的ライブラリとして取り込むのが普通です。しかし、ライブラリ形式になっていないツールを輸入するのにわざわざライブラリ化するのは手間ですよね。

そこで、*.ipaファイルの中にARM用の実行バイナリを入れて、iOSアプリ内からposix_spawn(2)で起動できるのかを確認してみました。アプリと同梱であればAppleのレギュレーション(アプリ外にある実行可能コードの実行禁止)に違反しないのでは?という期待もありました。

結論

jailbreakしていないiOS実機に実行バイナリを持ち込んで起動することはできない。fork(2)posix_spawn(2)など別プロセスを起動するようなシステムコールはiOSサンドボックス内で利用できないと考えられる。

テスト環境

Xcode 7.3.1 + iOS 9.3.2 (iPhone6s)

試したこと

輸入対象としてbannerコマンド(配布元:Cedar Solutions - Utilities)を使いました。標準出力にバナーを出すコマンドです。

$ banner foo

#######  #######  #######
#        #     #  #     #
#        #     #  #     #
#####    #     #  #     #
#        #     #  #     #
#        #     #  #     #
#        #######  #######

まずMach-Oの実行バイナリを作ります。「Autotools管理のライブラリをiOS向けにスマートにビルドする方法」で紹介したように、./configure; makeすればiOS/ARM用の実行バイナリを作ることができます。

今回はARM用だけでなくiOSシミュレータ用にx86用も作ってlipoで合体させました。

$ file banner
banner: Mach-O universal binary with 5 architectures
banner (for architecture i386):	Mach-O executable i386
banner (for architecture x86_64):	Mach-O 64-bit executable x86_64
banner (for architecture armv7):	Mach-O executable arm
banner (for architecture armv7s):	Mach-O executable arm
banner (for architecture arm64):	Mach-O 64-bit executable

これをXcodeから「Add Files to "プロジェクト名"...」でプロジェクトに取り込みます。取り込んだファイルへのパスは次のように取得できます。

    let path = NSBundle.mainBundle().pathForResource("banner",ofType:"")

これをposix_spawn(2)で起動してみましょう。下記コード中のCStringArrayは記事「SwiftでCのchar **をうまく扱う」で紹介したものです。

    let argv = CStringArray([path, "foo", nil])
    let status = posix_spawnp(nil, argv.pointers[0], nil, nil, argv.pointers, nil)
    if (status != 0) {
        print("posix_spawn: " + String.fromCString(strerror(status))! + " (status=\(Int(status)))")
    }

試してみると、iOSシミュレータ上とiOS実機とで異なるエラーが帰ってきました。

iOSシミュレータでは次のエラーが帰ってきます。

posix_spawn: Permission denied (status=13)

これは対象のパスに実行可能ビットが立っていないことによるエラーです。実行バイナリをキャッシュディレクトリ以下にコピーすればchmod(2)で実行可能ビットが立てられるので、無事バイナリを起動できるようになります。

一方、iOS実機では下記エラーが帰ってきます。

posix_spawn: Operation not permitted (status=1)

このエラーは手元のposix_spawn(2)のマニュアルに載っていませんので、別のレイヤでのエラーだと予想できます。おそらくiOSのサンドボックス環境でかかっている制約でしょうから、ちょっとやそっとの工夫じゃ動きそうにないですね。

おわりに

というわけで、UnixツールをiOSに移植したい場合は静的ライブラリ化するしかない、という当たり前の結論になりました。実験後に検索してみたところ、fork(2)がiOSではOperation not permittedを返すという話題が見つかりました。自分の検索力が低かったということで残念です。

参考URL

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?