GUAC-236: Acquire read lock on input files for guacenc. Refuse to encode in-progress recordings.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/9d43e225 Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/9d43e225 Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/9d43e225 Branch: refs/heads/master Commit: 9d43e2259281dd8525e8339b6cec5d34bfaf0bcb Parents: 0361dd2 Author: Michael Jumper <[email protected]> Authored: Tue Mar 15 17:08:39 2016 -0700 Committer: Michael Jumper <[email protected]> Committed: Tue Mar 15 17:08:39 2016 -0700 ---------------------------------------------------------------------- src/guacenc/encode.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/9d43e225/src/guacenc/encode.c ---------------------------------------------------------------------- diff --git a/src/guacenc/encode.c b/src/guacenc/encode.c index d7fe8eb..6e5fd02 100644 --- a/src/guacenc/encode.c +++ b/src/guacenc/encode.c @@ -30,10 +30,10 @@ #include <guacamole/parser.h> #include <guacamole/socket.h> -#include <errno.h> -#include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> +#include <errno.h> +#include <fcntl.h> #include <string.h> #include <unistd.h> @@ -93,6 +93,32 @@ int guacenc_encode(const char* path, const char* out_path, const char* codec, return 1; } + /* Lock entire input file for reading by the current process */ + struct flock file_lock = { + .l_type = F_RDLCK, + .l_whence = SEEK_SET, + .l_start = 0, + .l_len = 0, + .l_pid = getpid() + }; + + /* Abort if file cannot be locked for reading */ + if (fcntl(fd, F_SETLK, &file_lock) == -1) { + + /* Warn if lock cannot be acquired */ + if (errno == EACCES || errno == EAGAIN) + guacenc_log(GUAC_LOG_WARNING, "Refusing to encode in-progress " + "recording \"%s\".", path); + + /* Log an error if locking fails in an unexpected way */ + else + guacenc_log(GUAC_LOG_ERROR, "Cannot lock \"%s\" for reading: %s", + path, strerror(errno)); + + close(fd); + return 1; + } + /* Allocate display for encoding process */ guacenc_display* display = guacenc_display_alloc(out_path, codec, width, height, bitrate);
