#ifdef USE_PCH #include "pch.h" #else #include #include #include #include #include #include #include #include #include #include #include "sitecing/sitecing_util.h" #endif namespace sitecing { /* * XXX: all of these utilities could be sheerly optimized. */ string strip_prefix(const string& str,const string& prefix) { if( (str.length()=0); struct flock fl; fl.l_type = F_WRLCK; fl.l_whence=SEEK_SET; fl.l_start=fl.l_len=0; for(int tries=3;tries;tries--) { if(!fcntl(fd,F_SETLK,&fl)) return; sleep(8); } throw konforka::exception(CODEPOINT,"failed to obtain file lock"); } void file_lock::unlock() { if(fd<0) return; struct flock fl; fl.l_type = F_UNLCK; fl.l_whence=SEEK_SET; fl.l_start=fl.l_len=0; int rv = fcntl(fd,F_SETLK,&fl); close(fd); fd=-1; if(rv) throw konforka::exception(CODEPOINT,"failed to release file lock"); } void pid_file::set(const string& f,bool u) { ofstream of(f.c_str(),ios::trunc); if(!of) throw konforka::exception(CODEPOINT,"failed to open file for writing pid"); of << getpid() << endl; of.close(); file_name = f; unlink_pid = u; } void pid_file::unlink() { if(!unlink_pid) return; ::unlink(file_name.c_str()); } void semaphore::init() { deinit(); semid = semget(IPC_PRIVATE,1,IPC_CREAT|0600); if(semid<0) throw konforka::exception(CODEPOINT,"failed to semget()"); if(semctl(semid,0,SETVAL,1)) throw konforka::exception(CODEPOINT,"failed to semctl()"); } void semaphore::deinit() { if(semid<0) return; semctl(semid,0,IPC_RMID,0); } 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; } void auto_chdir::pushdir(const string& td,bool ap) { /* 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... } }