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 }