Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

History file locking?



In order to keep Zsh from trashing its history file, I have
implemented the following local patch.  Perhaps this can be worked
into the source tree?  This patch uses the fcntl() function to lock
the entire contents of the history file during read and write
operations, using the corresponding blocking read and write locks. 

-- 
Russell Senior                                seniorr@xxxxxxxxxxxx



*** hist.c-orig	Thu Dec 21 14:44:16 1995
--- hist.c	Wed Apr 10 03:22:35 1996
***************
*** 30,35 ****
--- 30,36 ----
   */
  
  #include "zsh.h"
+ #include <fcntl.h>
  
  extern int cs, ll;
  
***************
*** 1250,1255 ****
--- 1251,1262 ----
      time_t tim = time(NULL);
      short *wordlist;
      int nwordpos, nwordlist;
+     struct flock lk;
+ 
+     lk.l_type = F_RDLCK;
+     lk.l_whence = SEEK_SET;
+     lk.l_start = 0;
+     lk.l_len = 0;
  
      if (!s)
  	return;
***************
*** 1257,1262 ****
--- 1264,1271 ----
  	nwordlist = 16;
  	wordlist = (short *)zalloc(nwordlist*sizeof(short));
  
+         fcntl(fileno(in),F_SETLKW,&lk);
+         
  	while (fgets(buf, sizeof(buf), in)) {
  	    int l = strlen(buf);
  	    char *pt, *start;
***************
*** 1326,1333 ****
  	    } else
  		ent->words = (short *)NULL;
  	}
  	fclose(in);
! 
  	zfree(wordlist, nwordlist*sizeof(short));
      } else if (err)
  	zerr("can't read history file", s, 0);
--- 1335,1345 ----
  	    } else
  		ent->words = (short *)NULL;
  	}
+         
+         lk.l_type = F_UNLCK;
+         fcntl(fileno(in),F_SETLKW,&lk);
  	fclose(in);
!         
  	zfree(wordlist, nwordlist*sizeof(short));
      } else if (err)
  	zerr("can't read history file", s, 0);
***************
*** 1341,1347 ****
--- 1353,1364 ----
      FILE *out;
      int ev;
      Histent ent;
+     struct flock lk;
  
+     lk.l_whence = SEEK_SET;
+     lk.l_start = 0;
+     lk.l_len = 0;
+     
      if (!s || !interact || savehist == 0)
  	return;
      ev = curhist - savehist + 1;
***************
*** 1352,1357 ****
--- 1369,1376 ----
      else
  	out = fdopen(open(s, O_CREAT | O_WRONLY | O_TRUNC, 0600), "w");
      if (out) {
+         lk.l_type = F_WRLCK;
+         fcntl(fileno(out),F_SETLKW,&lk);
  	for (; ev <= curhist; ev++) {
  	    ent = gethistent(ev);
  	    if (app & 2) {
***************
*** 1374,1385 ****
--- 1393,1410 ----
  	    }
  	    fputc('\n', out);
  	}
+         
+         lk.l_type = F_UNLCK;
+         fcntl(fileno(out),F_SETLKW,&lk);
  	fclose(out);
  
  	if (app & 2 && (out = fopen(s, "r"))) {
  	    char **store, buf[1024], **ptr;
  	    int i, l, histnum = 0;
  
+             lk.l_type = F_WRLCK;
+             fcntl(fileno(out),F_SETLKW,&lk);
+ 
  	    store = (char **)zcalloc((savehist + 1) * sizeof *store);
  	    while (fgets(buf, sizeof(buf), out)) {
  		l = strlen(buf);
***************
*** 1394,1407 ****
--- 1419,1439 ----
  		strcpy(store[i], buf);
  		histnum++;
  	    }
+             lk.l_type = F_UNLCK;
+             fcntl(fileno(out),F_SETLKW,&lk);
  	    fclose(out);
  	    if ((out = fdopen(open(s, O_WRONLY | O_TRUNC, 0600), "w"))) {
+                 lk.l_type = F_WRLCK;
+                 fcntl(fileno(out),F_SETLKW,&lk);
+ 
  		if (histnum < savehist)
  		    for (i = 0; i < histnum; i++)
  			fprintf(out, "%s", store[i]);
  		else
  		    for (i = histnum; i < histnum + savehist; i++)
  			fprintf(out, "%s", store[i % savehist]);
+                 lk.l_type = F_UNLCK;
+                 fcntl(fileno(out),F_SETLKW,&lk);
  		fclose(out);
  	    }
  	    for (ptr = store; *ptr; ptr++)




Messages sorted by: Reverse Date, Date, Thread, Author