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 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 Content-Type: multipart/mixed; boundary="------------010409010203000009030808" Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , 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 #include #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--