00001 #include <IPC/mensageiro.H>
00002
00003 bool IPC::Mensageiro::existe_instancia = false;
00004
00005 IPC::Mensageiro::Mensageiro(key_t const chave)
00006 {
00007 assert(!existe_instancia);
00008
00009 existe_instancia = true;
00010
00011
00012
00013
00014 int permissoes = (chave == key_t(getuid()))? 0660 : 0666;
00015
00016
00017 eu = int(getpid());
00018 meuUID = int(getuid());
00019
00020
00021
00022 if((id = msgget(chave, IPC_CREAT | permissoes)) == -1)
00023 throw Erro();
00024
00025 try {
00026
00027
00028
00029
00030
00031
00032
00033 outro = leBasicoInt(1, false);
00034
00035
00036
00037 servidor = false;
00038
00039
00040 envia(eu);
00041
00042 } catch(Erro) {
00043
00044
00045
00046 servidor = true;
00047
00048
00049
00050
00051
00052
00053 escreveBasicoInt(2, 0);
00054
00055
00056 escreveBasicoInt(1, eu);
00057
00058
00059
00060 outro = intRecebido();
00061 }
00062
00063
00064 envia(meuUID);
00065
00066
00067 outroUID = intRecebido();
00068 }
00069
00070 IPC::Mensageiro::~Mensageiro()
00071 {
00072 try {
00073 if(servidor) {
00074
00075
00076
00077 string mensagem;
00078 while((mensagem = stringRecebida()) != "TeRmInEi")
00079 ;
00080
00081
00082
00083 leBasicoInt(2);
00084
00085
00086
00087
00088
00089 try {
00090 leBasicoInt(2, false);
00091 escreveBasicoInt(2, 0);
00092 } catch(Erro) {
00093 msgctl(id, IPC_RMID, 0);
00094 }
00095
00096 } else {
00097
00098 envia("TeRmInEi");
00099 }
00100 } catch(Erro) {
00101
00102
00103
00104 }
00105 }
00106
00107 string IPC::Mensageiro::leBasico(int const tipo, bool const espera)
00108 {
00109 typedef string::size_type Tamanho;
00110 int flag = espera? 0 : IPC_NOWAIT;
00111
00112
00113 msgbuf *mensagem_ipc =
00114 static_cast<msgbuf*>(malloc(sizeof(long) + sizeof(Tamanho)));
00115 if(msgrcv(id, mensagem_ipc, sizeof(Tamanho), tipo, flag) == -1)
00116 throw Erro();
00117 Tamanho tamanho;
00118 memcpy(static_cast<void*>(&tamanho),
00119 static_cast<void*>(mensagem_ipc->mtext),
00120 sizeof(Tamanho));
00121 free(mensagem_ipc);
00122
00123
00124 mensagem_ipc =
00125 static_cast<msgbuf*>(malloc(sizeof(long) + tamanho + 1));
00126 if(msgrcv(id, mensagem_ipc, tamanho + 1, tipo, flag) == -1)
00127 throw Erro();
00128 string mensagem = mensagem_ipc->mtext;
00129 free(mensagem_ipc);
00130
00131 return mensagem;
00132 }
00133
00134 void IPC::Mensageiro::escreveBasico(int const tipo, string const& mensagem)
00135 {
00136 typedef string::size_type Tamanho;
00137
00138
00139 msgbuf *mensagem_ipc =
00140 static_cast<msgbuf*>(malloc(sizeof(long) + sizeof(Tamanho)));
00141 mensagem_ipc->mtype = tipo;
00142 Tamanho tamanho = mensagem.size();
00143 memcpy(static_cast<void*>(mensagem_ipc->mtext),
00144 static_cast<void*>(&tamanho), sizeof(Tamanho));
00145 if(msgsnd(id, mensagem_ipc, sizeof(Tamanho), IPC_NOWAIT) == -1)
00146 throw Erro();
00147 free(mensagem_ipc);
00148
00149
00150 mensagem_ipc =
00151 static_cast<msgbuf*>(malloc(sizeof(long) + tamanho + 1));
00152 mensagem_ipc->mtype = tipo;
00153 strcpy(mensagem_ipc->mtext, mensagem.c_str());
00154 if(msgsnd(id, mensagem_ipc, tamanho + 1, IPC_NOWAIT) == -1)
00155 throw Erro();
00156 free(mensagem_ipc);
00157 }