]> granicus.if.org Git - postgresql/commitdiff
In the Programmer's Guide, the sample code for accessing large objects
authorBruce Momjian <bruce@momjian.us>
Sat, 20 Jan 2001 00:05:54 +0000 (00:05 +0000)
committerBruce Momjian <bruce@momjian.us>
Sat, 20 Jan 2001 00:05:54 +0000 (00:05 +0000)
from libpq has two functions with memory leaks.

The functions pickout() and overwrite() malloc space for buf which is
never freed.

See
http://www.postgresql.org/users-lounge/docs/7.0/programmer/largeobjects3207.htm

This problem is also in the 6.5 docs at
http://www.postgresql.org/users-lounge/docs/6.5/programmer/x3184.htm

Nishad Prakash

doc/src/sgml/lobj.sgml

index 9d25be88fd9a73bf80b34dad06edec4140cec609..df2d0a098cbe42eeb24e07ca9b7b169c3988cada 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.14 2000/12/21 22:55:27 petere Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.15 2001/01/20 00:05:54 momjian Exp $
 -->
 
  <chapter id="largeObjects">
@@ -316,48 +316,52 @@ SELECT lo_export(image.raster, '/tmp/motd') from image
  *--------------------------------------------------------------
  */
 #include &lt;stdio.h&gt;
-#include "libpq-fe.h"
-#include "libpq/libpq-fs.h"
+#include &quot;libpq-fe.h&quot;
+#include &quot;libpq/libpq-fs.h&quot;
 
 #define BUFSIZE          1024
 
 /*
- * importFile *    import file "in_filename" into database as large object "lobjOid"
+ * importFile *    import file &quot;in_filename&quot; into database as large object &quot;lob
+jOid&quot;
  *
  */
