summaryrefslogtreecommitdiffabout
path: root/lib/sitecing_util.cc
Side-by-side diff
Diffstat (limited to 'lib/sitecing_util.cc') (more/less context) (ignore whitespace changes)
-rw-r--r--lib/sitecing_util.cc3
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...
}
}