delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2005/11/07/21:57:10

Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
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
Message-ID: <437013E8.8030101@cwilson.fastmail.fm>
Date: Mon, 07 Nov 2005 21:56:40 -0500
From: Charles Wilson <cygwin AT cwilson DOT fastmail DOT fm>
User-Agent: Mozilla Thunderbird 1.0.6 (Windows/20050716)
MIME-Version: 1.0
To: cygwin AT cygwin DOT com
Subject: Re: BUG: alternatives
References: <436CF5E9 DOT 30106 AT cwilson DOT fastmail DOT fm> <001201c5e244$c9e50490$020aa8c0 AT DFW5RB41> <436D9993 DOT 7050100 AT cwilson DOT fastmail DOT fm> <20051106134339 DOT GA24549 AT trixie DOT casa DOT cgf DOT cx> <436E50DE DOT 3070405 AT cwilson DOT fastmail DOT fm> <20051107005502 DOT GA8754 AT trixie DOT casa DOT cgf DOT cx>
In-Reply-To: <20051107005502.GA8754@trixie.casa.cgf.cx>

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

Christopher Faylor wrote:

> I have mixed feelings about alloca, personally.  I use it all of the time but
> it is always with some trepidation because, AFAIK, the failure condition for
> alloca is a SEGV.  OTOH, it is very convenient.
> 
> In this case, however, I think you really want to use realloc.  You could even
> rely on the fact that realloc(NULL, n) is equivalent to malloc(n).

Okay, revised patch attached if anybody cares to comment.  But more 
importantly, a test release (1.3.20a-2) should be up on the mirrors soon.

--
Chuck


--------------070000070704000008060702
Content-Type: text/plain;
 name="alternatives-textmode-3.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="alternatives-textmode-3.patch"

diff -urN -x .build -x .inst -x .sinst -x .gmo -x .mo alternatives-1.3.20a-orig/alternatives.c alternatives-1.3.20a/alternatives.c
--- alternatives-1.3.20a-orig/alternatives.c	2005-06-25 21:55:02.000000000 -0400
+++ alternatives-1.3.20a/alternatives.c	2005-11-07 21:31:01.939142400 -0500
@@ -17,6 +17,23 @@
 #define	FLAGS_TEST	(1 << 0)
 #define	FLAGS_VERBOSE	(1 << 1)
 
+#if defined(O_BINARY)
+# define _O_BINARY		O_BINARY
+# define FOPEN_WRITE_MODE	"wb"
+# define FOPEN_READ_MODE	"rb"
+#else
+# define _O_BINARY		0
+# define FOPEN_WRITE_MODE	"w"
+# define FOPEN_READ_MODE	"r"
+#endif
+
+#define PARANOID_FREE(stale) do { \
+  if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+#define READCONFIG_BUF_INITIALSZ	16
+#define READCONFIG_BUF_BEHAVIOR_THRESH	4096
+
+
 #define FL_TEST(flags)	    ((flags) & FLAGS_TEST)
 #define FL_VERBOSE(flags)   ((flags) & FLAGS_VERBOSE)
 
