Signal Handling with Swift – sigaction version

I need a pointer in my signal handler, so I need to use sigaction. The following doesn’t go quite all the way with this, but I think it’s a useful example.

func shandler(sig: Int32, signfo: UnsafeMutablePointer<__siginfo>, 
              p: UnsafeMutablePointer) {
	print("Hello World")
}

var sinfo = siginfo_t()
sinfo.si_signo = SIGALRM

var sAction = sigaction()
sAction.__sigaction_u.__sa_sigaction = shandler
sAction.sa_flags = SA_SIGINFO

withUnsafeMutablePointer(&sAction) {
	sigaction(SIGALRM, $0, nil)
}

kill(getpid(), SIGALRM)

Later that same day…

I just found out that OS X doesn’t support sigqueue. Which is a total bummer. I suppose the signal masking stuff is reason enough to have a sigaction, but …

Anyhoo I guess I have to store state outside the signal handler in order to change behavior within it. Which makes me think ‘race’ and ‘reentrancy’….

Anyway, here’s some modified test code to illustrate the idea. Much of the signal handler is just seeing what’s being passed in to siginfo and p. I also make sure I can cast to and from the global fb.

struct Foobar {
	let name: String
	let value: Int
}

let fb = Foobar(name: "josie", value: 32)
let fbp = UnsafeMutablePointer.alloc(1)
fbp.memory = fb

let fbp2 = unsafeBitCast(fbp, UnsafeMutablePointer.self)

func shandler(sig: Int32, siginfo: UnsafeMutablePointer<__siginfo>, 
              p: UnsafeMutablePointer) {
	print("\(p)")
	let si = siginfo.memory
	print("\(si)")
	print("Hello World")
	
	print("\(fbp2)")
	let fbp3 = unsafeBitCast(fbp, UnsafeMutablePointer.self)
	print("\(fbp3.memory)")
}

var sinfo = siginfo_t()
sinfo.si_signo = SIGALRM

var sAction = sigaction()
sAction.__sigaction_u.__sa_sigaction = shandler
sAction.sa_flags = SA_SIGINFO

withUnsafeMutablePointer(&sAction) {
	sigaction(SIGALRM, $0, nil)
}

kill(getpid(), SIGALRM)

Leave a Reply

Your email address will not be published. Required fields are marked *