00001 /* 00002 SMI - sockets 00003 AUP2, Sec. 8.05 00004 00005 Copyright 2003 by Marc J. Rochkind. All rights reserved. 00006 May be copied only for purposes and under conditions described 00007 on the Web page www.basepath.com/aup/copyright.htm. 00008 00009 The Example Files are provided "as is," without any warranty; 00010 without even the implied warranty of merchantability or fitness 00011 for a particular purpose. The author and his publisher are not 00012 responsible for any damages, direct or incidental, resulting 00013 from the use or non-use of these Example Files. 00014 00015 The Example Files may contain defects, and some contain deliberate 00016 coding mistakes that were included for educational reasons. 00017 You are responsible for determining if and how the Example Files 00018 are to be used. 00019 00020 */ 00021 #include "defs.h" 00022 #include "smi_skt.h" 00023 #include "../c8/ssi.h" 00024 /*[SMIQ_SKT]*/ 00025 typedef struct { 00026 SMIENTITY sq_entity; 00027 SSI *sq_ssip; 00028 struct client_id sq_client; /* client ID */ 00029 size_t sq_msgsize; /* msg size */ 00030 struct smi_msg *sq_msg; /* msg buffer */ 00031 } SMIQ_SKT; 00032 /*[smi_open_skt]*/ 00033 SMIQ *smi_open_skt(const char *name, SMIENTITY entity, size_t msgsize) 00034 { 00035 SMIQ_SKT *p = NULL; 00036 00037 ec_null( p = calloc(1, sizeof(SMIQ_SKT)) ) 00038 p->sq_msgsize = msgsize + offsetof(struct smi_msg, smi_data); 00039 ec_null( p->sq_msg = calloc(1, p->sq_msgsize) ) 00040 p->sq_entity = entity; 00041 ec_null( p->sq_ssip = ssi_open(name, entity == SMI_SERVER) ) 00042 return (SMIQ *)p; 00043 00044 EC_CLEANUP_BGN 00045 (void)smi_close_skt((SMIQ *)p); 00046 return NULL; 00047 EC_CLEANUP_END 00048 } 00049 /*[smi_close_skt]*/ 00050 bool smi_close_skt(SMIQ *sqp) 00051 { 00052 SMIQ_SKT *p = (SMIQ_SKT *)sqp; 00053 SSI *ssip; 00054 00055 if (p != NULL) { 00056 ssip = p->sq_ssip; 00057 free(p->sq_msg); 00058 free(p); 00059 if (ssip != NULL) 00060 ec_false( ssi_close(ssip) ) 00061 } 00062 return true; 00063 00064 EC_CLEANUP_BGN 00065 return false; 00066 EC_CLEANUP_END 00067 } 00068 /*[smi_send_getaddr_skt]*/ 00069 bool smi_send_getaddr_skt(SMIQ *sqp, struct client_id *client, 00070 void **addr) 00071 { 00072 SMIQ_SKT *p = (SMIQ_SKT *)sqp; 00073 00074 if (p->sq_entity == SMI_SERVER) 00075 p->sq_client = *client; 00076 *addr = p->sq_msg; 00077 return true; 00078 } 00079 /*[smi_send_release_skt]*/ 00080 bool smi_send_release_skt(SMIQ *sqp) 00081 { 00082 SMIQ_SKT *p = (SMIQ_SKT *)sqp; 00083 int fd; 00084 00085 if (p->sq_entity == SMI_SERVER) 00086 ec_neg1( fd = p->sq_client.c_id1 ) 00087 else 00088 ec_neg1( fd = ssi_get_server_fd(p->sq_ssip) ) 00089 ec_neg1( writeall(fd, p->sq_msg, p->sq_msgsize) ) 00090 return true; 00091 00092 EC_CLEANUP_BGN 00093 return false; 00094 EC_CLEANUP_END 00095 } 00096 /*[smi_receive_getaddr_skt]*/ 00097 bool smi_receive_getaddr_skt(SMIQ *sqp, void **addr) 00098 { 00099 SMIQ_SKT *p = (SMIQ_SKT *)sqp; 00100 ssize_t /*nremain,*/ nread; 00101 int fd; 00102 00103 *addr = p->sq_msg; 00104 while (true) { 00105 if (p->sq_entity == SMI_SERVER) 00106 ec_neg1( fd = ssi_wait_server(p->sq_ssip) ) 00107 else 00108 ec_neg1( fd = ssi_get_server_fd(p->sq_ssip) ) 00109 ec_neg1( nread = readall(fd, p->sq_msg, p->sq_msgsize) ) 00110 if (nread == 0) { 00111 if (p->sq_entity == SMI_SERVER) { 00112 ec_false( ssi_close_fd(p->sq_ssip, fd) ) 00113 continue; 00114 } 00115 else { 00116 errno = EINVAL; /* book had ENOMSG, but Darwin doesn't have it */ 00117 EC_FAIL 00118 } 00119 } 00120 else 00121 break; 00122 } 00123 if (p->sq_entity == SMI_SERVER) 00124 p->sq_msg->smi_client.c_id1 = fd; 00125 return true; 00126 00127 EC_CLEANUP_BGN 00128 return false; 00129 EC_CLEANUP_END 00130 } 00131 /*[smi_receive_release_skt]*/ 00132 bool smi_receive_release_skt(SMIQ *sqp) 00133 { 00134 return true; 00135 } 00136 /*[]*/