-Oid importFile(PGconn *conn, char *filename)
+Oid
+importFile(PGconn *conn, char *filename)
 {
-    Oid lobjId;
-    int lobj_fd;
-    char buf[BUFSIZE];
-    int nbytes, tmp;
-    int fd;
+    Oid         lobjId;
+    int         lobj_fd;
+    char        buf[BUFSIZE];
+    int         nbytes,
+                tmp;
+    int         fd;
 
     /*
      * open the file to be read in
      */
     fd = open(filename, O_RDONLY, 0666);
-    if (fd &lt; 0)  {   /* error */
-     fprintf(stderr, "can't open unix file %s\n", filename);
+    if (fd &lt; 0)
+    {                           /* error */
+        fprintf(stderr, &quot;can't open unix file %s\n&quot;, filename);
     }
 
     /*
      * create the large object
      */
-    lobjId = lo_creat(conn, INV_READ|INV_WRITE);
-    if (lobjId == 0) {
-     fprintf(stderr, "can't create large object\n");
-    }
+    lobjId = lo_creat(conn, INV_READ | INV_WRITE);
+    if (lobjId == 0)
+        fprintf(stderr, &quot;can't create large object\n&quot;);
 
     lobj_fd = lo_open(conn, lobjId, INV_WRITE);
+
     /*
      * read in from the Unix file and write to the inversion file
      */
-    while ((nbytes = read(fd, buf, BUFSIZE)) &gt; 0) {
-     tmp = lo_write(conn, lobj_fd, buf, nbytes);
-     if (tmp &lt; nbytes) {
-         fprintf(stderr, "error while reading large object\n");
-     }
+    while ((nbytes = read(fd, buf, BUFSIZE)) &gt; 0)
+    {
+        tmp = lo_write(conn, lobj_fd, buf, nbytes);
+        if (tmp &lt; nbytes)
+            fprintf(stderr, &quot;error while reading large object\n&quot;);
     }
 
     (void) close(fd);
@@ -366,101 +370,115 @@ Oid importFile(PGconn *conn, char *filename)
     return lobjId;
 }
 
-void pickout(PGconn *conn, Oid lobjId, int start, int len)
+void
+pickout(PGconn *conn, Oid lobjId, int start, int len)
 {
-    int lobj_fd;
-    charbuf;
-    int nbytes;
-    int nread;
+    int         lobj_fd;
+    char       *buf;
+    int         nbytes;
+    int         nread;
 
     lobj_fd = lo_open(conn, lobjId, INV_READ);
-    if (lobj_fd &lt; 0) {
-     fprintf(stderr,"can't open large object %d\n",
-          lobjId);
+    if (lobj_fd &lt; 0)
+    {
+        fprintf(stderr, &quot;can't open large object %d\n&quot;,
+                lobjId);
     }
 
     lo_lseek(conn, lobj_fd, start, SEEK_SET);
-    buf = malloc(len+1);
+    buf = malloc(len + 1);
 
     nread = 0;
-    while (len - nread &gt; 0) {
-     nbytes = lo_read(conn, lobj_fd, buf, len - nread);
-     buf[nbytes] = ' ';
-     fprintf(stderr,"&gt;&gt;&gt; %s", buf);
-     nread += nbytes;
+    while (len - nread &gt; 0)
+    {
+        nbytes = lo_read(conn, lobj_fd, buf, len - nread);
+        buf[nbytes] = ' ';
+        fprintf(stderr, &quot;&gt;&gt;&gt; %s&quot;, buf);
+        nread += nbytes;
     }
-    fprintf(stderr,"\n");
+    free(buf);
+    fprintf(stderr, &quot;\n&quot;);
     lo_close(conn, lobj_fd);
 }
 
-void overwrite(PGconn *conn, Oid lobjId, int start, int len)
+void
+overwrite(PGconn *conn, Oid lobjId, int start, int len)
 {
-    int lobj_fd;
-    charbuf;
-    int nbytes;
-    int nwritten;
-    int i;
+    int         lobj_fd;
+    char       *buf;
+    int         nbytes;
+    int         nwritten;
+    int         i;
 
     lobj_fd = lo_open(conn, lobjId, INV_READ);
-    if (lobj_fd &lt; 0) {
-     fprintf(stderr,"can't open large object %d\n",
-          lobjId);
+    if (lobj_fd &lt; 0)
+    {
+        fprintf(stderr, &quot;can't open large object %d\n&quot;,
+                lobjId);
     }
 
     lo_lseek(conn, lobj_fd, start, SEEK_SET);
-    buf = malloc(len+1);
+    buf = malloc(len + 1);
 
-    for (i=0;i&lt;len;i++)
-     buf[i] = 'X';
+    for (i = 0; i &lt; len; i++)
+        buf[i] = 'X';
     buf[i] = ' ';
 
     nwritten = 0;
-    while (len - nwritten &gt; 0) {
-     nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
-     nwritten += nbytes;
+    while (len - nwritten &gt; 0)
+    {
+        nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
+        nwritten += nbytes;
     }
-    fprintf(stderr,"\n");
+    free(buf);
+    fprintf(stderr, &quot;\n&quot;);
     lo_close(conn, lobj_fd);
 }
 
 /*
- * exportFile *    export large object "lobjOid" to file "out_filename"
+ * exportFile *    export large object &quot;lobjOid&quot; to file &quot;out_filename&quot;
  *
  */
-void exportFile(PGconn *conn, Oid lobjId, char *filename)
+void
+exportFile(PGconn *conn, Oid lobjId, char *filename)
 {
-    int lobj_fd;
-    char buf[BUFSIZE];
-    int nbytes, tmp;
-    int fd;
+    int         lobj_fd;
+    char        buf[BUFSIZE];
+    int         nbytes,
+                tmp;
+    int         fd;
 
     /*
-     * create an inversion "object"
+     * create an inversion &quot;object&quot;
      */
     lobj_fd = lo_open(conn, lobjId, INV_READ);
-    if (lobj_fd &lt; 0) {
-     fprintf(stderr,"can't open large object %d\n",
-          lobjId);
+    if (lobj_fd &lt; 0)
+    {
+        fprintf(stderr, &quot;can't open large object %d\n&quot;,
+                lobjId);
     }
 
     /*
      * open the file to be written to
      */
-    fd = open(filename, O_CREAT|O_WRONLY, 0666);
-    if (fd &lt; 0)  {   /* error */
-     fprintf(stderr, "can't open unix file %s\n",
-          filename);
+    fd = open(filename, O_CREAT | O_WRONLY, 0666);
+    if (fd &lt; 0)
+    {                           /* error */
+        fprintf(stderr, &quot;can't open unix file %s\n&quot;,
+                filename);
     }
 
     /*
      * read in from the Unix file and write to the inversion file
      */
-    while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) &gt; 0) {
-     tmp = write(fd, buf, nbytes);
-        if (tmp &lt; nbytes) {
-         fprintf(stderr,"error while writing %s\n",
-              filename);
-     }
+    while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) &gt; 0)
+    {
+        tmp = write(fd, buf, nbytes);
+        if (tmp &lt; nbytes)
+        {
+            fprintf(stderr, &quot;error while writing %s\n&quot;,
+                    filename);
+        }
     }
 
     (void) lo_close(conn, lobj_fd);
@@ -470,25 +488,27 @@ void exportFile(PGconn *conn, Oid lobjId, char *filename)
 }
 
 void
-exit_nicely(PGconnconn)
+exit_nicely(PGconn *conn)
 {
-  PQfinish(conn);
-  exit(1);
+    PQfinish(conn);
+    exit(1);
 }
 
 int
 main(int argc, char **argv)
 {
-    char *in_filename, *out_filename;
-    char *database;
-    Oid lobjOid;
-    PGconn *conn;
-    PGresult *res;
-
-    if (argc != 4) {
-     fprintf(stderr, "Usage: %s database_name in_filename out_filename\n",
-          argv[0]);
-     exit(1);
+    char       *in_filename,
+               *out_filename;
+    char       *database;
+    Oid         lobjOid;
+    PGconn     *conn;
+    PGresult   *res;
+
+    if (argc != 4)
+    {
+        fprintf(stderr, &quot;Usage: %s database_name in_filename out_filename\n&quot;,
+                argv[0]);
+        exit(1);
     }
 
     database = argv[1];
@@ -501,33 +521,34 @@ main(int argc, char **argv)
     conn = PQsetdb(NULL, NULL, NULL, NULL, database);
 
     /* check to see that the backend connection was successfully made */
-    if (PQstatus(conn) == CONNECTION_BAD) {
-     fprintf(stderr,"Connection to database '%s' failed.\n", database);
-     fprintf(stderr,"%s",PQerrorMessage(conn));
-     exit_nicely(conn);
+    if (PQstatus(conn) == CONNECTION_BAD)
+    {
+        fprintf(stderr, &quot;Connection to database '%s' failed.\n&quot;, database);
+        fprintf(stderr, &quot;%s&quot;, PQerrorMessage(conn));
+        exit_nicely(conn);
     }
 
-    res = PQexec(conn, "begin");
+    res = PQexec(conn, &quot;begin&quot;);
     PQclear(res);
 
-    printf("importing file %s\n", in_filename);
+    printf(&quot;importing file %s\n&quot;, in_filename);
 /*  lobjOid = importFile(conn, in_filename); */
     lobjOid = lo_import(conn, in_filename);
 /*
-    printf("as large object %d.\n", lobjOid);
+    printf(&quot;as large object %d.\n&quot;, lobjOid);
 
-    printf("picking out bytes 1000-2000 of the large object\n");
+    printf(&quot;picking out bytes 1000-2000 of the large object\n&quot;);
     pickout(conn, lobjOid, 1000, 1000);
 
-    printf("overwriting bytes 1000-2000 of the large object with X's\n");
+    printf(&quot;overwriting bytes 1000-2000 of the large object with X's\n&quot;);
     overwrite(conn, lobjOid, 1000, 1000);
 */
 
-    printf("exporting large object to file %s\n", out_filename);
+    printf(&quot;exporting large object to file %s\n&quot;, out_filename);
 /*    exportFile(conn, lobjOid, out_filename); */
-    lo_export(conn, lobjOid,out_filename);
+    lo_export(conn, lobjOid, out_filename);
 
-    res = PQexec(conn, "end");
+    res = PQexec(conn, &quot;end&quot;);
     PQclear(res);
     PQfinish(conn);
     exit(0);