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");
}
fd = open(path, O_WRONLY|O_APPEND);
fd = open(path, O_RDONLY);
if (fd<0 && ENOENT==errno) {
// 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");
}
if ((pid = mylockf(fd))) {
#ifdef LOCK_FILES
if ((pid = checklockf(fd))) {
// file locked by another file_upload_handler: try again later
//
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
);
}
// 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);
close(fd);

View File

@ -239,6 +239,24 @@ int mylockf(int fd) {
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) {
char buf[256];
strcpy(buf, "--");

View File

@ -60,6 +60,12 @@ extern int dir_hier_url(
//
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)
//
extern bool is_arg(const char*, const char*);