在多线程的环境中,我们需要有线程创建函数来创建需要的线程,一般的系统都是有自己的线程创建函数的,但是有的系统没有,或者说两个系统不兼容,那么我们就需要有自己的线程创建函数来兼容第三方,一般在模拟线程创建的时候都是用进程来实现的,下面就是一个例子:
static int
pthread_create(sp_pthread_t *thread, const void *attr,
void *(*thread_start)(void *), void *arg)
{
pid_t pid;
struct pam_ctxt *ctx = arg;
sshpam_thread_status = -1;
switch ((pid = fork())) {
case -1:
error("fork(): %s", strerror(errno));
return (-1);
case 0:
close(ctx->pam_psock);
ctx->pam_psock = -1;
thread_start(arg);
_exit(1);
default:
*thread = pid;
close(ctx->pam_csock);
ctx->pam_csock = -1;
sshpam_oldsig = signal(SIGCHLD, sshpam_sigchld_handler);
return (0);
}
}
typedef pthread_t sp_pthread_t;
#else
typedef pid_t sp_pthread_t;
#endif
struct pam_ctxt {
sp_pthread_t pam_thread;
int pam_psock;
int pam_csock;
int pam_done;
};
static void sshpam_free_ctx(void *);
static struct pam_ctxt *cleanup_ctxt;
#ifndef UNSUPPORTED_POSIX_THREADS_HACK
/*
* Simulate threads with processes.
*/
static int sshpam_thread_status = -1;
static mysig_t sshpam_oldsig;
static void
sshpam_sigchld_handler(int sig)
{
signal(SIGCHLD, SIG_DFL);
if (cleanup_ctxt == NULL)
return; /* handler called after PAM cleanup, shouldn't happen */
if (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, WNOHANG)
<= 0) {
/* PAM thread has not exitted, privsep slave must have */
kill(cleanup_ctxt->pam_thread, SIGTERM);
if (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, 0)
<= 0)
return; /* could not wait */
}
if (WIFSIGNALED(sshpam_thread_status) &&
WTERMSIG(sshpam_thread_status) == SIGTERM)
return; /* terminated by pthread_cancel */
if (!WIFEXITED(sshpam_thread_status))
sigdie("PAM: authentication thread exited unexpectedly");
if (WEXITSTATUS(sshpam_thread_status) != 0)
sigdie("PAM: authentication thread exited uncleanly");
}
/* ARGSUSED */
static void
pthread_exit(void *value)
{
_exit(0);
}