/* Test cancellation of a door_return call. */
#include <assert.h>
#include <door.h>
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/lwp.h>
#include <unistd.h>
static volatile lwpid_t server_lwpid = 0;
static void server_procedure(void *cookie, char *argp, size_t arg_size,
door_desc_t *dp, uint_t n_desc)
{
assert(0);
}
static void *my_server_thread(void *arg)
{
server_lwpid = _lwp_self();
door_return(NULL, 0, NULL, 0);
return NULL;
}
static void create_door_thread(door_info_t *info)
{
static int called = 0;
pthread_t thread;
int res;
/* Allow to create only one server door thread. */
assert(!called);
called = 1;
res = pthread_create(&thread, NULL, my_server_thread, NULL);
if (res) {
errno = res;
perror("pthread_create");
exit(1);
}
}
static void signal_handler(int signo, siginfo_t *info, void *uc)
{
const char str[] = "Signal caught.\n";
size_t len = sizeof(str) - 1;
ssize_t res;
res = write(STDOUT_FILENO, str, len);
assert(res == len);
}
int main(void)
{
int res = 1;
int did = -1;
struct sigaction sa;
sa.sa_sigaction = signal_handler;
sa.sa_flags = SA_RESTART;
if (sigfillset(&sa.sa_mask)) {
perror("sigfillset");
return 1;
}
if (sigaction(SIGINT, &sa, NULL)) {
perror("sigaction");
return 1;
}
door_server_create(create_door_thread);
if ((did = door_create(server_procedure, NULL, 0)) < 0) {
perror("door_create");
return 1;
}
/* Let the server thread to run. */
sleep(2);
/* Send a signal to the server thread that should be already created and
blocked in door_return. */
if (_lwp_kill(server_lwpid, SIGINT)) {
perror("_lwp_kill");
goto out;
}
/* Let the other thread to run. */
sleep(2);
res = 0;
out:
if (did >= 0 && door_revoke(did))
perror("door_revoke");
return res;
}