©2004 by Marc J. Rochkind. All rights reserved. Portions marked "Open Source" may be copied under license.

 

Main Page   Modules   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

c7/smi_msg.c

Go to the documentation of this file.
00001 /*
00002     SMI - System V messages
00003     AUP2, Sec. 7.05.3
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_msg.h"
00023 #ifdef HAVE_SYSVMSG
00024 #include <sys/msg.h>
00025 /*[top]*/
00026 typedef struct {
00027     SMIENTITY sq_entity;    /* entity */
00028     int sq_qid_server;  /* server identifier */
00029     int sq_qid_client;  /* client identifier (not used by server) */
00030     char sq_name[SERVER_NAME_MAX];  /* server name */
00031     struct client_id sq_client;     /* client ID */
00032     size_t sq_msgsize; /* msg size */
00033     struct smi_msg *sq_msg; /* msg buffer */
00034 } SMIQ_MSG;
00035 /*[mkmsg_name_server]*/
00036 static void mkmsg_name_server(const SMIQ_MSG *p, char *msgname,
00037   size_t msgname_max)
00038 {
00039     snprintf(msgname, msgname_max, "/tmp/smimsg-%s", p->sq_name);
00040 }
00041 /*[smi_open_msg]*/
00042 SMIQ *smi_open_msg(const char *name, SMIENTITY entity, size_t msgsize)
00043 {
00044     SMIQ_MSG *p = NULL;
00045     char msgname[SERVER_NAME_MAX + 100];
00046     key_t key;
00047 
00048     ec_null( p = calloc(1, sizeof(SMIQ_MSG)) )
00049     p->sq_msgsize = msgsize + offsetof(struct smi_msg, smi_data);
00050     ec_null( p->sq_msg = calloc(1, p->sq_msgsize) )
00051     p->sq_qid_server = p->sq_qid_client = -1;
00052     p->sq_entity = entity;
00053     if (strlen(name) >= SERVER_NAME_MAX) {
00054         errno = ENAMETOOLONG;
00055         EC_FAIL
00056     }
00057     strcpy(p->sq_name, name);
00058     mkmsg_name_server(p, msgname, sizeof(msgname));
00059     (void)close(open(msgname, O_WRONLY | O_CREAT, 0));
00060     ec_neg1( key = ftok(msgname, 1) )
00061     if (p->sq_entity == SMI_SERVER) {
00062         if ((p->sq_qid_server = msgget(key, PERM_FILE)) != -1)
00063             (void)msgctl(p->sq_qid_server, IPC_RMID, NULL);
00064         ec_neg1( p->sq_qid_server = msgget(key, IPC_CREAT | PERM_FILE) )
00065     }
00066     else {
00067         ec_neg1( p->sq_qid_server = msgget(key, 0) )
00068         ec_neg1( p->sq_qid_client = msgget(IPC_PRIVATE, PERM_FILE) );
00069     }
00070     return (SMIQ *)p;
00071 
00072 EC_CLEANUP_BGN
00073     if (p != NULL)
00074         (void)smi_close_msg((SMIQ *)p);
00075     return NULL;
00076 EC_CLEANUP_END
00077 }
00078 /*[smi_close_msg]*/
00079 bool smi_close_msg(SMIQ *sqp)
00080 {
00081     SMIQ_MSG *p = (SMIQ_MSG *)sqp;
00082 
00083     if (p->sq_entity == SMI_SERVER) {
00084         char msgname[FILENAME_MAX]; // wrong symbol... need max pathname
00085 
00086         (void)msgctl(p->sq_qid_server, IPC_RMID, NULL);
00087         mkmsg_name_server(p, msgname, sizeof(msgname));
00088         (void)unlink(msgname);
00089     }
00090     else
00091         (void)msgctl(p->sq_qid_client, IPC_RMID, NULL);
00092     free(p->sq_msg);
00093     free(p);
00094     return true;
00095 }
00096 /*[smi_send_getaddr_msg]*/
00097 bool smi_send_getaddr_msg(SMIQ *sqp, struct client_id *client,
00098   void **addr)
00099 {
00100     SMIQ_MSG *p = (SMIQ_MSG *)sqp;
00101 
00102     if (p->sq_entity == SMI_SERVER)
00103         p->sq_client = *client;
00104     *addr = p->sq_msg;
00105     return true;
00106 }
00107 
00108 bool smi_send_release_msg(SMIQ *sqp)
00109 {
00110     SMIQ_MSG *p = (SMIQ_MSG *)sqp;
00111     int qid_receiver;
00112 
00113     p->sq_msg->smi_mtype = 1;
00114     if (p->sq_entity == SMI_SERVER)
00115         qid_receiver = p->sq_client.c_id1;
00116     else {
00117         qid_receiver = p->sq_qid_server;
00118         p->sq_msg->smi_client.c_id1 = p->sq_qid_client;
00119     }
00120     ec_neg1( msgsnd(qid_receiver, p->sq_msg,
00121       p->sq_msgsize - sizeof(p->sq_msg->smi_mtype), 0) )
00122     return true;
00123 
00124 EC_CLEANUP_BGN
00125     return false;
00126 EC_CLEANUP_END
00127 }
00128 /*[smi_receive_getaddr_msg]*/
00129 bool smi_receive_getaddr_msg(SMIQ *sqp, void **addr)
00130 {
00131     SMIQ_MSG *p = (SMIQ_MSG *)sqp;
00132     int qid_receiver;
00133     ssize_t nrcv;
00134 
00135     if (p->sq_entity == SMI_SERVER)
00136         qid_receiver = p->sq_qid_server;
00137     else
00138         qid_receiver = p->sq_qid_client;
00139     ec_neg1( nrcv = msgrcv(qid_receiver, p->sq_msg,
00140       p->sq_msgsize - sizeof(p->sq_msg->smi_mtype), 0, 0) )
00141     *addr = p->sq_msg;
00142     return true;
00143 
00144 EC_CLEANUP_BGN
00145     return false;
00146 EC_CLEANUP_END
00147 }
00148 
00149 bool smi_receive_release_msg(SMIQ *sqp)
00150 {
00151     return true;
00152 }
00153 /*[]*/
00154 
00155 #else /* HAVE_SYSVMSG */
00156 SMIQ *smi_open_msg(const char *name, SMIENTITY entity, size_t msgsize)
00157 {
00158     errno = ENOSYS;
00159     return NULL;
00160 }
00161 
00162 bool smi_close_msg(SMIQ *sqp)
00163 {
00164     errno = ENOSYS;
00165     return false;
00166 }
00167 
00168 bool smi_send_getaddr_msg(SMIQ *sqp, struct client_id *client,
00169   void **addr)
00170 {
00171     errno = ENOSYS;
00172     return false;
00173 }
00174 
00175 bool smi_send_release_msg(SMIQ *sqp)
00176 {
00177     errno = ENOSYS;
00178     return false;
00179 }
00180 
00181 bool smi_receive_getaddr_msg(SMIQ *sqp, void **addr)
00182 {
00183     errno = ENOSYS;
00184     return false;
00185 }
00186 
00187 bool smi_receive_release_msg(SMIQ *sqp)
00188 {
00189     errno = ENOSYS;
00190     return false;
00191 }
00192 
00193 #endif /* HAVE_SYSVMSG */

Generated on Fri Apr 23 10:56:59 2004 for AUP2 Example Source by doxygen 1.3.1