From 627fd8a8aa380c3343800012c58ff0431c566614 Mon Sep 17 00:00:00 2001
From: Frederic Culot <calcurse@culot.org>
Date: Sun, 21 Jun 2009 18:16:21 +0000
Subject: Basic lock mechanism implemented to avoid having two calcurse
 instances running at the same time.

---
 src/calcurse.c |  6 ++++--
 src/io.c       | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++---
 src/io.h       |  4 +++-
 src/utils.c    |  3 ++-
 src/vars.c     |  3 ++-
 src/vars.h     |  6 +++++-
 6 files changed, 66 insertions(+), 9 deletions(-)

(limited to 'src')

diff --git a/src/calcurse.c b/src/calcurse.c
index 552cfb4..30beffb 100755
--- a/src/calcurse.c
+++ b/src/calcurse.c
@@ -1,4 +1,4 @@
-/*	$calcurse: calcurse.c,v 1.78 2009/01/24 18:45:35 culot Exp $	*/
+/*	$calcurse: calcurse.c,v 1.79 2009/06/21 18:16:22 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
@@ -88,7 +88,9 @@ main (int argc, char **argv)
   non_interactive = parse_args (argc, argv, &conf);
   if (non_interactive)
     exit_calcurse (EXIT_SUCCESS);
-
+  else
+    io_set_lock ();
+  
   /* Begin of interactive mode with ncurses interface. */
   sigs_init (&sigact);		/* signal handling init */
   initscr ();			/* start the curses mode */
diff --git a/src/io.c b/src/io.c
index e277ae4..bef5501 100755
--- a/src/io.c
+++ b/src/io.c
@@ -1,4 +1,4 @@
-/*	$calcurse: io.c,v 1.59 2009/06/01 08:04:04 culot Exp $	*/
+/*	$calcurse: io.c,v 1.60 2009/06/21 18:16:22 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
@@ -679,7 +679,8 @@ io_init (char *cfile, char *datadir)
       (void)snprintf (path_conf, BUFSIZ, "%s/" CONF_PATH_NAME, home);
       (void)snprintf (path_notes, BUFSIZ, "%s/" NOTES_DIR_NAME, home);
       (void)snprintf (path_apts, BUFSIZ, "%s/" APTS_PATH_NAME, home);
-      (void)snprintf (path_keys, BUFSIZ, "%s/" KEYS_PATH_NAME, home);      
+      (void)snprintf (path_keys, BUFSIZ, "%s/" KEYS_PATH_NAME, home);
+      (void)snprintf (path_lock, BUFSIZ, "%s/" LOCK_PATH_NAME, home);
     }
   else
     {
@@ -691,7 +692,8 @@ io_init (char *cfile, char *datadir)
       (void)snprintf (path_dir, BUFSIZ, "%s/" DIR_NAME, home);
       (void)snprintf (path_todo, BUFSIZ, "%s/" TODO_PATH, home);
       (void)snprintf (path_conf, BUFSIZ, "%s/" CONF_PATH, home);
-      (void)snprintf (path_keys, BUFSIZ, "%s/" KEYS_PATH, home);      
+      (void)snprintf (path_keys, BUFSIZ, "%s/" KEYS_PATH, home);
+      (void)snprintf (path_lock, BUFSIZ, "%s/" LOCK_PATH, home);      
       (void)snprintf (path_notes, BUFSIZ, "%s/" NOTES_DIR, home);
       if (cfile == NULL)
         {
@@ -2820,3 +2822,48 @@ io_stop_psave_thread (void)
   if (io_t_psave)
     pthread_cancel (io_t_psave);  
 }
+
+/*
+ * This sets a lock file to prevent from having two different instances of
+ * calcurse running.
+ * If the lock cannot be obtained, then warn the user and exit calcurse.
+ * Else, create a .calcurse.lock file in the user defined directory, which
+ * will be removed when calcurse exits.
+ *
+ * Note: when creating the lock file, the interactive mode is not initialized
+ * yet.
+ */
+void
+io_set_lock (void)
+{
+  FILE *lock;
+
+  if ((lock = fopen (path_lock, "r")) != NULL)
+    {
+      (void)fprintf (stderr,
+                     _("\nWARNING: it seems that another calcurse instance is "
+                       "already running.\n"
+                       "If this is not the case, please remove the following "
+                       "lock file: \n\"%s\"\n"
+                       "and restart calcurse.\n"), path_lock);
+      exit_calcurse (EXIT_FAILURE);
+    }
+  else
+    {
+      if ((lock = fopen (path_lock, "w")) == NULL)
+	{
+	  (void)fprintf (stderr, _("FATAL ERROR: could not create %s: %s\n"),
+                         path_lock, strerror (errno));
+	  exit_calcurse (EXIT_FAILURE);
+	}
+      (void)fclose (lock);
+    }
+}  
+
+/* Used when calcurse exits to remove the lock file. */
+void
+io_unset_lock (void)
+{
+  if (unlink (path_lock) != 0)
+    EXIT (_("Could not remove lock file: %s\n"), strerror (errno));
+}
diff --git a/src/io.h b/src/io.h
index ee70da6..edaec47 100755
--- a/src/io.h
+++ b/src/io.h
@@ -1,4 +1,4 @@
-/*	$calcurse: io.h,v 1.18 2008/12/28 19:41:45 culot Exp $	*/
+/*	$calcurse: io.h,v 1.19 2009/06/21 18:16:22 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
@@ -68,5 +68,7 @@ void        io_log_display (io_file_t *, char *, char *);
 void        io_log_free (io_file_t *);
 void        io_start_psave_thread (conf_t *);
 void        io_stop_psave_thread (void);
+void        io_set_lock (void);
+void        io_unset_lock (void);
 
 #endif /* !CALCURSE_IO_H */
