[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

emacs and buggy HP readlink

From: Philippe Waroquiers
Subject: emacs and buggy HP readlink
Date: Tue, 4 Sep 2001 20:56:11 +0200 (METDST)

In GNU Emacs 20.7.1 (hppa1.1-hp-hpux11.00, X toolkit)
 of Mon Aug 14 2000 on rhino
configured using `configure  hppa1.1-hp-hpux11.00 --with-gcc=no --with-x11r6 
--x-libraries=/usr/lib/X11R6:/usr/contrib/X11R6/lib --with-x-toolkit=lucid 
--prefix=/opt/contrib/emacs --exec-prefix=/opt/contrib/emacs/20.7 

Please describe exactly what actions triggered the bug
and the precise symptoms of the bug:

file-symlink-p does not work properly on HP with "big" symlink.

gull: touch a
gull: ln -s a b
gull: touch 
gull: ln -s 
gull: /opt/contrib/bin/emacs --no-init-file --no-site-file --batch --eval 
'(print (file-symlink-p "big"))'

gull: /opt/contrib/bin/emacs --no-init-file --no-site-file --batch --eval 
'(print (file-symlink-p "b"))'


So, as you can see, file-symlink-p works ok with         b -> a
                                   fails    with         big -> .....

The problem originates from file-symlink-p using readlink that does not work
properly on hp-ux.
This is shown by the following piece of code and sequence of command.
(code is adapted from fileio.c file-symlink-p function).
Put the below code in a file file_symlink_p.c and compile it as shown

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
main (int argc, char * argv[])
  char *buf;
  int bufsize;
  int valsize;
  char *filename;

  filename = argv[1];
  bufsize = 10;  /* made small so that it is easier to produce the problem */
  while (1)
      buf = (char *) malloc (bufsize);
      bzero (buf, bufsize);
      valsize = readlink (filename, buf, bufsize);
      printf ("bufsize %d valsize %d errno %d\n", bufsize, valsize, errno);

      /* buggy HP readlink has to be corrected : */
      if ((valsize == -1) && errno == ERANGE) valsize = bufsize;
      /* end of correction */

      if (valsize < bufsize) break;
      /* Buffer was not long enough */
      free (buf);
      bufsize *= 2;
  if (valsize == -1)
      printf ("-1\n");
    printf ("symlink %s\n", buf);

gull: cc -o file_symlink_p file_symlink_p.c
gull: touch 12345678901
gull: ln -s 12345678901 1
gull: file_symlink_p b
bufsize 10 valsize 1 errno 0
symlink a
gull: file_symlink_p 1
bufsize 10 valsize -1 errno 34
bufsize 20 valsize 11 errno 34
symlink 12345678901
gull: file_symlink_p big
bufsize 10 valsize -1 errno 34
bufsize 20 valsize -1 errno 34
bufsize 40 valsize -1 errno 34
bufsize 80 valsize -1 errno 34
bufsize 160 valsize 110 errno 34

As you can see, the call to readlink returns -1 errno 34 when the bufsize is
smaller than what is needed to read the link. So, instead to try with the
double size, emacs goes out of the loop and tells that it is not a link
while in fact it is. One of the effect of this bug is to change the
backup behaviour when the file is a symlink of more than 100 characters.

I see 3 possible corrections (not necessarily exclusive) :
  * insert the correction above in fileio.c (with #ifdef HPUX I suppose).
  * alternatively, decrease the probability of the bug by using an initial
    size of e.g. 1000 for bufsize (for HPUX only or for targets).
  * HP corrects the behaviour of readlink.
    I will submit the same problem to HP but it is of course unclear if/when/how
    HP will correct this bug.
    The minimum is that HP should document this -1/ERANGE behaviour. Currently, 
    the HP manpage for readlink does not even describe this behaviour.

Note there is another usage of readlink in filelock.c that will suffer
from the same HP bug so filelock.c should be corrected similarly.
Maybe there are some other readlink usage that a simple grep on emacs
sources did not find.

Thanks for your nice work on emacs.

Philippe WAROQUIERS                  Eurocontrol - Central Flow Management Unit
philippe.waroquiers@eurocontrol.be   Rue de la fusee, 96
Tel: +32 2 729 97 35                 1130 Brussels
Fax: +32 2 729 90 22                 Belgium

reply via email to

[Prev in Thread] Current Thread [Next in Thread]