diff -urN --minimal gnumeric-1.0.8/src/Makefile.am gnumeric-filelocking/src/Makefile.am --- gnumeric-1.0.8/src/Makefile.am Sun Apr 14 15:41:23 2002 +++ gnumeric-filelocking/src/Makefile.am Mon Jul 15 15:40:26 2002 @@ -245,7 +245,9 @@ xml-io.h \ xml-io-version.h \ xml-io-autoft.c \ - xml-io-autoft.h + xml-io-autoft.h \ + lock.c \ + lock.h # TODO : split the bonobo and corba tests one day GNUMERIC_CORBA = \ diff -urN --minimal gnumeric-1.0.8/src/file.c gnumeric-filelocking/src/file.c --- gnumeric-1.0.8/src/file.c Tue May 28 04:39:21 2002 +++ gnumeric-filelocking/src/file.c Tue Jul 16 10:53:27 2002 @@ -18,6 +18,7 @@ #include "workbook-view.h" #include "workbook.h" #include "gutils.h" +#include "lock.h" #include #include @@ -203,6 +204,10 @@ g_return_if_fail (IS_GNUM_FILE_OPENER (fo)); g_return_if_fail (file_name != NULL); + if (is_locked(file_name)) { + gnumeric_io_error_info_set(io_context, error_info_new_str(_("File locked by another process!"))); + return; + } GNUM_FILE_OPENER_METHOD (fo, open) (fo, io_context, wbv, file_name); } diff -urN --minimal gnumeric-1.0.8/src/lock.c gnumeric-filelocking/src/lock.c --- gnumeric-1.0.8/src/lock.c Thu Jan 1 01:00:00 1970 +++ gnumeric-filelocking/src/lock.c Tue Jul 16 14:06:58 2002 @@ -0,0 +1,124 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "gnumeric.h" + +gboolean acquire_lock(const char* filename) +{ + char *lockfile; + gboolean retval = FALSE; + int fd; + + printf("DEBUG: acquire_lock(%s)\n", filename); + + g_return_val_if_fail(filename != NULL, FALSE); + g_return_val_if_fail(strlen(filename) != 0, FALSE); + if( is_locked(filename) == TRUE ) { + return FALSE; + } + + lockfile = g_strconcat (filename, ".lck", 0); + + if ((fd = open(lockfile, O_WRONLY|O_CREAT|O_EXCL, S_IREAD|S_IWRITE)) >= 0) { + + char *lockstr; + lockstr = create_locking_string(filename); + + printf("DEBUG: Locking %s with %s\n", lockfile, lockstr); + write(fd, lockstr, strlen(lockstr)); + close(fd); + g_free(lockstr); + retval = TRUE; + } + g_free(lockfile); + + return retval; +} + +gboolean relinquish_lock(const char* filename) +{ + char *lockfile; + gboolean retval = FALSE; + int fd; + + printf("DEBUG: relinquish_lock(%s)\n", filename); + + g_return_val_if_fail(filename != NULL, FALSE); + g_return_val_if_fail(strlen(filename) != 0, FALSE); + + lockfile = g_strconcat( filename, ".lck" , 0); + + if ((fd = open(lockfile, O_RDONLY)) >= 0) { + char lockstr[300] = "\0"; + if (read(fd, lockstr, 300) >= 0) { + char *lockstr2; + lockstr2 = create_locking_string(filename); + + if ( strcmp(lockstr, lockstr2) == 0 ) { + printf("DEBUG: Relinquishing lock to %s!\n", filename); + close(fd); + unlink(lockfile); + retval = TRUE; + } else { + printf("DEBUG: Lock file %s is not ours!\n", lockfile); + close(fd); + } + g_free(lockstr2); + + } else { + printf("DEBUG: error during read (%d)\n", errno); + close(fd); + } + } else { + printf("DEBUG: Lock file %s doesn't exist!\n", lockfile); + } + g_free(lockfile); + + return retval; +} + +gboolean is_locked(const char* filename) +{ + char *lockfile; + gboolean retval = FALSE; + int ret; + struct stat st; + + printf("DEBUG: is_locked(%s)\n", filename); + + g_return_val_if_fail(filename != NULL, FALSE); + g_return_val_if_fail(strlen(filename) != 0, FALSE); + + lockfile = g_strconcat( filename, ".lck", 0); + + if ((ret = stat(lockfile, &st)) >= 0) { + retval = TRUE; + } + g_free(lockfile); + return retval; +} + + +/* Create the locking string, format is + * hostname:pid + * FBK 15-9-2002 + */ +gchar* create_locking_string(const gchar* filename) +{ + gchar *lockstr; + char hostname[256]; + long pid; + + gethostname(hostname, 255); + hostname[255] = 0; + pid = (long) getpid(); + + lockstr = g_strdup_printf("%s:%ld", hostname, pid); + return lockstr; +} + diff -urN --minimal gnumeric-1.0.8/src/lock.h gnumeric-filelocking/src/lock.h --- gnumeric-1.0.8/src/lock.h Thu Jan 1 01:00:00 1970 +++ gnumeric-filelocking/src/lock.h Tue Jul 16 14:06:58 2002 @@ -0,0 +1,11 @@ +#ifndef GNUMERIC_LOCK_H +#define GNUMERIC_LOCK_H + +#include "gnumeric.h" + +gboolean acquire_lock(char* filename); +gboolean relinquish_lock(char* filename); +gboolean is_locked(char* filename); +gchar* create_locking_string(char* filename); +#endif + Binary files gnumeric-1.0.8/src/lock.o and gnumeric-filelocking/src/lock.o differ diff -urN --minimal gnumeric-1.0.8/src/workbook-view.c gnumeric-filelocking/src/workbook-view.c --- gnumeric-1.0.8/src/workbook-view.c Sun Jun 2 02:08:33 2002 +++ gnumeric-filelocking/src/workbook-view.c Tue Jul 16 10:53:33 2002 @@ -41,6 +41,7 @@ #include "cell.h" #include "parse-util.h" #include "io-context.h" +#include "lock.h" #include #include @@ -611,7 +612,10 @@ wb = wb_view_workbook (wbv); io_context = gnumeric_io_context_new (context); - gnum_file_saver_save (fs, io_context, wbv, file_name); + if (is_locked(file_name)) + gnumeric_io_error_info_set(io_context, error_info_new_str(_("File locked by another process!"))); + else + gnum_file_saver_save (fs, io_context, wbv, file_name); if (!gnumeric_io_error_occurred (io_context)) { workbook_set_saveinfo (wb, file_name, gnum_file_saver_get_format_level (fs), fs); workbook_set_dirty (wb, FALSE); diff -urN --minimal gnumeric-1.0.8/src/workbook.c gnumeric-filelocking/src/workbook.c --- gnumeric-1.0.8/src/workbook.c Thu Jan 31 04:11:27 2002 +++ gnumeric-filelocking/src/workbook.c Mon Jul 15 15:40:26 2002 @@ -32,6 +32,7 @@ #include "file.h" #include "io-context.h" #include "gutils.h" +#include "lock.h" #ifdef ENABLE_BONOBO #include @@ -122,6 +123,11 @@ Workbook *wb = WORKBOOK (wb_object); GList *sheets, *ptr; + /* BV 14/12/2001 + * Add file locking to Gnumeric + */ + relinquish_lock(workbook_get_filename(wb)); + wb->priv->during_destruction = TRUE; if (wb->file_saver_sig_id != 0) { @@ -529,11 +535,21 @@ g_return_val_if_fail (wb != NULL, FALSE); g_return_val_if_fail (name != NULL, FALSE); - if (wb->filename) + if (wb->filename) { + /* BV 14/12/2001 + * Add file locking to gnumeric + */ + relinquish_lock(wb->filename); g_free (wb->filename); + } wb->filename = g_strdup (name); base_name = g_basename (name); + + /* BV 14/12/2001 + * Add file locking to gnumeric + */ + if( acquire_lock(wb->filename) == FALSE ) { return FALSE; } WORKBOOK_FOREACH_CONTROL (wb, view, control, wb_control_title_set (control, base_name););