📄 log.cc
字号:
throw CORBA::PERSIST_STORE(); } checkpointNeeded = 1; }}voidomniNameslog::checkpoint(void){ if (!checkpointNeeded) { // cerr << ts.t() << "No checkpoint needed." << endl; return; } cerr << ts.t() << "Checkpointing Phase 1: Prepare." << endl; // // Get the global lock as a reader. This means clients will still be able // to do "resolve" and "list" operations, but anyone who tries to alter // the state in any way will block until we've finished. // NamingContext_i::lock.readerIn(); ofstream ckpf; int fd = -1; try {#ifdef USE_STREAM_OPEN ckpf.OPEN(checkpt,ios::out|ios::trunc,0666); if (!ckpf) { cerr << ts.t() << "Error: cannot open checkpoint file '" << checkpt << "' for writing." << endl; throw IOError(); }#else# ifdef __WIN32__ fd = _open(checkpt, O_WRONLY | O_CREAT | O_TRUNC, _S_IWRITE);# else fd = open(checkpt, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, 0666);# endif if (fd < 0) { cerr << ts.t() << "Error: cannot open checkpoint file '" << checkpt << "' for writing." << endl; throw IOError(); } ckpf.attach(fd);#endif putPort(port, ckpf); NamingContext_i* nci; for (nci = NamingContext_i::headContext; nci; nci = nci->next) { PortableServer::ObjectId_var id = nci->PR_id(); putCreate(id, ckpf); } for (nci = NamingContext_i::headContext; nci; nci = nci->next) { for (ObjectBinding* ob = nci->headBinding; ob; ob = ob->next) { putBind(nci->_this(), ob->binding.binding_name, ob->object, ob->binding.binding_type, ckpf); } } ckpf.close(); if (!ckpf) throw IOError();// a bug in sparcworks C++ means that the fd doesn't get closed.#if defined(__sunos__) && defined(__SUNPRO_CC) && __SUNPRO_CC < 0x500 if (close(fd) < 0) throw IOError();#endif } catch (IOError& ex) { cerr << ts.t() << flush; perror("I/O error writing checkpoint file"); cerr << "Abandoning checkpoint" << endl; ckpf.close();// a bug in sparcworks C++ means that the fd doesn't get closed.#if defined(__sunos__) && defined(__SUNPRO_CC) && __SUNPRO_CC < 0x500 close(fd);#endif NamingContext_i::lock.readerOut(); unlink(checkpt); return; } // // Now commit the checkpoint to become the active log. // cerr << ts.t() << "Checkpointing Phase 2: Commit." << endl;// a bug in sparcworks C++ means that the fd doesn't get closed.#if defined(__sunos__) && defined(__SUNPRO_CC) && __SUNPRO_CC < 0x500 close(logf.rdbuf()->fd());#endif logf.close(); unlink(backup);#if defined(__WIN32__) if (!CopyFile(active,backup,TRUE)) {#elif defined(__VMS) if (rename(active, backup) < 0) {#else if (link(active,backup) < 0) {#endif // Failure here leaves old active and checkpoint file. cerr << ts.t() << "Error: failed to link backup file '" << backup << "' to old log file '" << active << "'." << endl; exit(1); }#ifndef __VMS if (unlink(active) < 0) { // Failure here leaves active and backup pointing to the same (old) file. cerr << ts.t() << "Error: failed to unlink old log file '" << active << "'." << endl; exit(1); }#endif#if defined(__WIN32__) if (!CopyFile(checkpt,active,TRUE)) {#elif defined(__VMS) if (rename(checkpt,active) < 0) {#else if (link(checkpt,active) < 0) {#endif // Failure here leaves no active but backup points to the old file. cerr << ts.t() << "Error: failed to link log file '" << active << "' to checkpoint file '" << checkpt << "'." << endl; exit(1); }#ifndef __VMS if (unlink(checkpt) < 0) { // Failure here leaves active and checkpoint pointing to the same file. cerr << ts.t() << "Error: failed to unlink checkpoint file '" << checkpt << "'." << endl; exit(1); }#endif#ifdef USE_STREAM_OPEN logf.OPEN(active,ios::out|ios::app,0666); if (!logf) { cerr << ts.t() << "Error: cannot open log file '" << active << "' for writing." << endl; exit(1); }#else# ifdef __WIN32__ fd = _open(active, O_WRONLY | O_APPEND);# else fd = open(active, O_WRONLY | O_APPEND | O_SYNC);# endif if (fd < 0) { cerr << ts.t() << "Error: cannot open new log file '" << active << "' for writing." << endl; exit(1); } logf.attach(fd);#endif NamingContext_i::lock.readerOut(); cerr << ts.t() << "Checkpointing completed." << endl; checkpointNeeded = 0;}voidomniNameslog::putPort(int p, ostream& file){ file << "port " << p << '\n'; if (!file) throw IOError();}//// getPort is different from the other get... functions in that the "command"// ("port") hasn't been read yet, and also we cannot use any CORBA stuff// since ORB_init may not have been called yet.//voidomniNameslog::getPort(istream& file){ char* str; getNonfinalString(str, file); if (strcmp(str, "port") != 0) { cerr << ts.t() << "Error: log file doesn't start with \"port\"." << endl; throw ParseError(); } delete [] str; getFinalString(str, file); port = atoi(str); delete [] str; if (port == 0) { cerr << ts.t() << "Error: invalid port specified in log file." << endl; throw ParseError(); }}voidomniNameslog::putCreate(const PortableServer::ObjectId& id, ostream& file){ file << "create "; putKey(id, file); file << '\n'; if (!file) throw IOError();}voidomniNameslog::getCreate(istream& file){ // // Argument to "create" is the object key of the naming context. // PortableServer::ObjectId id; NamingContext_i* rc; getKey(id, file); if (id.length() == 12) // SYS_ASSIGNED_ID_SIZE + TRANSIENT_SUFFIX_SIZE rc = new NamingContext_i(poa, id, this); else rc = new NamingContext_i(ins_poa, id, this); rc->_remove_ref();}voidomniNameslog::putDestroy(CosNaming::NamingContext_ptr nc, ostream& file){ file << "destroy "; CORBA::String_var s = orb->object_to_string(nc); putString(s, file); file << '\n'; if (!file) throw IOError();}voidomniNameslog::getDestroy(istream& file){ // // Argument to "destroy" is NamingContext IOR. // char* str; getFinalString(str, file); CORBA::Object_var o; try { o = orb->string_to_object(str); } catch (...) { cerr << ts.t() << "getDestroy: invalid IOR." << endl; delete [] str; throw ParseError(); } delete [] str; CosNaming::NamingContext_var nc = CosNaming::NamingContext::_narrow(o); if (CORBA::is_nil(nc)) { cerr << ts.t() << "getDestroy: IOR not a NamingContext." << endl; throw ParseError(); } nc->destroy();}voidomniNameslog::putBind(CosNaming::NamingContext_ptr nc, const CosNaming::Name& n, CORBA::Object_ptr obj, CosNaming::BindingType t, ostream& file){ file << "bind "; CORBA::String_var s = orb->object_to_string(nc); putString(s, file); file << ' '; putString(n[0].id, file); file << ' '; putString(n[0].kind, file); if (t == CosNaming::nobject) file << " nobject "; else file << " ncontext "; s = orb->object_to_string(obj); putString(s, file); file << '\n'; if (!file) throw IOError();}voidomniNameslog::getBind(istream& file){ // // First arg is NamingContext IOR. // char* str; getNonfinalString(str, file); CORBA::Object_var o; try { o = orb->string_to_object(str); } catch (...) { cerr << ts.t() << "getBind: invalid IOR." << endl; delete [] str; throw ParseError(); } delete [] str; CosNaming::NamingContext_var nc = CosNaming::NamingContext::_narrow(o); if (CORBA::is_nil(nc)) { cerr << ts.t() << "getBind: IOR not a NamingContext." << endl; throw ParseError(); } // // 2nd & 3rd args are name id and kind. // CosNaming::Name name(1); name.length(1); getNonfinalString(str, file); name[0].id = str; getNonfinalString(str, file); name[0].kind = str; // // 4th arg is binding type. // char* bindingType; getNonfinalString(bindingType, file); // // 5th arg is object IOR. // getFinalString(str, file); try { o = orb->string_to_object(str); } catch (...) { cerr << ts.t() << "getDestroy: invalid IOR." << endl; delete [] str; throw ParseError(); } delete [] str; if (strcmp(bindingType, "ncontext") == 0) { CosNaming::NamingContext_var nc2 = CosNaming::NamingContext::_narrow(o); if (CORBA::is_nil(nc2)) { cerr << ts.t() << "bind: IOR not a NamingContext." << endl; throw ParseError(); } nc->rebind_context(name, nc2); } else { nc->rebind(name, o); } delete [] bindingType;}voidomniNameslog::putUnbind(CosNaming::NamingContext_ptr nc, const CosNaming::Name& n, ostream& file){ file << "unbind "; CORBA::String_var s = orb->object_to_string(nc); putString(s, file); file << ' '; putString(n[0].id, file); file << ' '; putString(n[0].kind, file); file << '\n'; if (!file) throw IOError();}voidomniNameslog::getUnbind(istream& file){ // // First arg is NamingContext IOR. // char* str; getNonfinalString(str, file); CORBA::Object_var o; try { o = orb->string_to_object(str); } catch (...) { cerr << ts.t() << "getUnbind: invalid IOR." << endl; delete [] str; throw ParseError(); } delete [] str; CosNaming::NamingContext_var nc = CosNaming::NamingContext::_narrow(o); if (CORBA::is_nil(nc)) { cerr << ts.t() << "getUnbind: IOR not a NamingContext." << endl; throw ParseError(); } // // 2nd & 3rd args are name id and kind. // CosNaming::Name name(1); name.length(1); getNonfinalString(str, file); name[0].id = str; getFinalString(str, file); name[0].kind = str; nc->unbind(name);}voidomniNameslog::putKey(const PortableServer::ObjectId& id, ostream& file){ file << hex; for (unsigned int i = 0; i < id.length(); i++) { file << setfill('0') << setw(2) << (int)id[i]; } file << dec;}voidomniNameslog::getKey(PortableServer::ObjectId& id, istream& file){ char* str; getFinalString(str, file); int l = strlen(str) / 2; id.length(l); char* p = str; for (int i = 0; i < l; i++) { int n; sscanf(p,"%02x",&n); id[i] = n; p += 2; } delete [] str;}voidomniNameslog::putString(const char* str, ostream& file){ for (int i = strlen(str); i > 0; i--, str++) { switch (*str) { case '\\': file.put('\\'); file.put('\\'); break; case ' ': file.put('\\'); file.put(' '); break; case '\n': file.put('\\'); file.put('n'); break; case '\t': file.put('\\'); file.put('t'); break; case '\r': file.put('\\'); file.put('r'); break; default: file.put(*str); break; } }}voidomniNameslog::getFinalString(char*& buf, istream& file){ if (getString(buf, file) != '\n') throw ParseError(); line++;}voidomniNameslog::getNonfinalString(char*& buf, istream& file){ if (getString(buf, file) != ' ') throw ParseError();}intomniNameslog::getString(char*& buf, istream& file){ int bufsz = 512; buf = new char[bufsz]; char* p = buf; int backslash = 0; while (1) { char c; if (!file.get(c)) { // I/O problem or EOF delete [] buf; if (!file.eof()) throw IOError(); throw ParseError(); } if (backslash) { backslash = 0; switch (c) { case '\\': *p++ = '\\'; break; case ' ': *p++ = ' '; break; case 'n': *p++ = '\n'; break; case 't': *p++ = '\t'; break; case 'r': *p++ = '\r'; break; default: cerr << ts.t() << "Unknown character following '\\' in log file" << endl; } } else { switch (c) { case '\\': backslash = 1; break; case ' ': case '\n': *p = '\0'; return (int)c; break; default: *p++ = c; } } if (p == (buf + bufsz)) { // buffer is too small char *obuf = buf; buf = new char[bufsz+bufsz]; memcpy(buf, obuf, bufsz); delete [] obuf; p = buf + bufsz; bufsz += bufsz; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -