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);

Reply via email to