delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2009/07/10/15:22:55

X-Recipient: archive-cygwin AT delorie DOT com
X-SWARE-Spam-Status: No, hits=-2.7 required=5.0 tests=AWL,BAYES_00,J_CHICKENPOX_43,J_CHICKENPOX_71,RCVD_IN_DNSWL_LOW,SPF_PASS
X-Spam-Check-By: sourceware.org
Message-ID: <4A5794FA.7020406@cwilson.fastmail.fm>
Date: Fri, 10 Jul 2009 15:22:34 -0400
From: Charles Wilson <cygwin AT cwilson DOT fastmail DOT fm>
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.22) Gecko/20090605 Thunderbird/2.0.0.22 Mnenhy/0.7.6.666
MIME-Version: 1.0
To: cygwin AT cygwin DOT com
Subject: [1.7] Bug in link() with long filenames
Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Id: <cygwin.cygwin.com>
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com

--------------010409010203000009030808
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

It seems that the st_nlink count is not updated for very long file
names. If the filename length is 247, everything is fine. If it is
248...the link count does not get updated, although the files (original
and the link) both have the same st_ino value.

Here's a test case (takes an optional argument that sets the smaller of
the two filename lengths; defaults to 247, which demonstrates the problem).

$ ./longlink
orig1(247):
/tmp/test_longlink/f/abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqr
link1(247):
/tmp/test_longlink/l/abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqr
orig2(248):
/tmp/test_longlink/f/abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrs
link2(248):
/tmp/test_longlink/l/abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrs


ino: 11821949022413710
dev: 11821950991284627
nlink: 1
ino: 11540474045703055
dev: 11540476014573971
nlink: 1

after link (namelen 247):
original file
ino: 11821949022413710
dev: 11821950991284627
nlink: 2
link
ino: 11821949022413710
dev: 11821950991284627
nlink: 2

after link (namelen 248):
original file
ino: 11540474045703055
dev: 11540476014573971
nlink: 1
link
ino: 11540474045703055
dev: 11540476014573971
nlink: 1

Any idea why "247" is a magic number?

--
Chuck


--------------010409010203000009030808
Content-Type: text/plain;
 name="longlink.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="longlink.c"

#include <stdio.h>
#include <sys/stat.h>

#define ORIGPATH "/tmp/test_longlink/f"
#define LINKPATH "/tmp/test_longlink/l"

void do_stat(const char * s)
{
  struct stat st;
  if (lstat(s, &st) != 0)
  {
    fprintf(stderr, "problem with stat(%s,...)", s);
    return;
  }
  fprintf(stderr, "ino: %llu\n", st.st_ino);
  fprintf(stderr, "dev: %llu\n", st.st_dev);
  fprintf(stderr, "nlink: %d\n", st.st_nlink);
}

int main(int argc, char *argv[])
{
  char orig1[1024];
  char orig2[1024];
  char link1[1024];
  char link2[1024];
  char name[1024];
  int len = 247;
  size_t baselen, newlen;
  FILE* f;

  if (argv[1] && *argv[1])
  {
    len = atoi(argv[1]);
  }

  mkdir("/tmp/test_longlink", 0755);
  mkdir(ORIGPATH, 0755);
  mkdir(LINKPATH, 0755);
  strcpy(orig1, ORIGPATH);
  strcpy(orig2, ORIGPATH);
  strcpy(link1, LINKPATH);
  strcpy(link2, LINKPATH);
  strcat(orig1, "/");
  strcat(orig2, "/");
  strcat(link1, "/");
  strcat(link2, "/");

  baselen = strlen(orig1);
  newlen = baselen;
  while (newlen < len)
  {
    char a = ((char)((newlen - baselen) % 26)) + 'a';
    orig1[newlen] = a;
    link1[newlen] = a;
    newlen++;
  }
  orig1[newlen] = '\0';
  link1[newlen] = '\0';

  newlen = baselen;
  while (newlen < len + 1)
  {
    char a = ((char)((newlen - baselen) % 26)) + 'a';
    orig2[newlen] = a;
    link2[newlen] = a;
    newlen++;
  }
  orig2[newlen] = '\0';
  link2[newlen] = '\0';

  fprintf(stderr, "orig1(%d): %s\n", strlen(orig1), orig1);
  fprintf(stderr, "link1(%d): %s\n", strlen(link1), link1);
  fprintf(stderr, "orig2(%d): %s\n", strlen(orig2), orig2);
  fprintf(stderr, "link2(%d): %s\n", strlen(link2), link2);
  fprintf(stderr, "\n\n");

  f = fopen(orig1, "wb");
  fprintf(f, "%s\n", orig1);
  fclose(f);
  do_stat(orig1);

  f = fopen(orig2, "wb");
  fprintf(f, "%s\n", orig2);
  fclose(f);
  do_stat(orig2);

  link (orig1, link1);
  fprintf(stderr, "\nafter link (namelen %d):\n", strlen(orig1));
  fprintf(stderr, "original file\n");
  do_stat(orig1);
  fprintf(stderr, "link\n");
  do_stat(link1);

  link (orig2, link2);
  fprintf(stderr, "\nafter link (namelen %d):\n", strlen(orig2));
  fprintf(stderr, "original file\n");
  do_stat(orig2);
  fprintf(stderr, "link\n");
  do_stat(link2);

  return 0;
}


--------------010409010203000009030808
Content-Type: text/plain; charset=us-ascii

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
--------------010409010203000009030808--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019