about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--Doc/Zsh/calsys.yo4
-rw-r--r--Functions/Calendar/calendar13
-rw-r--r--Functions/Calendar/calendar_add14
-rw-r--r--Functions/Calendar/calendar_edit11
-rw-r--r--Functions/Calendar/calendar_sort12
-rw-r--r--Src/Modules/system.c4
7 files changed, 57 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 4df71cc6b..268e5b202 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2010-02-26  Peter Stephenson  <pws@csr.com>
 
+	* 27756: Doc/Zsh/calsys.yo, Functions/Calendar/calendar,
+	Functions/Calendar/calendar_add, Functions/Calendar/calendar_edit,
+	Functions/Calendar/calendar_sort, Src/Modules/system.c:
+	use new file locking in calendar where available and add
+	errflag test to loop over fcntl().
+
 	* users/14891: Doc/Zsh/cond.yo: say explicitly that condition
 	arguments don't undergo file generation.
 
@@ -12829,5 +12835,5 @@
 
 *****************************************************
 * This is used by the shell to define $ZSH_PATCHLEVEL
-* $Revision: 1.4916 $
+* $Revision: 1.4917 $
 *****************************************************
diff --git a/Doc/Zsh/calsys.yo b/Doc/Zsh/calsys.yo
index 68f68a8d2..94ddd9f75 100644
--- a/Doc/Zsh/calsys.yo
+++ b/Doc/Zsh/calsys.yo
@@ -470,7 +470,9 @@ tt(calendar -s) is called to update it.
 
 This function locks out the calendar system during the edit.
 Hence it should be used to edit the calendar file if there is any
-possibility of a calendar event occurring meanwhile.
+possibility of a calendar event occurring meanwhile.  Note this
+can lead to another shell with calendar functions enabled hanging waiting
+for a lock, so it is necessary to quit the editor as soon as possible.
 )
 findex(calendar_parse)
 item(tt(calendar_parse) var(calendar-entry))(
diff --git a/Functions/Calendar/calendar b/Functions/Calendar/calendar
index f6316eb18..b87a14628 100644
--- a/Functions/Calendar/calendar
+++ b/Functions/Calendar/calendar
@@ -253,13 +253,21 @@ if (( verbose )); then
   fi
 fi
 
+# start of subshell for OS file locking
+(
 # start of block for following always to clear up lockfiles.
+# Not needed but harmless if OS file locking is used.
 {
   if [[ -n $donefile ]]; then
     # Attempt to lock both $donefile and $calendar.
     # Don't lock $newfile; we've tried our best to make
     # the name unique.
-    calendar_lockfiles $calendar $donefile || return 1
+    if zmodload -F zsh/system b:zsystem && zsystem supports flock; then
+      zsystem flock $calendar
+      zsystem flock $donefile
+    else
+      calendar_lockfiles $calendar $donefile || exit 1
+    fi
   fi
 
   calendar_read $calendar
@@ -414,4 +422,5 @@ Old calendar left in $calendar.old." >&2
   (( ${#lockfiles} )) && rm -f $lockfiles
 }
 
-return $rstat
+exit $rstat
+)
diff --git a/Functions/Calendar/calendar_add b/Functions/Calendar/calendar_add
index 280e5f365..ac5caecd7 100644
--- a/Functions/Calendar/calendar_add
+++ b/Functions/Calendar/calendar_add
@@ -68,9 +68,18 @@ if [[ $addline = ${~uidpat} ]]; then
   my_uid=${(U)match[1]}
 fi
 
+# start of subshell for OS file locking
+(
 # start of block for following always to clear up lockfiles.
+# Not needed but harmless if OS file locking is used.
 {
-  (( nolock )) || calendar_lockfiles $calendar || return 1
+  if (( ! nolock )); then
+    if zmodload -F zsh/system b:zsystem && zsystem supports flock; then
+      zsystem flock $calendar
+    else
+      calendar_lockfiles $calendar || exit 1
+    fi
+  fi
 
   if [[ -f $calendar ]]; then
     calendar_read $calendar
@@ -158,4 +167,5 @@ Old calendar left in $calendar.old." >&2
   (( ${#lockfiles} )) && rm -f $lockfiles
 }
 
-return $rstat
+exit $rstat
+)
diff --git a/Functions/Calendar/calendar_edit b/Functions/Calendar/calendar_edit
index e31decb76..e3ac5c39b 100644
--- a/Functions/Calendar/calendar_edit
+++ b/Functions/Calendar/calendar_edit
@@ -10,12 +10,21 @@ done
 
 zstyle -s ':datetime:calendar:' calendar-file calendar || calendar=~/calendar
 
+# start of subshell for OS file locking
+(
+# start of block for following always to clear up lockfiles.
+# Not needed but harmless if OS file locking is used.
 {
-  calendar_lockfiles $calendar || return 1
+  if zmodload -F zsh/system b:zsystem && zsystem supports flock; then
+    zsystem flock $calendar
+  else
+    calendar_lockfiles $calendar || exit 1
+  fi
 
   eval $editor \$calendar
 } always {
   (( ${#lockfiles} )) && rm -f $lockfiles
 }
+)
 
 (( cal_running )) && calendar -s
diff --git a/Functions/Calendar/calendar_sort b/Functions/Calendar/calendar_sort
index 7d346efc1..4911e34a2 100644
--- a/Functions/Calendar/calendar_sort
+++ b/Functions/Calendar/calendar_sort
@@ -11,9 +11,16 @@ integer i
 # Read the calendar file from the calendar-file style
 zstyle -s ':datetime:calendar:' calendar-file calendar || calendar=~/calendar
 
-# Start block for "always" to handle lockfile
+# start of subshell for OS file locking
+(
+# start of block for following always to clear up lockfiles.
+# Not needed but harmless if OS file locking is used.
 {
-  calendar_lockfiles $calendar || return 1
+  if zmodload -F zsh/system b:zsystem && zsystem supports flock; then
+    zsystem flock $calendar
+  else
+    calendar_lockfiles $calendar || exit 1
+  fi
 
   new=$calendar.new.$$
   calendar_read $calendar
@@ -65,3 +72,4 @@ Old calendar left in $calendar.old"
 } always {
   (( ${#lockfiles} )) && rm -rf $lockfiles
 }
+)
diff --git a/Src/Modules/system.c b/Src/Modules/system.c
index 93796128b..f6a21d160 100644
--- a/Src/Modules/system.c
+++ b/Src/Modules/system.c
@@ -463,6 +463,8 @@ bin_zsystem_flock(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
     if (timeout > 0) {
 	time_t end = time(NULL) + (time_t)timeout;
 	while (fcntl(flock_fd, F_SETLK, &lck) < 0) {
+	    if (errflag)
+		return 1;
 	    if (errno != EINTR && errno != EACCES && errno != EAGAIN) {
 		zwarnnam(nam, "failed to lock file %s: %e", args[0], errno);
 		return 1;
@@ -473,6 +475,8 @@ bin_zsystem_flock(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 	}
     } else {
 	while (fcntl(flock_fd, F_SETLKW, &lck) < 0) {
+	    if (errflag)
+		return 1;
 	    if (errno == EINTR)
 		continue;
 	    zwarnnam(nam, "failed to lock file %s: %e", args[0], errno);