int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)

{

    CPUState *cpu = ENV_GET_CPU(env);

    TaskState *ts = cpu->opaque;

    struct emulated_sigtable *k;

    struct sigqueue *q, **pq;

    abi_ulong handler;

    int queue;



    trace_user_queue_signal(env, sig);

    k = &ts->sigtab[sig - 1];

    queue = gdb_queuesig ();

    handler = sigact_table[sig - 1]._sa_handler;



    if (sig == TARGET_SIGSEGV && sigismember(&ts->signal_mask, SIGSEGV)) {

        /* Guest has blocked SIGSEGV but we got one anyway. Assume this

         * is a forced SIGSEGV (ie one the kernel handles via force_sig_info

         * because it got a real MMU fault). A blocked SIGSEGV in that

         * situation is treated as if using the default handler. This is

         * not correct if some other process has randomly sent us a SIGSEGV

         * via kill(), but that is not easy to distinguish at this point,

         * so we assume it doesn't happen.

         */

        handler = TARGET_SIG_DFL;

    }



    if (!queue && handler == TARGET_SIG_DFL) {

        if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {

            kill(getpid(),SIGSTOP);

            return 0;

        } else

        /* default handler : ignore some signal. The other are fatal */

        if (sig != TARGET_SIGCHLD &&

            sig != TARGET_SIGURG &&

            sig != TARGET_SIGWINCH &&

            sig != TARGET_SIGCONT) {

            force_sig(sig);

        } else {

            return 0; /* indicate ignored */

        }

    } else if (!queue && handler == TARGET_SIG_IGN) {

        /* ignore signal */

        return 0;

    } else if (!queue && handler == TARGET_SIG_ERR) {

        force_sig(sig);

    } else {

        pq = &k->first;

        if (sig < TARGET_SIGRTMIN) {

            /* if non real time signal, we queue exactly one signal */

            if (!k->pending)

                q = &k->info;

            else

                return 0;

        } else {

            if (!k->pending) {

                /* first signal */

                q = &k->info;

            } else {

                q = alloc_sigqueue(env);

                if (!q)

                    return -EAGAIN;

                while (*pq != NULL)

                    pq = &(*pq)->next;

            }

        }

        *pq = q;

        q->info = *info;

        q->next = NULL;

        k->pending = 1;

        /* signal that a new signal is pending */

        atomic_set(&ts->signal_pending, 1);

        return 1; /* indicates that the signal was queued */

    }

}

int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)

{

    CPUState *cpu = ENV_GET_CPU(env);

    TaskState *ts = cpu->opaque;

    struct emulated_sigtable *k;

    struct sigqueue *q, **pq;

    abi_ulong handler;

    int queue;



    trace_user_queue_signal(env, sig);

    k = &ts->sigtab[sig - 1];

    queue = gdb_queuesig ();

    handler = sigact_table[sig - 1]._sa_handler;



    if (sig == TARGET_SIGSEGV && sigismember(&ts->signal_mask, SIGSEGV)) {

        















        handler = TARGET_SIG_DFL;

    }



    if (!queue && handler == TARGET_SIG_DFL) {

        if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {

            kill(getpid(),SIGSTOP);

            return 0;

        } else

        

        if (sig != TARGET_SIGCHLD &&

            sig != TARGET_SIGURG &&

            sig != TARGET_SIGWINCH &&

            sig != TARGET_SIGCONT) {

            force_sig(sig);

        } else {

            return 0; 

        }

    } else if (!queue && handler == TARGET_SIG_IGN) {

        

        return 0;

    } else if (!queue && handler == TARGET_SIG_ERR) {

        force_sig(sig);

    } else {

        pq = &k->first;

        if (sig < TARGET_SIGRTMIN) {

            

            if (!k->pending)

                q = &k->info;

            else

                return 0;

        } else {

            if (!k->pending) {

                

                q = &k->info;

            } else {

                q = alloc_sigqueue(env);

                if (!q)

                    return -EAGAIN;

                while (*pq != NULL)

                    pq = &(*pq)->next;

            }

        }

        *pq = q;

        q->info = *info;

        q->next = NULL;

        k->pending = 1;

        

        atomic_set(&ts->signal_pending, 1);

        return 1; 

    }

}

int FUNC_0(CPUArchState *VAR_0, int VAR_1, target_siginfo_t *VAR_2)

