次のような書籍の勉強中なので、
その内容理解とSwiftからCを触ってみる練習のための自分用メモです。
以後、全て対話式にSwiftを動かしています。
$ swift
libcを使う(macOS)
// macOSの場合
import Darwin
// Linuxの場合
// import Glibc
PID, PPID
PID取得
let pid = getpid()
// -> pid: pid_t = 48846
別ウィンドウで取得したPIDのプロセスを確認
$ ps -p 48846
PID TTY TIME CMD
48846 ttys000 0:00.04 /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/repl_swift
対話式で起動しているので、repl_swift
が動いているよう
親プロセスのPID取得
let ppid = getppid()
// ppid: pid_t = 48847
同じく別ウィンドウで取得したPIDのプロセスを確認
$ ps -p 48847
PID TTY TIME CMD
48847 ttys000 0:00.11 /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/debugserver --native-regs --setsid --reverse-connect 127.0.0.1:59152
システムコール
man 2 getpid
# man 2 getppid も同じ
補足
PIDだけならSwiftのFoundationで可能
import Foundation
ProcessInfo().processIdentifier
// -> $R12: Int32 = 48846
getpid()
の返り値はpid_t
, ProcessInfo().processIdentifier
の返り値はInt32
。
ProcessInfo().processIdentifier == getpid()
// $R16: Bool = true
比較できるので、pid_t
はInt32のエイリアスなのかな?
ファイルディスクリプタ
標準入力、標準出力、標準エラー(stdin, stdout, stderr)
標準入力、標準出力、標準エラーのファイルディスクリプタはそれぞれ、 0, 1, 2 と決まっているので、それを確認する。
libcを読み込んだので、stdin, stdout, stderrが使える。
- 標準入力のファイルディスクリプタ
let stdinFileNo = fileno(stdin)
// -> stdinFileNo: Int32 = 0
- 標準出力のファイルディスクリプタ
let stdoutFileNo = fileno(stdout)
// -> stdoutFileNo: Int32 = 1
- 標準出力のファイルディスクリプタ
let stderrFileNo = fileno(stderr)
// -> stderrFileNo: Int32 = 2
ちなみに、stdin, stdout, stderrの型はUnsafeMutablePointer<FILE>
。
type(of: stdin)
// -> $R2: UnsafeMutablePointer<FILE>.Type = UnsafeMutablePointer<__sFILE>
また、Cライブラリでは、 STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO というマクロが用意されているとのこと。
// libcを読み込んでいるので、これもSwiftから呼べる
STDIN_FILENO
// -> $R9: Int32 = 0
STDOUT_FILENO
// -> $R10: Int32 = 1
STDERR_FILENO
// -> $R11: Int32 = 2
ファイルを開いてファイルディスクリプタの確認
let fd = open("test.txt", O_RDONLY)
// -> fd: Int32 = 5
// ファイルディスクリプタ 5 が返ってきた
let fd2 = open("test2.txt", O_RDONLY)
// -> fd2: Int32 = 6
// ファイルディスクリプタ 6 が返ってきた
close(fd)
// -> $R7: Int32 = 0
// ファイルを閉じる
// ファイルディスクリプタ 5 が再利用可能になった
let fd3 = open("test3.txt", O_RDONLY)
// -> fd: Int32 = 5
// 先ほどファイルを閉じたことで再利用可能になったファイルディスクリプタ 5 が使われた
fileno()
関数は Swift Package Manager でも使ってるっぽい。
システムコール
man 2 open
man 2 close
とりあえずここまで。