Sched: make get_file_size request in file_upload_handler read-only

* If there is a size discrepancy between server and client this needs to be handled in handle_file_upload()
* Setting a write lock on a read only file does not work obviously. Instead try to see if another process has a write lock and continue if not. If another process is still writing to the file there is no need to determine the size.
This commit is contained in:
Christian Beer 2016-04-01 10:22:24 +02:00
parent 0f82e5cd2a
commit 614376be84
3 changed files with 29 additions and 4 deletions

View File

@ -475,7 +475,7 @@ int handle_get_file_size(char* file_name) {
return return_error(ERR_TRANSIENT, "Server is out of disk space"); return return_error(ERR_TRANSIENT, "Server is out of disk space");
} }
fd = open(path, O_WRONLY|O_APPEND); fd = open(path, O_RDONLY);
if (fd<0 && ENOENT==errno) { if (fd<0 && ENOENT==errno) {
// file does not exist: return zero length // file does not exist: return zero length
@ -495,8 +495,8 @@ int handle_get_file_size(char* file_name) {
); );
return return_error(ERR_TRANSIENT, "can't open file"); return return_error(ERR_TRANSIENT, "can't open file");
} }
#ifdef LOCK_FILES
if ((pid = mylockf(fd))) { if ((pid = checklockf(fd))) {
// file locked by another file_upload_handler: try again later // file locked by another file_upload_handler: try again later
// //
close(fd); close(fd);
@ -507,7 +507,8 @@ int handle_get_file_size(char* file_name) {
"[%s] locked by file_upload_handler PID=%d", file_name, pid "[%s] locked by file_upload_handler PID=%d", file_name, pid
); );
} }
// file exists, writable, not locked by anyone else, so return length. #endif
// file exists, readable, not locked by anyone else, so return length.
// //
retval = stat(path, &sbuf); retval = stat(path, &sbuf);
close(fd); close(fd);

View File

@ -239,6 +239,24 @@ int mylockf(int fd) {
return -1; return -1;
} }
// check if there is a write lock on the given file with given fd. Returns:
// 0 if there is no write lock
// PID (>0) of the process that has the lock
// -1 if error
//
int checklockf(int fd) {
struct flock fl;
fl.l_type=F_RDLCK;
fl.l_whence=SEEK_SET;
fl.l_start=0;
fl.l_len=0;
if (-1 != fcntl(fd, F_GETLK, &fl)) {
if (fl.l_type == F_UNLCK) return 0;
if (fl.l_pid>0) return fl.l_pid;
}
return -1;
}
bool is_arg(const char* x, const char* y) { bool is_arg(const char* x, const char* y) {
char buf[256]; char buf[256];
strcpy(buf, "--"); strcpy(buf, "--");

View File

@ -60,6 +60,12 @@ extern int dir_hier_url(
// //
extern int mylockf(int fd); extern int mylockf(int fd);
// returns zero if there is no write lock on file with file descriptor fd.
// returns < 0 if error
// returns PID > 0 of the process that has the lock
//
extern int checklockf(int fd);
// return true if x is -y or --y (for argv processing) // return true if x is -y or --y (for argv processing)
// //
extern bool is_arg(const char*, const char*); extern bool is_arg(const char*, const char*);