{

    CPUState *cpu = ENV_GET_CPU(VAR_0);

    TaskState *ts = cpu->opaque;

    struct emulated_sigtable *VAR_3;

    struct sigqueue *VAR_4, **VAR_5;

    abi_ulong handler;

    int VAR_6;



    trace_user_queue_signal(VAR_0, VAR_1);

    VAR_3 = &ts->sigtab[VAR_1 - 1];

    VAR_6 = gdb_queuesig ();

    handler = sigact_table[VAR_1 - 1]._sa_handler;



    if (VAR_1 == TARGET_SIGSEGV && sigismember(&ts->signal_mask, SIGSEGV)) {

        















        handler = TARGET_SIG_DFL;

    }



    if (!VAR_6 && handler == TARGET_SIG_DFL) {

        if (VAR_1 == TARGET_SIGTSTP || VAR_1 == TARGET_SIGTTIN || VAR_1 == TARGET_SIGTTOU) {

            kill(getpid(),SIGSTOP);

            return 0;

        } else

        

        if (VAR_1 != TARGET_SIGCHLD &&

            VAR_1 != TARGET_SIGURG &&

            VAR_1 != TARGET_SIGWINCH &&

            VAR_1 != TARGET_SIGCONT) {

            force_sig(VAR_1);

        } else {

            return 0; 

        }

    } else if (!VAR_6 && handler == TARGET_SIG_IGN) {

        

        return 0;

    } else if (!VAR_6 && handler == TARGET_SIG_ERR) {

        force_sig(VAR_1);

    } else {

        VAR_5 = &VAR_3->first;

        if (VAR_1 < TARGET_SIGRTMIN) {

            

            if (!VAR_3->pending)

                VAR_4 = &VAR_3->VAR_2;

            else

                return 0;

        } else {

            if (!VAR_3->pending) {

                

                VAR_4 = &VAR_3->VAR_2;

            } else {

                VAR_4 = alloc_sigqueue(VAR_0);

                if (!VAR_4)

                    return -EAGAIN;

                while (*VAR_5 != NULL)

                    VAR_5 = &(*VAR_5)->next;

            }

        }

        *VAR_5 = VAR_4;

        VAR_4->VAR_2 = *VAR_2;

        VAR_4->next = NULL;

        VAR_3->pending = 1;

        

        atomic_set(&ts->signal_pending, 1);

        return 1; 

    }

}

int FUNC_0(CPUArchState *VAR_0, int VAR_1, target_siginfo_t *VAR_2)
{ CPUState *cpu = ENV_GET_CPU(VAR_0); TaskState *ts = cpu->opaque; struct emulated_sigtable *VAR_3; struct sigqueue *VAR_4, **VAR_5; abi_ulong handler; int VAR_6; trace_user_queue_signal(VAR_0, VAR_1); VAR_3 = &ts->sigtab[VAR_1 - 1]; VAR_6 = gdb_queuesig (); handler = sigact_table[VAR_1 - 1]._sa_handler; if (VAR_1 == TARGET_SIGSEGV && sigismember(&ts->signal_mask, SIGSEGV)) { handler = TARGET_SIG_DFL; } if (!VAR_6 && handler == TARGET_SIG_DFL) { if (VAR_1 == TARGET_SIGTSTP || VAR_1 == TARGET_SIGTTIN || VAR_1 == TARGET_SIGTTOU) { kill(getpid(),SIGSTOP); return 0; } else if (VAR_1 != TARGET_SIGCHLD &&
VAR_1 != TARGET_SIGURG &&
VAR_1 != TARGET_SIGWINCH &&
VAR_1 != TARGET_SIGCONT) { force_sig(VAR_1); } else { return 0; } } else if (!VAR_6 && handler == TARGET_SIG_IGN) { return 0; } else if (!VAR_6 && handler == TARGET_SIG_ERR) { force_sig(VAR_1); } else { VAR_5 = &VAR_3->first; if (VAR_1 < TARGET_SIGRTMIN) { if (!VAR_3->pending)
VAR_4 = &VAR_3->VAR_2; else
return 0; } else { if (!VAR_3->pending) { VAR_4 = &VAR_3->VAR_2; } else { VAR_4 = alloc_sigqueue(VAR_0); if (!VAR_4)
return -EAGAIN; while (*VAR_5 != NULL)
VAR_5 = &(*VAR_5)->next; } } *VAR_5 = VAR_4; VAR_4->VAR_2 = *VAR_2; VAR_4->next = NULL; VAR_3->pending = 1; atomic_set(&ts->signal_pending, 1); return 1; } }