📄 sel_common.c
字号:
#ifndef lint#ifdef sccsstatic char sccsid[] = "@(#)sel_common.c 1.1 92/07/30";#endif#endif#include <sunwindow/rect.h> /* LINT_CAST definition */#include <suntool/selection_impl.h>/* * sel_common.c: routines which appear in both the service and the * client library. (See header of sel_clnt.c for * discussion of service / client terminology in * this package.) * * (C) Copyright 1986 Sun Microsystems, Inc. *//* initialized data goes into sharable (read-only) text segment */Seln_function_buffer seln_null_function = { SELN_FN_ERROR, SELN_UNKNOWN, SELN_NULL_HOLDER, SELN_NULL_HOLDER, SELN_NULL_HOLDER, SELN_NULL_HOLDER};Seln_holder seln_null_holder = { SELN_NULL_HOLDER};Seln_request seln_null_request = { 0, {0, 0}, 0, SELN_UNKNOWN, SELN_FAILED, 0, 0};/* Basic information about how this process communicates: */Seln_access seln_my_access; /* How requesters contact us */int seln_my_tcp_socket;int seln_transient_tcp_socket;int seln_my_udp_socket;SVCXPRT *seln_my_tcp_transport; /* How we answer */SVCXPRT *seln_my_udp_transport;static fd_set seln_my_open_tcps; /* mask of fds that are open */Seln_client_node clients;/* * External procedures (called by client code) * * First, some predicates * * * Holder_same_client: * TRUE if argument access struct identifies this client * (valid only in the client's address space) */intseln_holder_same_client(holder, client_data) register Seln_holder *holder; register char *client_data;{ return (holder != (Seln_holder *) NULL && holder->access.pid == seln_my_access.pid && ((Seln_client_node *) (LINT_CAST(holder->access.client)))->client_data == client_data);}/* * Holder_same_process: * Return TRUE if argument access struct identifies same process */intseln_holder_same_process(holder) register Seln_holder *holder;{ return (holder != (Seln_holder *) NULL && holder->access.pid == seln_my_access.pid);}/* * Same_holder: Return TRUE if 2 holders are the same (incl. rank & state) */intseln_same_holder(h1, h2)register Seln_holder *h1, *h2;{ if (h1 == (Seln_holder *) NULL || h2 == (Seln_holder *) NULL) { return FALSE; } return (h1->rank == h2->rank && h1->state == h2->state && seln_equal_access(&h1->access, &h2->access));}/* * Return TRUE if two holder structs agree in all elements, else FALSE */intseln_equal_access(first, second) register Seln_access *first; register Seln_access *second;{ if (first == (Seln_access *) NULL || second == (Seln_access *) NULL) { return FALSE; } return (first->pid == second->pid && first->program == second->program && first->client == second->client && seln_equal_addrs(&first->tcp_address, &second->tcp_address) && seln_equal_addrs(&first->udp_address, &second->udp_address));}/* Secondary_made: true if this buffer indicates a secondary selection * has been made since the function key went down (whether or not * one exists now). */intseln_secondary_made(buffer) Seln_function_buffer *buffer;{ return (buffer->secondary.access.pid != 0);}/* Secondary_exists: true if this buffer indicates a secondary selection * existed at the time the function key went up. */intseln_secondary_exists(buffer) Seln_function_buffer *buffer;{ return (buffer->secondary.state != SELN_NONE);}/* * package-internal routines: * *//* * first, shoulda-been-provided routines for * dealing with fd masks. * * WARNING: this stuff is byte- and bit-order sensitive! * (as is the stuff that *was* provided...). * * fd_set svc_fdset; declared in <rpc/svc.h> */#define N_FD_MASKS (sizeof(svc_fdset.fds_bits)/sizeof(svc_fdset.fds_bits[0]))static voidfd_diff(base, removed) /* turns off removed bits in base */ register fd_set *base; register fd_set *removed;{ register int i; for (i = N_FD_MASKS; i-- > 0;) { base->fds_bits[i] &= ~(removed->fds_bits[i]); }}static intfd_last(mask) /* returns the fd for the highest 1-bit in mask */ register fd_set *mask;{ register int i, j; register fd_mask m; for (i = N_FD_MASKS; i-- > 0;) if (m = mask->fds_bits[i]) for (j = NFDBITS; j-- > 0;) if (m & 1 << j) return j + i * NFDBITS; return -1; /* none set */}/* Now use them. This routine keeps the notifier up-to-date as TCP * connections get opened & closed behind our back in svc_getreqset. */ static voidseln_adjust_fds(saved) fd_set *saved;{ fd_set opened; fd_set closed; register int fd; opened = svc_fdset; /* opened files have bits on now */ fd_diff(&opened, saved); /* that used to be off */ for (fd = fd_last(&opened); fd >= 0; fd--) { if (FD_ISSET(fd, &opened)) { (void) notify_set_input_func((Notify_client) seln_my_tcp_transport, seln_listener, fd); FD_SET(fd, &seln_my_open_tcps); } } closed = *saved; /* closed fds used to be on */ fd_diff(&closed, &svc_fdset); /* and now are off */ for (fd = fd_last(&closed); fd >= 0; fd--) { if (FD_ISSET(fd, &closed)) { (void) notify_set_input_func((Notify_client) seln_my_tcp_transport, NOTIFY_FUNC_NULL, fd); FD_CLR(fd, &seln_my_open_tcps); } }}Seln_resultseln_send_yield(rank, holder, use_std_timeout) Seln_rank rank; Seln_holder *holder; int use_std_timeout;{ register CLIENT *client; int sock = RPC_ANYSOCK; enum clnt_stat rpc_result; Seln_request buffer; Seln_replier_data replier; char **requestp; struct timeval seln_timer; if (use_std_timeout) { seln_timer.tv_sec = seln_std_timeout.tv_sec; seln_timer.tv_usec = seln_std_timeout.tv_usec; } else { seln_timer.tv_sec = 0; seln_timer.tv_usec = 0; } buffer.replier = 0; buffer.requester.consume = 0; buffer.requester.context = 0; buffer.addressee = holder->access.client; buffer.rank = rank; buffer.status = SELN_SUCCESS; buffer.buf_size = 3 * sizeof (char *); requestp = (char **) (LINT_CAST(buffer.data)); *requestp++ = (char *) SELN_REQ_YIELD; *requestp++ = 0; *requestp++ = 0; if (seln_holder_same_process(holder)) { buffer.replier = &replier; replier.client_data = ((Seln_client_node *)(LINT_CAST(holder->access.client)))->client_data; replier.rank = holder->rank; replier.context = 0; replier.request_pointer = (char **) (LINT_CAST(buffer.data)); if (seln_get_reply_buffer(&buffer) != SELN_SUCCESS) { return SELN_FAILED; } } else { if ((client = clntudp_bufcreate(&holder->access.udp_address, holder->access.program, SELN_VERSION, seln_std_timeout, &sock, SELN_RPC_BUFSIZE, SELN_RPC_BUFSIZE)) == (CLIENT *) NULL) { return SELN_FAILED; } rpc_result = clnt_call(client, SELN_CLNT_REQUEST, xdr_seln_request, &buffer, xdr_seln_reply, &buffer, seln_timer); clnt_destroy(client); (void)close(sock); if (rpc_result == RPC_TIMEDOUT && seln_timer.tv_sec == 0 && seln_timer.tv_usec == 0) { return SELN_SUCCESS; } if (rpc_result != RPC_SUCCESS) { return SELN_FAILED; } } requestp = (char **) (LINT_CAST(buffer.data)); if (*requestp++ != (char *) SELN_REQ_YIELD) { return SELN_FAILED; } return (Seln_result) *requestp;}/* seln_listener is called by (window system) notifier *//* ARGSUSED */Notify_valueseln_listener(handle, fd) caddr_t handle; int fd;{ fd_set saved_fdset; fd_set getreq_mask;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -