From ed70a0cfa055fcd8c5243424ca8fb3e61ead2d8b Mon Sep 17 00:00:00 2001
From: tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>
Date: Mon, 19 Sep 2011 01:33:09 +0000
Subject: Copy tsak in from latest git Wait for tsak start before kdm init Set
 readonly access mode for SAK pipe in kdmtsak

git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1254374 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
---
 kdm/kfrontend/kgapp.cpp |  2 +-
 kdmlib/kdmtsak.cpp      |  8 ++---
 tsak/main.cpp           | 80 +++++++++++++++++++++++++++++++++++--------------
 3 files changed, 63 insertions(+), 27 deletions(-)

diff --git a/kdm/kfrontend/kgapp.cpp b/kdm/kfrontend/kgapp.cpp
index f610ea776..ac8bd793c 100644
--- a/kdm/kfrontend/kgapp.cpp
+++ b/kdm/kfrontend/kgapp.cpp
@@ -194,7 +194,7 @@ kg_main( const char *argv0 )
 	if (trinity_desktop_lock_use_sak) {
 		tsak = new KProcess;
 		*tsak << TQCString( argv0, strrchr( argv0, '/' ) - argv0 + 2 ) + "tsak";
-		tsak->start();
+		tsak->start(KProcess::Block);
 	}
 	if (tsak) {
 		tsak->closeStdin();
diff --git a/kdmlib/kdmtsak.cpp b/kdmlib/kdmtsak.cpp
index ebfedb261..cb3c5b3b2 100644
--- a/kdmlib/kdmtsak.cpp
+++ b/kdmlib/kdmtsak.cpp
@@ -138,14 +138,14 @@ int main (int argc, char *argv[])
 	if (verifier_result == 0) {
 			// OK, the calling process is authorized to retrieve SAK data
 			// First, flush the buffer
-			mPipe_fd = open(FIFO_FILE, O_RDWR | O_NONBLOCK);
+			mPipe_fd = open(FIFO_FILE, O_RDONLY | O_NONBLOCK);
 			numread = 1;
 			while (numread > 0) {
 				numread = read(mPipe_fd, readbuf, 6);
 			}
 			close(mPipe_fd);
 			// Now wait for SAK press
-			mPipe_fd = open(FIFO_FILE, O_RDWR);
+			mPipe_fd = open(FIFO_FILE, O_RDONLY);
 			while (mPipe_fd > -1) {
 				numread = read(mPipe_fd, readbuf, 6);
 				readbuf[numread] = 0;
@@ -158,13 +158,13 @@ int main (int argc, char *argv[])
 					else {
 						usleep(100);
 						// Flush the buffer
-						mPipe_fd = open(FIFO_FILE, O_RDWR | O_NONBLOCK);
+						mPipe_fd = open(FIFO_FILE, O_RDONLY | O_NONBLOCK);
 						numread = 1;
 						while (numread > 0) {
 							numread = read(mPipe_fd, readbuf, 6);
 						}
 						close(mPipe_fd);
-						mPipe_fd = open(FIFO_FILE, O_RDWR);
+						mPipe_fd = open(FIFO_FILE, O_RDONLY);
 					}
 				}
 				else {
diff --git a/tsak/main.cpp b/tsak/main.cpp
index 2b51dbc85..b73609a67 100644
--- a/tsak/main.cpp
+++ b/tsak/main.cpp
@@ -144,7 +144,47 @@ void tearDownPipe()
 	}
 }
 
-void setupPipe()
+bool setFileLock(int fd, bool close_on_failure)
+{
+	struct flock fl;
+	
+	fl.l_type = F_WRLCK;
+	fl.l_whence = SEEK_SET;
+	fl.l_start = 0;
+	fl.l_len = 1;
+
+	// Set the exclusive file lock
+	if (fcntl(mPipe_fd_out, F_SETLK, &fl) == -1) {
+		close(mPipe_fd_out);
+		return false;
+	}
+
+	return true;
+}
+
+bool checkFileLock()
+{
+	struct flock fl;
+
+	fl.l_type    = F_WRLCK;   /* Test for any lock on any part of file. */
+	fl.l_start   = 0;
+	fl.l_whence  = SEEK_SET;
+	fl.l_len     = 0;
+
+	int fd = open(FIFO_FILE_OUT, O_RDWR | O_NONBLOCK);
+	fcntl(fd, F_GETLK, &fl);  /* Overwrites lock structure with preventors. */
+
+	if (fd > -1) {
+		if (fl.l_type == F_WRLCK) {
+			return false;
+		}
+		return true;
+	}
+
+	return true;
+}
+
+bool setupPipe()
 {
 	/* Create the FIFOs if they do not exist */
 	umask(0);
@@ -153,30 +193,13 @@ void setupPipe()
 	mknod(FIFO_FILE_OUT, S_IFIFO|0600, 0);
 	chmod(FIFO_FILE_OUT, 0600);
 	
-	mPipe_fd_out = open(FIFO_FILE_OUT, O_WRONLY | O_NONBLOCK);
+	mPipe_fd_out = open(FIFO_FILE_OUT, O_RDWR | O_NONBLOCK);
 	if (mPipe_fd_out > -1) {
 		mPipeOpen_out = true;
 	}
-}
 
-bool checkLocks()
-{
-	int fdlock;
-	struct flock fl;
-	
-	fl.l_type = F_WRLCK;
-	fl.l_whence = SEEK_SET;
-	fl.l_start = 0;
-	fl.l_len = 1;
-
-	fdlock = open(FIFO_FILE_OUT, O_RDWR | O_NONBLOCK);
-	if (fdlock != -1) {
-		if(fcntl(fdlock, F_SETLK, &fl) == -1) {
-			return 0;
-		}
-	}
-
-	return 1;
+	// Set the exclusive file lock
+	return setFileLock(mPipe_fd_out, true);
 }
 
 class PipeHandler
@@ -214,13 +237,18 @@ int main (int argc, char *argv[])
 		}
 	}
 
-	if (!checkLocks()) {
+	// Check for existing file locks
+	if (!checkFileLock()) {
 		fprintf(stderr, "Another instance of this program is already running\n");
 		return 8;
 	}
 
 	// Create the output pipe
 	PipeHandler controlpipe;
+	if (!setupPipe()) {
+		fprintf(stderr, "Another instance of this program is already running\n");
+		return 8;
+	}
 
 	while (1) {
 		if ((getuid ()) != 0) {
@@ -283,6 +311,14 @@ int main (int argc, char *argv[])
 						fprintf(stderr,"Device created.\n");
 
 						if (established == false) {
+							tearDownPipe();
+							int i=fork();
+							if (i<0) return 9; // fork failed
+							if (i>0) {
+								// close parent process
+								close(mPipe_fd_out);
+								return 0;
+							}
 							setupPipe();
 						}
 
-- 
cgit v1.2.3

