diff --git a/include/lighttpd/request.h b/include/lighttpd/request.h index ce27780..ddaceab 100644 --- a/include/lighttpd/request.h +++ b/include/lighttpd/request.h @@ -26,6 +26,8 @@ struct physical { GString *pathinfo; gboolean have_stat; + gboolean have_errno; + guint stat_errno; struct stat stat; /* contains valid data only if have_stat is true */ }; diff --git a/src/condition.c b/src/condition.c index 78a423d..eef605a 100644 --- a/src/condition.c +++ b/src/condition.c @@ -265,8 +265,8 @@ static handler_t condition_check_eval_bool(vrequest *vr, condition *cond, gboole if (cond->lvalue->type == COMP_PHYSICAL_ISDIR || cond->lvalue->type == COMP_PHYSICAL_ISFILE) { if (!vr->physical.have_stat) { - if (!vrequest_stat(vr)) { - switch (errno) { + if (vr->physical.have_errno || !vrequest_stat(vr)) { + switch (vr->physical.stat_errno) { case EACCES: vr->response.http_status = 403; break; case EBADF: vr->response.http_status = 500; break; case EFAULT: vr->response.http_status = 500; break; @@ -397,8 +397,8 @@ static handler_t condition_check_eval_int(vrequest *vr, condition *cond, gboolea val = vr->request.content_length; case COMP_PHYSICAL_SIZE: if (!vr->physical.have_stat) { - if (!vrequest_stat(vr)) { - switch (errno) { + if (vr->physical.have_errno || !vrequest_stat(vr)) { + switch (vr->physical.stat_errno) { case EACCES: vr->response.http_status = 403; break; case EBADF: vr->response.http_status = 500; break; case EFAULT: vr->response.http_status = 500; break; diff --git a/src/plugin_core.c b/src/plugin_core.c index 96a7b8b..26085d0 100644 --- a/src/plugin_core.c +++ b/src/plugin_core.c @@ -146,6 +146,7 @@ static handler_t core_handle_docroot(vrequest *vr, gpointer param, gpointer *con g_string_append_len(vr->physical.doc_root, GSTR_LEN((GString*) param)); /* reset stat info because path has changed */ vr->physical.have_stat = FALSE; + vr->physical.have_errno = FALSE; /* build physical path: docroot + uri.path */ g_string_truncate(vr->physical.path, 0); diff --git a/src/request.c b/src/request.c index a58a49d..8eae282 100644 --- a/src/request.c +++ b/src/request.c @@ -243,6 +243,7 @@ void physical_init(physical *phys) { phys->rel_path = g_string_sized_new(256); phys->pathinfo = g_string_sized_new(256); phys->have_stat = FALSE; + phys->have_errno = FALSE; } void physical_reset(physical *phys) { @@ -252,6 +253,7 @@ void physical_reset(physical *phys) { g_string_truncate(phys->rel_path, 0); g_string_truncate(phys->pathinfo, 0); phys->have_stat = FALSE; + phys->have_errno = FALSE; } void physical_clear(physical *phys) { @@ -261,4 +263,5 @@ void physical_clear(physical *phys) { g_string_free(phys->rel_path, TRUE); g_string_free(phys->pathinfo, TRUE); phys->have_stat = FALSE; + phys->have_errno = FALSE; } diff --git a/src/virtualrequest.c b/src/virtualrequest.c index f72190c..dbd1cd8 100644 --- a/src/virtualrequest.c +++ b/src/virtualrequest.c @@ -353,7 +353,10 @@ void vrequest_joblist_append(vrequest *vr) { gboolean vrequest_stat(vrequest *vr) { if (-1 == stat(vr->physical.path->str, &vr->physical.stat)) { - VR_DEBUG(vr, "stat(%s) failed: %s (%d)", vr->physical.path->str, g_strerror(errno), errno); + vr->physical.have_stat = FALSE; + vr->physical.have_errno = TRUE; + vr->physical.stat_errno = errno; + VR_DEBUG(vr, "stat(%s) failed: %s (%d)", vr->physical.path->str, g_strerror(vr->physical.stat_errno), vr->physical.stat_errno); return FALSE; }