diff -urN --minimal gnumeric-1.0.8/src/Makefile.am gnumeric-1.0.8-snow/src/Makefile.am --- gnumeric-1.0.8/src/Makefile.am Sun Apr 14 15:41:23 2002 +++ gnumeric-1.0.8-snow/src/Makefile.am Tue Jul 2 15:00:42 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-1.0.8-snow/src/file.c --- gnumeric-1.0.8/src/file.c Tue May 28 04:39:21 2002 +++ gnumeric-1.0.8-snow/src/file.c Tue Jul 2 15:00:42 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 is in use!")); + return; + } GNUM_FILE_OPENER_METHOD (fo, open) (fo, io_context, wbv, file_name); } diff -urN --minimal gnumeric-1.0.8/src/lock.c gnumeric-1.0.8-snow/src/lock.c --- gnumeric-1.0.8/src/lock.c Thu Jan 1 01:00:00 1970 +++ gnumeric-1.0.8-snow/src/lock.c Tue Jul 2 15:00:42 2002 @@ -0,0 +1,118 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "gnumeric.h" + +gboolean acquire_lock(const char* filename) +{ + char *lockfile; + gboolean retval = FALSE; + int fd; + + 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_malloc(strlen(filename) + 5); + strcpy(lockfile, filename); + strcat(lockfile, ".lck"); + + if ((fd = open(lockfile, O_WRONLY|O_CREAT|O_EXCL, S_IREAD|S_IWRITE)) >= 0) { + /* Lock succeeded */ + char lockstr[300]; + char hostname[256]; + /* Create the locking string, format is + * hostname:pid */ + gethostname(hostname, 255); + snprintf(lockstr, 300, "%s:%d", hostname, getpid()); + printf("DEBUG: Locking %s with %s\n", lockfile, lockstr); + write(fd, lockstr, strlen(lockstr)); + close(fd); + retval = TRUE; + } + g_free(lockfile); + + return retval; +} + +gboolean relinquish_lock(const char* filename) +{ + char *lockfile; + gboolean retval = FALSE; + int fd; + + g_return_val_if_fail(filename != NULL, FALSE); + g_return_val_if_fail(strlen(filename) != 0, FALSE); + + lockfile = g_malloc(strlen(filename) + 5); + strcpy(lockfile, filename); + strcat(lockfile, ".lck"); + + if ((fd = open(lockfile, O_RDONLY)) >= 0) { + char lockstr[300] = "\0"; + int pid = 0; + if (read(fd, lockstr, 300) >= 0) { + char *hostname1; + char *pidstr; + int index; + char hostname2[256] = "\0"; + gethostname(hostname2, 255); + index = strchr(lockstr, ':') - lockstr; + if (index > 0) { + lockstr[index] = '\0'; + hostname1 = lockstr; + pidstr = lockstr + index + 1; + pid = atoi(pidstr); + } + printf("hostname = %s, pid = %d\n", hostname1, pid); + if ((getpid() == pid) && + (strcmp(hostname2, hostname1) == 0)) { + printf("DEBUG: Relinquishing lock to %s!\n", filename); + close(fd); + /* Unlink the lockfile */ + unlink(lockfile); + retval = TRUE; + } else { + /* Not ours to relinquish */ + printf("DEBUG: Lock file %s is not ours!\n", lockfile); + close(fd); + } + } 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; + g_return_val_if_fail(filename != NULL, FALSE); + g_return_val_if_fail(strlen(filename) != 0, FALSE); + + lockfile = g_malloc(strlen(filename) + 5); + strcpy(lockfile, filename); + strcat(lockfile, ".lck"); + + if ((ret = stat(lockfile, &st)) >= 0) { + + retval = TRUE; + } + return retval; +} + diff -urN --minimal gnumeric-1.0.8/src/lock.h gnumeric-1.0.8-snow/src/lock.h --- gnumeric-1.0.8/src/lock.h Thu Jan 1 01:00:00 1970 +++ gnumeric-1.0.8-snow/src/lock.h Tue Jul 2 15:00:42 2002 @@ -0,0 +1,10 @@ +#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); +#endif + diff -urN --minimal gnumeric-1.0.8/src/workbook-view.c gnumeric-1.0.8-snow/src/workbook-view.c --- gnumeric-1.0.8/src/workbook-view.c Sun Jun 2 02:08:33 2002 +++ gnumeric-1.0.8-snow/src/workbook-view.c Tue Jul 2 15:08:29 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)) + gnum_file_saver_save (fs, io_context, wbv, file_name); + else + gnumeric_io_error_info_set(io_context, error_info_new_str("File is in use!")); 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-1.0.8-snow/src/workbook.c --- gnumeric-1.0.8/src/workbook.c Thu Jan 31 04:11:27 2002 +++ gnumeric-1.0.8-snow/src/workbook.c Tue Jul 2 15:00:42 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););