diff --git a/src/utils.c b/src/utils.c
index 80101b9..42c4170 100755
--- a/src/utils.c
+++ b/src/utils.c
@@ -1,4 +1,4 @@
-/*	$calcurse: utils.c,v 1.69 2009/06/21 14:42:50 culot Exp $	*/
+/*	$calcurse: utils.c,v 1.70 2009/06/21 18:16:23 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
@@ -74,6 +74,7 @@ exit_calcurse (int status)
   notify_free_app ();
   keys_free ();
   mem_stats ();
+  io_unset_lock ();
   exit (status);
 }
 
diff --git a/src/vars.c b/src/vars.c
index 9e7e529..36029e5 100755
--- a/src/vars.c
+++ b/src/vars.c
@@ -1,4 +1,4 @@
-/*	$calcurse: vars.c,v 1.14 2009/01/02 22:28:54 culot Exp $	*/
+/*	$calcurse: vars.c,v 1.15 2009/06/21 18:16:23 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
@@ -90,6 +90,7 @@ char path_apts[] = "";
 char path_conf[] = "";
 char path_notes[] = "";
 char path_keys[] = "";
+char path_lock[] = "";
 
 /* Variable to handle pads. */
 struct pad_s apad;
diff --git a/src/vars.h b/src/vars.h
index a47c611..d9410f7 100755
--- a/src/vars.h
+++ b/src/vars.h
@@ -1,4 +1,4 @@
-/*	$calcurse: vars.h,v 1.31 2009/01/23 21:09:21 culot Exp $	*/
+/*	$calcurse: vars.h,v 1.32 2009/06/21 18:16:23 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
@@ -49,11 +49,14 @@
 #define APTS_PATH_NAME   "apts"
 #define CONF_PATH_NAME   "conf"
 #define KEYS_PATH_NAME   "keys"
+#define LOCK_PATH_NAME   ".calcurse.lock"
 #define NOTES_DIR_NAME   "notes/"
+
 #define TODO_PATH        DIR_NAME TODO_PATH_NAME
 #define APTS_PATH        DIR_NAME APTS_PATH_NAME
 #define CONF_PATH        DIR_NAME CONF_PATH_NAME
 #define KEYS_PATH        DIR_NAME KEYS_PATH_NAME
+#define LOCK_PATH        DIR_NAME LOCK_PATH_NAME
 #define NOTES_DIR        DIR_NAME NOTES_DIR_NAME
 
 #define ATTR_FALSE	0
@@ -145,6 +148,7 @@ extern char           path_apts[BUFSIZ];
 extern char           path_conf[BUFSIZ];
 extern char           path_keys[BUFSIZ];
 extern char           path_notes[BUFSIZ];
+extern char           path_lock[BUFSIZ];
 extern struct pad_s   apad;
 extern struct nbar_s  nbar;
 
-- 
cgit v1.2.3-70-g09d2