char * ttyname(int fd) { char *buf; if (thr_main() != 0) buf = ttyname_buf; else { if (thr_once(&ttyname_init_once, ttyname_keycreate) != 0 || !ttyname_keycreated) return (NULL); if ((buf = thr_getspecific(ttyname_key)) == NULL) { if ((buf = malloc(sizeof ttyname_buf)) == NULL) return (NULL); if (thr_setspecific(ttyname_key, buf) != 0) { free(buf); return (NULL); } } } if (ttyname_r(fd, buf, sizeof ttyname_buf) != 0) return (NULL); return (buf); }
/* * Broadcasts on UDP transport. Obsoleted by rpc_broadcast(). */ enum clnt_stat clnt_broadcast( u_long prog, /* program number */ u_long vers, /* version number */ u_long proc, /* procedure number */ xdrproc_t xargs, /* xdr routine for args */ caddr_t argsp, /* pointer to args */ xdrproc_t xresults, /* xdr routine for results */ caddr_t resultsp, /* pointer to results */ resultproc_t eachresult) /* call with each result obtained */ { #ifdef _REENTRANT if (__isthreaded == 0) clnt_broadcast_result_main = eachresult; else { thr_once(&clnt_broadcast_once, clnt_broadcast_setup); thr_setspecific(clnt_broadcast_key, (void *) eachresult); } #else clnt_broadcast_result_main = eachresult; #endif return rpc_broadcast((rpcprog_t)prog, (rpcvers_t)vers, (rpcproc_t)proc, xargs, argsp, xresults, resultsp, (resultproc_t) rpc_wrap_bcast, "udp"); }
res_state __res_state(void) { res_state statp; if (thr_main() != 0) return (&_res); if (thr_once(&res_init_once, res_keycreate) != 0 || !res_thr_keycreated) return (&_res); statp = thr_getspecific(res_key); if (statp != NULL) return (statp); statp = calloc(1, sizeof(*statp)); if (statp == NULL) return (&_res); #ifdef __BIND_RES_TEXT statp->options = RES_TIMEOUT; /* Motorola, et al. */ #endif if (thr_setspecific(res_key, statp) == 0) return (statp); free(statp); return (&_res); }
char * fdevname(int fd) { char *buf; int error; if (thr_main() != 0) buf = fdevname_buf; else { if (thr_once(&fdevname_init_once, fdevname_keycreate) != 0 || !fdevname_keycreated) return (NULL); if ((buf = thr_getspecific(fdevname_key)) == NULL) { if ((buf = malloc(sizeof fdevname_buf)) == NULL) return (NULL); if (thr_setspecific(fdevname_key, buf) != 0) { free(buf); return (NULL); } } } if (((error = fdevname_r(fd, buf, sizeof fdevname_buf))) != 0) { errno = error; return (NULL); } return (buf); }
/* * Broadcasts on UDP transport. Obsoleted by rpc_broadcast(). */ enum clnt_stat clnt_broadcast(u_long prog, u_long vers, u_long proc, xdrproc_t xargs, void *argsp, xdrproc_t xresults, void *resultsp, resultproc_t eachresult) /* * u_long prog; // program number * u_long vers; // version number * u_long proc; // procedure number * xdrproc_t xargs; // xdr routine for args * void *argsp; // pointer to args * xdrproc_t xresults; // xdr routine for results * void *resultsp; // pointer to results * resultproc_t eachresult; // call with each result obtained */ { if (thr_main()) clnt_broadcast_result_main = eachresult; else { thr_once(&clnt_broadcast_once, clnt_broadcast_key_init); thr_setspecific(clnt_broadcast_key, (void *) eachresult); } return rpc_broadcast((rpcprog_t)prog, (rpcvers_t)vers, (rpcproc_t)proc, xargs, argsp, xresults, resultsp, (resultproc_t) rpc_wrap_bcast, "udp"); }
static int * __nc_error(void) { static int nc_error = 0; int *nc_addr; /* * Use the static `nc_error' if we are the main thread * (including non-threaded programs), or if an allocation * fails. */ if (thr_main()) return (&nc_error); if (thr_once(&nc_once, nc_key_init) != 0 || nc_key_error != 0) return (&nc_error); if ((nc_addr = (int *)thr_getspecific(nc_key)) == NULL) { nc_addr = (int *)malloc(sizeof (int)); if (thr_setspecific(nc_key, (void *) nc_addr) != 0) { free(nc_addr); return (&nc_error); } *nc_addr = 0; } return (nc_addr); }
static int * __nc_error(void) { #ifdef _REENTRANT int *nc_addr = NULL; #endif static int nc_error = 0; #ifdef _REENTRANT if (__isthreaded == 0) return &nc_error; thr_once(&nc_once, __nc_error_setup); nc_addr = thr_getspecific(nc_key) ; if (nc_addr == NULL) { nc_addr = malloc(sizeof (int)); if (nc_addr == NULL) return &nc_error; if (thr_setspecific(nc_key, (void *) nc_addr) != 0) { if (nc_addr) free(nc_addr); return &nc_error; } *nc_addr = 0; } return nc_addr; #else return &nc_error; #endif }
static char * sig_tlsalloc(void) { char *ebuf = NULL; if (thr_main() != 0) ebuf = sig_ebuf; else { if (thr_once(&sig_init_once, sig_keycreate) != 0 || !sig_keycreated) goto thr_err; if ((ebuf = thr_getspecific(sig_key)) == NULL) { if ((ebuf = malloc(sizeof(sig_ebuf))) == NULL) goto thr_err; if (thr_setspecific(sig_key, ebuf) != 0) { free(ebuf); ebuf = NULL; goto thr_err; } } } thr_err: if (ebuf == NULL) ebuf = sig_ebuf_err; return (ebuf); }
struct servdata * __servdata_init(void) { struct servdata *sd; if (thr_main() != 0) return (&servdata); if (thr_once(&servdata_init_once, servdata_keycreate) != 0 || !servdata_thr_keycreated) return (NULL); if ((sd = thr_getspecific(servdata_key)) != NULL) return (sd); if ((sd = calloc(1, sizeof(*sd))) == NULL) return (NULL); if (thr_setspecific(servdata_key, sd) == 0) return (sd); free(sd); return (NULL); }
const char * gai_strerror(int ecode) { #if defined(NLS) nl_catd catd; char *buf; if (thr_main() != 0) buf = gai_buf; else { if (thr_once(&gai_init_once, gai_keycreate) != 0 || !gai_keycreated) goto thr_err; if ((buf = thr_getspecific(gai_key)) == NULL) { if ((buf = malloc(sizeof(gai_buf))) == NULL) goto thr_err; if (thr_setspecific(gai_key, buf) != 0) { free(buf); goto thr_err; } } } catd = catopen("libc", NL_CAT_LOCALE); if (ecode > 0 && ecode < EAI_MAX) strlcpy(buf, catgets(catd, 3, ecode, ai_errlist[ecode]), sizeof(gai_buf)); else if (ecode == 0) strlcpy(buf, catgets(catd, 3, NL_MSGMAX - 1, "Success"), sizeof(gai_buf)); else strlcpy(buf, catgets(catd, 3, NL_MSGMAX, "Unknown error"), sizeof(gai_buf)); catclose(catd); return buf; thr_err: #endif if (ecode >= 0 && ecode < EAI_MAX) return ai_errlist[ecode]; return "Unknown error"; }
struct rpc_createerr * __rpc_createerr(void) { struct rpc_createerr *rce_addr = 0; if (thr_main()) return (&rpc_createerr); if (thr_once(&rce_once, rce_key_init) != 0 || rce_key_error != 0) return (&rpc_createerr); rce_addr = (struct rpc_createerr *)thr_getspecific(rce_key); if (!rce_addr) { rce_addr = (struct rpc_createerr *) malloc(sizeof (struct rpc_createerr)); if (thr_setspecific(rce_key, (void *) rce_addr) != 0) { free(rce_addr); return (&rpc_createerr); } memset(rce_addr, 0, sizeof (struct rpc_createerr)); return (rce_addr); } return (rce_addr); }
struct rpc_createerr* __rpc_createerr(void) { #ifdef _REENTRANT struct rpc_createerr *rce_addr = 0; if (__isthreaded == 0) return (&rpc_createerr); thr_once(&rce_once, __rpc_createerr_setup); rce_addr = thr_getspecific(rce_key); if (rce_addr == NULL) { rce_addr = malloc(sizeof(*rce_addr)); if (rce_addr == NULL) return &rpc_createerr; thr_setspecific(rce_key, (void *) rce_addr); memset(rce_addr, 0, sizeof (struct rpc_createerr)); } return (rce_addr); #else return &rpc_createerr; #endif }
/* * This is the simplified interface to the client rpc layer. * The client handle is not destroyed here and is reused for * the future calls to same prog, vers, host and nettype combination. * * The total time available is 25 seconds. * * host - host name * prognum - program number * versnum - version number * procnum - procedure number * inproc, outproc - in/out XDR procedures * in, out - recv/send data * nettype - nettype */ enum clnt_stat rpc_call(const char *host, const rpcprog_t prognum, const rpcvers_t versnum, const rpcproc_t procnum, const xdrproc_t inproc, const char *in, const xdrproc_t outproc, char *out, const char *nettype) { struct rpc_call_private *rcp = (struct rpc_call_private *) 0; enum clnt_stat clnt_stat; struct timeval timeout, tottimeout; int main_thread = 1; if ((main_thread = thr_main())) { rcp = rpc_call_private_main; } else { if (thr_once(&rpc_call_once, rpc_call_key_init) != 0 || rpc_call_key_error != 0) { rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = rpc_call_key_error; return (rpc_createerr.cf_stat); } rcp = (struct rpc_call_private *)thr_getspecific(rpc_call_key); } if (rcp == NULL) { rcp = malloc(sizeof (*rcp)); if (rcp == NULL) { rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = errno; return (rpc_createerr.cf_stat); } if (main_thread) rpc_call_private_main = rcp; else thr_setspecific(rpc_call_key, (void *) rcp); rcp->valid = 0; rcp->client = NULL; } if ((nettype == NULL) || (nettype[0] == 0)) nettype = "netpath"; if (!(rcp->valid && rcp->pid == getpid() && (rcp->prognum == prognum) && (rcp->versnum == versnum) && (!strcmp(rcp->host, host)) && (!strcmp(rcp->nettype, nettype)))) { int fd; rcp->valid = 0; if (rcp->client) CLNT_DESTROY(rcp->client); /* * Using the first successful transport for that type */ rcp->client = clnt_create(host, prognum, versnum, nettype); rcp->pid = getpid(); if (rcp->client == NULL) { return (rpc_createerr.cf_stat); } /* * Set time outs for connectionless case. Do it * unconditionally. Faster than doing a t_getinfo() * and then doing the right thing. */ timeout.tv_usec = 0; timeout.tv_sec = 5; (void) CLNT_CONTROL(rcp->client, CLSET_RETRY_TIMEOUT, (char *)(void *)&timeout); if (CLNT_CONTROL(rcp->client, CLGET_FD, (char *)(void *)&fd)) _fcntl(fd, F_SETFD, 1); /* make it "close on exec" */ rcp->prognum = prognum; rcp->versnum = versnum; if ((strlen(host) < (size_t)MAXHOSTNAMELEN) && (strlen(nettype) < (size_t)NETIDLEN)) { (void) strcpy(rcp->host, host); (void) strcpy(rcp->nettype, nettype); rcp->valid = 1; } else { rcp->valid = 0; } } /* else reuse old client */ tottimeout.tv_sec = 25; tottimeout.tv_usec = 0; /*LINTED const castaway*/ clnt_stat = CLNT_CALL(rcp->client, procnum, inproc, (char *) in, outproc, out, tottimeout); /* * if call failed, empty cache */ if (clnt_stat != RPC_SUCCESS) rcp->valid = 0; return (clnt_stat); }