IPC-Door

 view release on metacpan or  search on metacpan

Door.xs  view on Meta::CPAN

    char ipc_door_data_pv[MAX_STRING];
    int  cur;
    int  len;
} ipc_door_data_t;

/* The server process */
static void servproc(void *cookie, char *dataptr, size_t datasize,
    door_desc_t *descptr, size_t ndesc)
{
    dSP;

    ipc_door_data_t arg, retval;
    SV          *result;
#ifdef _UCRED_H_
    ucred_t     **info;
#else
    door_cred_t info;
#endif
    SV          *sv_callback; /* serverprocess code reference */
    register SV *sv;          /* convenience variable */
    void        *tmp;
    char        *str;
    int         count;
            /* number of elements returned from sv_callback in Perl */

    ENTER;
    SAVETMPS;

    PUSHMARK(SP);

    memmove(&arg, dataptr, min(datasize,sizeof(arg)));
    if ((str = calloc(1, MAX_STRING)) == NULL)
    {
        WARN(("memory allocation error: %s", strerror(errno)));
        return;
    }
    arg.ipc_door_data_pv[MAX_STRING-1]='\0';
    memmove((void*)str, arg.ipc_door_data_pv, MAX_STRING);

    sv=sv_newmortal();
    sv_callback=sv_newmortal();
    sv_callback = (SV *) cookie;
    sv = newSVpv( "", 0 );
    SvGROW(sv,MAX_STRING);
    memmove((void*)SvPVX(sv), str, MAX_STRING);
    SvCUR(sv)=arg.cur;
    SvLEN(sv)=arg.len;

    free(str);

    if (SvOK(sv))
        XPUSHs(sv);
    else {
        /* fall through; we shouldn't be here, but you never know. */
        WARN(("Something went horribly wrong in servproc"));
        return;
    }

    PUTBACK;

    /* grab the client's credentials before calling &main::serv */
#ifdef _UCRED_H_
/* the new way to get the client process credentials */
    if ( (*info = calloc(1, ucred_size())) == NULL )
    {
        WARN(("memory allocation error: %s\n", strerror(errno)));
        return;
    }
    if (door_ucred(info) < 0)
        WARN(("door_ucred() failed: %s\n", strerror(errno)));

    sv_setiv( get_sv("IPC::Door::CLIENT_EUID",TRUE), ucred_geteuid( *info));
    sv_setiv( get_sv("IPC::Door::CLIENT_EGID",TRUE), ucred_getegid( *info));
    sv_setiv( get_sv("IPC::Door::CLIENT_RUID",TRUE), ucred_getruid( *info));
    sv_setiv( get_sv("IPC::Door::CLIENT_RGID",TRUE), ucred_getrgid( *info));
    sv_setiv( get_sv("IPC::Door::CLIENT_PID", TRUE), ucred_getpid(  *info));

    ucred_free( *info );

#else
    if (door_cred(&info) < 0)
        WARN(("door_cred() failed: %s\n", strerror(errno)));

    sv_setiv( get_sv("IPC::Door::CLIENT_EUID",TRUE), info.dc_euid );
    sv_setiv( get_sv("IPC::Door::CLIENT_EGID",TRUE), info.dc_egid );
    sv_setiv( get_sv("IPC::Door::CLIENT_RUID",TRUE), info.dc_ruid );
    sv_setiv( get_sv("IPC::Door::CLIENT_RGID",TRUE), info.dc_rgid );
    sv_setiv( get_sv("IPC::Door::CLIENT_PID", TRUE), info.dc_pid  );

#endif

    count = call_sv(sv_callback, G_SCALAR);

    SPAGAIN;

    if (count != 1)
        WARN(("servproc: Expected 1 value from server process, but got %d values", count));
    result = POPs;

    str = SvPV( result, PL_na );
    memmove(retval.ipc_door_data_pv, str, MAX_STRING);
    retval.cur=SvCUR(result);
    retval.len=SvLEN(result);

    if (door_return((char *) &retval, sizeof(retval),NULL,0) < 0)
        WARN(("door_return() failed in servproc: %s\n", strerror(errno)));

    PUTBACK;

    FREETMPS;
    LEAVE;

}

/*
Start XSUB
*/

MODULE=IPC::Door    PACKAGE=IPC::Door

INCLUDE: const-xs.inc

int



( run in 1.383 second using v1.01-cache-2.11-cpan-ad19def0cd9 )