Package: zsh
Version: 4.3.2-25
Severity: important

Under NFS, I often get corrupt history files (I use INC_APPEND_HISTORY).
After looking at the zsh source, though it has a lockhistfile function,
this function doesn't seem to lock the history file (it just calls link,
which isn't a NFS-safe system call). It should lock files with fcntl
(possibly with other mechanisms for very old machines, but personnally,
I don't mind).

I've attached a small program I wrote a few years ago to test fcntl
locking over NFS. See also:

  http://www.quepublishing.com/articles/article.asp?p=23618&seqNum=4&rl=1

(If no-one has worked on it, I'll probably look at that in a few days.)

-- System Information:
Debian Release: 4.0
  APT prefers unstable
  APT policy: (500, 'unstable'), (500, 'testing'), (500, 'stable')
Architecture: i386 (i686)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.18-4-686-bigmem
Locale: LANG=POSIX, LC_CTYPE=en_US.ISO8859-1 (charmap=ISO-8859-1)

Versions of packages zsh depends on:
ii  debconf [debconf-2.0]       1.5.12       Debian configuration management sy
ii  libc6                       2.3.6.ds1-13 GNU C Library: Shared libraries
ii  libncurses5                 5.5-5        Shared libraries for terminal hand

Versions of packages zsh recommends:
ii  libcap1                       1:1.10-14  support for getting/setting POSIX.
ii  libpcre3                      6.7-1      Perl 5 Compatible Regular Expressi

-- no debconf information
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

int main (int argc, char *argv[])
{
  FILE *f;
  int fd;
  struct flock lck;

  if (argc != 3)
  {
    fprintf (stderr, "Usage: tfcntl <file> <sleeptime>\n");
    exit (1);
  }

  f = fopen (argv[1], "r+b");
  if (f == NULL)
  {
    fprintf (stderr, "tfcntl: can't open file %s\n", argv[1]);
    perror ("tfnctl");
    exit (2);
  }
  fd = fileno (f);

  memset (&lck, 0, sizeof (struct flock));
  lck.l_type = F_WRLCK;
  lck.l_whence = SEEK_SET;
  if (fcntl (fd, F_SETLK, &lck) == -1)
  {
    fprintf (stderr, "tfcntl: lock failed (errno = %d)\n", errno);
    perror ("tfnctl");
    exit (3);
  }

  sleep(atoi(argv[2]));

  memset (&lck, 0, sizeof (struct flock));
  lck.l_type = F_UNLCK;
  lck.l_whence = SEEK_SET;
  fcntl (fd, F_SETLK, &lck);

  return 0;
}

Reply via email to