From dave@bodenstab.org Thu Nov 21 22:17:30 2002 Date: Thu, 21 Nov 2002 16:17:30 -0600 (CST) From: Dave Bodenstab dave@bodenstab.org Subject: [Pgtcl-hackers] pgtcl patch for your consideration
Hello,
A couple of years ago I was trying to use large objects with the
Tcl interface. I recall that I had to insert debugging code to
try to figure out how things worked at that time. Honestly, I don't
remember if the attached patch fixed a problem that I actually saw
or was a preemptive fix in case lo_read/write returned short
counts.
Anyway, I've had the attached patch applied against pgtcl in
postgressql v7.1.3, but I lost interest in my project with large
objects and haven't looked at it for a long time.
The key question is 'does lo_read/write return short counts and/or
error (-1) returns?' If they do not, then this patch is irrelevant.
If they do, then I think you should consider this patch or something like it.
Sorry, but I cannot test your version of pgtcl with this patch
since I don't have time to upgrade from postgressql 7.1.3, and the
new pgtcl uses a function introduced in a later version.
Use this anyway you want.
Dave Bodenstab
Patch against 1.4b3 :
--- generic/pgtclCmds.c.orig Fri Nov 15 18:58:47 2002
+++ generic/pgtclCmds.c Thu Nov 21 15:56:54 2002
@@ -1534,6 +1534,14 @@
buf = ckalloc(len + 1);
nbytes = lo_read(conn, fd, buf, len);
+
+ if (nbytes < 0)
+ {
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(nbytes));
+ rc = TCL_ERROR;
+ }
+ else
+ {
bufObj = Tcl_NewStringObj(buf, nbytes);
if (Tcl_ObjSetVar2(interp, bufVar, NULL, bufObj,
@@ -1541,6 +1549,7 @@
rc = TCL_ERROR;
else
Tcl_SetObjResult(interp, Tcl_NewIntObj(nbytes));
+ }
ckfree(buf);
return rc;
@@ -1562,6 +1571,7 @@
char *buf;
int fd;
int nbytes = 0;
+ int nwritten;
int len;
if (objc != 5)
@@ -1592,8 +1602,17 @@
return TCL_OK;
}
- nbytes = lo_write(conn, fd, buf, len);
+ nwritten = 0;
+ while (len - nwritten > 0) {
+ nbytes = lo_write(conn, fd, buf + nwritten, len - nwritten);
+ if (nbytes < 0 )
+ {
Tcl_SetObjResult(interp, Tcl_NewIntObj(nbytes));
+ return TCL_ERROR;
+ }
+ nwritten += nbytes;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(nwritten));
return TCL_OK;
}
From dave at bodenstab.org Thu Nov 21 22:17:30 2002
From: dave at bodenstab.org (Dave Bodenstab)
Date: Thu, 21 Nov 2002 16:17:30 -0600 (CST)
Subject: [Pgtcl-hackers] pgtcl patch for your consideration
Message-ID: <200211212217.gALMHUT21611@base486.home.org>
Hello,
A couple of years ago I was trying to use large objects with the
Tcl interface. I recall that I had to insert debugging code to
try to figure out how things worked at that time. Honestly, I don't
remember if the attached patch fixed a problem that I actually saw
or was a preemptive fix in case lo_read/write returned short
counts.
Anyway, I've had the attached patch applied against pgtcl in
postgressql v7.1.3, but I lost interest in my project with large
objects and haven't looked at it for a long time.
The key question is 'does lo_read/write return short counts and/or
error (-1) returns?' If they do not, then this patch is irrelevant.
If they do, then I think you should consider this patch or something like it.
Sorry, but I cannot test your version of pgtcl with this patch
since I don't have time to upgrade from postgressql 7.1.3, and the
new pgtcl uses a function introduced in a later version.
Use this anyway you want.
Dave Bodenstab
Patch against 1.4b3 :
--- generic/pgtclCmds.c.orig Fri Nov 15 18:58:47 2002
+++ generic/pgtclCmds.c Thu Nov 21 15:56:54 2002
@@ -1534,6 +1534,14 @@
buf = ckalloc(len + 1);
nbytes = lo_read(conn, fd, buf, len);
+
+ if (nbytes < 0)
+ {
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(nbytes));
+ rc = TCL_ERROR;
+ }
+ else
+ {
bufObj = Tcl_NewStringObj(buf, nbytes);
if (Tcl_ObjSetVar2(interp, bufVar, NULL, bufObj,
@@ -1541,6 +1549,7 @@
rc = TCL_ERROR;
else
Tcl_SetObjResult(interp, Tcl_NewIntObj(nbytes));
+ }
ckfree(buf);
return rc;
@@ -1562,6 +1571,7 @@
char *buf;
int fd;
int nbytes = 0;
+ int nwritten;
int len;
if (objc != 5)
@@ -1592,8 +1602,17 @@
return TCL_OK;
}
- nbytes = lo_write(conn, fd, buf, len);
+ nwritten = 0;
+ while (len - nwritten > 0) {
+ nbytes = lo_write(conn, fd, buf + nwritten, len - nwritten);
+ if (nbytes < 0 )
+ {
Tcl_SetObjResult(interp, Tcl_NewIntObj(nbytes));
+ return TCL_ERROR;
+ }
+ nwritten += nbytes;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(nwritten));
return TCL_OK;
}