@@ -115,16 +132,30 @@
 
 char * parseLine(char ** buf) {
     char * start = *buf;
-    char * end;
+    char * end1 = *buf;
+    char * end2;
 
     if (!*buf || !**buf) return NULL;
 
-    end = strchr(start, '\n');
-    if (!end) {
-	*buf = start + strlen(start);
-    } else {
-	*buf = end + 1;
-	*end = '\0';
+    while (*end1 && (*end1 != '\n') && (*end1 != '\r'))
+       end1++;
+
+    end2 = end1;
+    while (*end2 && (*end2 == '\r')) /* only walk past '\r', NOT '\n' */
+    {
+       *end2 = '\0';
+       end2++;
+    }
+
+    /* ensures this parseLine() only consumes ONE '\n' */
+    if (*end2 == '\n')
+    {
+       *buf = end2 + 1;
+       *end2 = '\0';
+    }
+    else
+    {
+       *buf = end2;
     }
 
     while (isspace(*start) && *start) start++;
@@ -139,6 +170,7 @@
     int i;
     struct stat sb;
     char * buf;
+    char * bufp;
     char * end;
     char * line;
     struct {
@@ -147,6 +179,9 @@
     } * groups = NULL;
     int numGroups = 0;
     char linkBuf[1024];
+    size_t curBufSz;
+    size_t totalBytesRead;
+    size_t numBytesRead;
 
     set->alts = NULL;
     set->numAlts = 0;
@@ -160,26 +195,50 @@
     if (FL_VERBOSE(flags))
 	printf(_("reading %s\n"), path);
 
-    if ((fd = open(path, O_RDONLY)) < 0) {
+    if ((fd = open(path, O_RDONLY | _O_BINARY)) < 0) {
 	if (errno == ENOENT) return 3;
 	fprintf(stderr, _("failed to open %s: %s\n"), path,
 	        strerror(errno));
 	return 1;
     }
 
-    fstat(fd, &sb);
-    buf = alloca(sb.st_size + 1);
-    if (read(fd, buf, sb.st_size) != sb.st_size) {
-	close(fd);
+    curBufSz = READCONFIG_BUF_INITIALSZ;
+    totalBytesRead = 0;
+    numBytesRead = 0;
+    buf = NULL;
+    do
+    {
+       if (curBufSz < READCONFIG_BUF_BEHAVIOR_THRESH)
+          curBufSz *= 2;
+       else
+          curBufSz += READCONFIG_BUF_BEHAVIOR_THRESH;
+
+       buf = realloc(buf, curBufSz + 1);
+
+       bufp = buf + totalBytesRead;
+       numBytesRead = read(fd, bufp, curBufSz - totalBytesRead);
+
+       /* don't add '-1' ! */
+       if (numBytesRead > 0)
+           totalBytesRead += numBytesRead;
+    }
+    while (numBytesRead > 0);
+
+    if (numBytesRead < 0)
+    {
+        close(fd);
+        PARANOID_FREE(buf);
 	fprintf(stderr, _("failed to read %s: %s\n"), path,
 	        strerror(errno));
 	return 1;
     }
     close(fd);
-    buf[sb.st_size] = '\0';
+    buf[curBufSz] = '\0';
+    bufp = buf;
 
-    line = parseLine(&buf);
+    line = parseLine(&bufp);
     if (!line) {
+        PARANOID_FREE(buf);
 	fprintf(stderr, _("%s empty!\n"), path);
 	return 1;
     }
@@ -189,13 +248,15 @@
     } else if (!strcmp(line, "manual")) {
 	set->mode = MANUAL;
     } else {
+        PARANOID_FREE(buf);
 	fprintf(stderr, _("bad mode on line 1 of %s\n"), path);
 	return 1;
     }
     free(line);
 
-    line = parseLine(&buf);
+    line = parseLine(&bufp);
     if (!line || *line != '/') {
+        PARANOID_FREE(buf);
 	fprintf(stderr, _("bad primary link in %s\n"), path);
 	return 1;
     }
@@ -205,9 +266,10 @@
     groups[0].facility = line;
     numGroups = 1;
 
-    line = parseLine(&buf);
+    line = parseLine(&bufp);
     while (line && *line) {
 	if (*line == '/') {
+            PARANOID_FREE(buf);
 	    fprintf(stderr, _("path %s unexpected in %s\n"), line, path);
 	    return 1;
 	}
@@ -215,27 +277,30 @@
 	groups = realloc(groups, sizeof(*groups) * (numGroups + 1));
 	groups[numGroups].title = line;
 
-	line = parseLine(&buf);
+	line = parseLine(&bufp);
 	if (!line || !*line) {
+            PARANOID_FREE(buf);
 	    fprintf(stderr, _("missing path for slave %s in %s\n"), line, path);
 	    return 1;
 	}
 
 	groups[numGroups++].facility = line;
 
-	line = parseLine(&buf);
+	line = parseLine(&bufp);
     }
 
     if (!line) {
+        PARANOID_FREE(buf);
 	fprintf(stderr, _("unexpected end of file in %s\n"), path);
 	return 1;
     }
 
-    line = parseLine(&buf);
+    line = parseLine(&bufp);
     while (line && *line) {
 	set->alts = realloc(set->alts, (set->numAlts + 1) * sizeof(*set->alts));
 
 	if (*line != '/') {
+            PARANOID_FREE(buf);
 	    fprintf(stderr, _("path to alternate expected in %s\n"), path);
 	    return 1;
 	}
@@ -251,11 +316,12 @@
 	else
 	    set->alts[set->numAlts].slaves = NULL;
 
-	line = parseLine(&buf);
+	line = parseLine(&bufp);
 	set->alts[set->numAlts].priority = -1;
 	set->alts[set->numAlts].priority = strtol(line, &end, 0);
 	set->alts[set->numAlts].initscript = NULL;
 	if (!end || (end == line)) {
+            PARANOID_FREE(buf);
 	    fprintf(stderr, _("numeric priority expected in %s\n"), path);
 	    return 1;
 	}
@@ -276,8 +342,9 @@
 	    set->best = set->numAlts;
 
 	for (i = 1; i < numGroups; i++) {
-	    line = parseLine(&buf);
+	    line = parseLine(&bufp);
 	    if (line && strlen(line) && *line != '/') {
+                PARANOID_FREE(buf);
 		fprintf(stderr, _("slave path expected in %s\n"), path);
 		return 1;
 	    }
@@ -291,12 +358,13 @@
 
 	set->numAlts++;
 
-	line = parseLine(&buf);
+	line = parseLine(&bufp);
     }
 
     while (line) {
-	line = parseLine(&buf);
+	line = parseLine(&bufp);
 	if (line && *line) {
+            PARANOID_FREE(buf);
 	    fprintf(stderr, _("unexpected line in %s: %s\n"), path, line);
 	    return 1;
 	}
@@ -305,6 +373,7 @@
     sprintf(path, "%s/%s", altDir, set->alts[0].master.title);
 
     if (((i = readlink(path, linkBuf, sizeof(linkBuf) - 1)) < 0)) {
+        PARANOID_FREE(buf);
 	fprintf(stderr, _("failed to read link %s: %s\n"),
 		set->alts[0].master.facility, strerror(errno));
 	return 2;
@@ -331,6 +400,7 @@
 
     set->currentLink = strdup(linkBuf);
 
+    PARANOID_FREE(buf);
     return 0;
 }
 
@@ -414,7 +484,7 @@
     if (FL_TEST(flags))
 	fd = dup(1);
     else
-	fd = open(path, O_RDWR | O_CREAT | O_EXCL, 0644);
+	fd = open(path, O_RDWR | O_CREAT | O_EXCL | _O_BINARY, 0644);
 
     if (fd < 0) {
 	if (errno == EEXIST) 
@@ -425,7 +495,7 @@
 	return 1;
     }
 
-    f = fdopen(fd, "w");
+    f = fdopen(fd, FOPEN_WRITE_MODE); 
     fprintf(f, "%s\n", set->mode == AUTO ? "auto" : "manual");
     fprintf(f, "%s\n", set->alts[0].master.facility);
     for (i = 0; i < set->alts[0].numSlaves; i++) {


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

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

- Raw text -


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