Skip to content

Instantly share code, notes, and snippets.

@JJTech0130
Last active February 24, 2024 14:25
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JJTech0130/d153c491283311a28ee962bf725ec2fb to your computer and use it in GitHub Desktop.
Save JJTech0130/d153c491283311a28ee962bf725ec2fb to your computer and use it in GitHub Desktop.
Pure Swift raw syscall to retrieve the name of a semaphore
import Foundation
struct psem_fdinfo {
struct proc_fileinfo {
var fi_openflags: UInt32
var fi_status: UInt32
var fi_offset: Int64
var fi_type: Int32
var fi_guardflags: UInt32
}
struct psem_info {
struct vinfo_stat {
var vst_dev: UInt32
var vst_mode: UInt16
var vst_nlink: UInt16
var vst_ino: UInt64
var vst_uid: UInt32
var vst_gid: UInt32
var vst_atime: Int64
var vst_atimensec: Int64
var vst_mtime: Int64
var vst_mtimensec: Int64
var vst_ctime: Int64
var vst_ctimensec: Int64
var vst_birthtime: Int64
var vst_birthtimensec: Int64
var vst_size: Int64
var vst_blocks: Int64
var vst_blksize: Int32
var vst_flags: UInt32
var vst_gen: UInt32
var vst_rdev: UInt32
var vst_qspare: (Int64, Int64)
}
var psem_stat: vinfo_stat
// normally there would be a 1024 byte array here, but fixed sized arrays don't exist in Swift
}
var pfi: proc_fileinfo
var psem: psem_info
}
let PROC_INFO_CALL_PIDFDINFO: UInt64 = 0x3
let PROC_PIDFDSEMINFO: UInt64 = 4
func sem_info(_ sem: Semaphore) -> (psem_fdinfo, String) {
let syscall_ptr = dlsym(dlopen(nil, RTLD_NOW), "syscall")
let syscall_sem_info = unsafeBitCast(syscall_ptr, to: (@convention(c)(
Int32, // syscall #
UInt64, UInt64, UInt64, UInt64, UInt64, UInt64, UInt64, // filler for x1-x7
UInt64, // call #
UInt64, // pid
UInt64, // flavor
UInt64, // arg (semaphore)
UInt64, // buffer
UInt64 // buffer_size
) -> Int32).self)
let sem_info_size = 1184
let sem_info_buf = UnsafeMutableRawPointer.allocate(byteCount: sem_info_size, alignment: 1)
let s_ret = syscall_sem_info(
SYS_proc_info,
0, 0, 0, 0, 0, 0, 0, // filler for x1-x7
PROC_INFO_CALL_PIDFDINFO,
UInt64(getpid()),
PROC_PIDFDSEMINFO,
UInt64(UInt(bitPattern: sem)),
UInt64(UInt(bitPattern: sem_info_buf)),
UInt64(sem_info_size))
assert (s_ret == Int32(sem_info_size))
let sem_info = sem_info_buf.load(as: psem_fdinfo.self)
let sem_name_raw = sem_info_buf.advanced(by: MemoryLayout<psem_fdinfo>.size).bindMemory(to: CChar.self, capacity: 1024)
let sem_name = String(cString: sem_name_raw)
return (sem_info, sem_name)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment