-rw-r--r-- | lib/sitecing_util.cc | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/lib/sitecing_util.cc b/lib/sitecing_util.cc index 9b6c54e..5466b28 100644 --- a/lib/sitecing_util.cc +++ b/lib/sitecing_util.cc @@ -167,112 +167,113 @@ namespace sitecing { } void semaphore::on() { assert(semid>=0); struct sembuf sb; sb.sem_num=0; sb.sem_op=-1; sb.sem_flg = SEM_UNDO; while(semop(semid,&sb,1)<0) { if(errno!=EINTR) throw konforka::exception(CODEPOINT,"failed to semop()"); } } void semaphore::off() { assert(semid>=0); struct sembuf sb; sb.sem_num=0; sb.sem_op=1; sb.sem_flg = SEM_UNDO; while(semop(semid,&sb,1)<0) { if(errno!=EINTR) throw konforka::exception(CODEPOINT,"failed to semop()"); } } void semaphore_lock::lock() { assert(sem); if(locked) return; sem->on(); locked = true; } void semaphore_lock::unlock() { if(!sem) return; if(!locked) return; sem->off(); locked=false; } string combine_path(const string& origin,const string& relative,int opts) { string r = normalize_path(relative,0); string rv; // XXX: what to do if relative is empty is a question, really. if(r.empty()) { return normalize_path( (opts&origin_is_file)?dir_name(origin):origin ,strip_leading_slash|restrict_dotdot|strip_trailing_slash); }else{ if(r[0]=='/') { r.erase(0,1); }else{ rv = normalize_path((opts&origin_is_file)?dir_name(origin):origin,restrict_dotdot|strip_trailing_slash); } } string::size_type lsl = rv.rfind('/'); for(string::size_type sl=r.find('/');sl!=string::npos;sl=r.find('/')) { assert(sl!=0); if(sl==1 && r[0]=='.') { // it's a "./" r.erase(0,2); }else if(sl==2 && r[0]=='.' && r[1]=='.') { // we have a "../" if(lsl==string::npos) { if(rv.empty() && (opts&fail_beyond_root)) throw utility_beyond_root(CODEPOINT,"went beyond root while combining path"); rv.clear(); }else{ rv.erase(lsl); lsl = rv.rfind('/'); } r.erase(0,3); }else{ // we have a "something/" lsl = rv.length(); rv += '/'; rv += r.substr(0,sl); r.erase(0,sl+1); } } if(r.empty()) return rv+'/'; if(r.length()==2 && r[0]=='.' && r[0]=='.') { if(lsl==string::npos) { if(rv.empty() & (opts&fail_beyond_root)) throw utility_beyond_root(CODEPOINT,"went beyond root while combining path"); return "/"; }else{ rv.erase(lsl+1); return rv; } } rv += '/'; rv += r; return rv; } void auto_chdir::pushdir(const string& td,bool ap) { - char *tmp = get_current_dir_name(); + /* TODO: make use of fchdir(2) instead */ + char *tmp = getcwd(0,0); assert(tmp); saved_pwd = tmp; free(tmp); autopop=ap; if(chdir(td.c_str())) throw konforka::exception(CODEPOINT,"failed to chdir()"); } void auto_chdir::popdir() { autopop=false; if(chdir(saved_pwd.c_str())) throw konforka::exception(CODEPOINT,"failed to chdir()"); // XXX: or should it be thrown? after all we call it from destructor... } } |