88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/interfaces/libpq/fe-lobj.c,v 1.56 2006/03/05 15:59:09 momjian Exp $
11+ * $PostgreSQL: pgsql/src/interfaces/libpq/fe-lobj.c,v 1.57 2006/06/14 01:28:55 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -58,6 +58,12 @@ lo_open(PGconn *conn, Oid lobjId, int mode)
5858PQArgBlock argv [2 ];
5959PGresult * res ;
6060
61+ if (conn -> lobjfuncs == NULL )
62+ {
63+ if (lo_initialize (conn )< 0 )
64+ return -1 ;
65+ }
66+
6167argv [0 ].isint = 1 ;
6268argv [0 ].len = 4 ;
6369argv [0 ].u .integer = lobjId ;
@@ -66,12 +72,6 @@ lo_open(PGconn *conn, Oid lobjId, int mode)
6672argv [1 ].len = 4 ;
6773argv [1 ].u .integer = mode ;
6874
69- if (conn -> lobjfuncs == NULL )
70- {
71- if (lo_initialize (conn )< 0 )
72- return -1 ;
73- }
74-
7575res = PQfn (conn ,conn -> lobjfuncs -> fn_lo_open ,& fd ,& result_len ,1 ,argv ,2 );
7676if (PQresultStatus (res )== PGRES_COMMAND_OK )
7777{
@@ -438,23 +438,22 @@ lo_import(PGconn *conn, const char *filename)
438438char buf [LO_BUFSIZE ];
439439Oid lobjOid ;
440440int lobj ;
441+ char sebuf [256 ];
441442
442443/*
443444 * open the file to be read in
444445 */
445446fd = open (filename ,O_RDONLY |PG_BINARY ,0666 );
446447if (fd < 0 )
447448{/* error */
448- char sebuf [256 ];
449-
450449printfPQExpBuffer (& conn -> errorMessage ,
451450libpq_gettext ("could not open file \"%s\": %s\n" ),
452451filename ,pqStrerror (errno ,sebuf ,sizeof (sebuf )));
453452return InvalidOid ;
454453}
455454
456455/*
457- * create an inversion" object"
456+ * create an inversion object
458457 */
459458lobjOid = lo_creat (conn ,INV_READ |INV_WRITE );
460459if (lobjOid == InvalidOid )
@@ -477,41 +476,65 @@ lo_import(PGconn *conn, const char *filename)
477476}
478477
479478/*
480- * read in from theUnix file and write to theinversion file
479+ * read in from the file and write to thelarge object
481480 */
482481while ((nbytes = read (fd ,buf ,LO_BUFSIZE ))> 0 )
483482{
484483tmp = lo_write (conn ,lobj ,buf ,nbytes );
485- if (tmp < nbytes )
484+ if (tmp != nbytes )
486485{
486+ /*
487+ * If the lo_write failed, we are probably in an aborted
488+ * transaction and so lo_close will fail. Try it anyway for
489+ * cleanliness, but don't let it determine the returned error
490+ * message.
491+ */
492+ (void )lo_close (conn ,lobj );
493+
487494printfPQExpBuffer (& conn -> errorMessage ,
488- libpq_gettext ("error whilereading file \"%s\" \n" ),
489- filename );
495+ libpq_gettext ("error whilewriting large object %u \n" ),
496+ lobjOid );
490497(void )close (fd );
491- (void )lo_close (conn ,lobj );
492498return InvalidOid ;
493499}
494500}
495501
502+ if (nbytes < 0 )
503+ {
504+ printfPQExpBuffer (& conn -> errorMessage ,
505+ libpq_gettext ("could not read from file \"%s\": %s\n" ),
506+ filename ,pqStrerror (errno ,sebuf ,sizeof (sebuf )));
507+ lobjOid = InvalidOid ;
508+ }
509+
496510(void )close (fd );
497- (void )lo_close (conn ,lobj );
511+
512+ if (lo_close (conn ,lobj )!= 0 )
513+ {
514+ printfPQExpBuffer (& conn -> errorMessage ,
515+ libpq_gettext ("error while writing large object %u\n" ),
516+ lobjOid );
517+ return InvalidOid ;
518+ }
498519
499520return lobjOid ;
500521}
501522
502523/*
503524 * lo_export -
504525 * exports an (inversion) large object.
505- * returns -1 upon failure, 1otherwise
526+ * returns -1 upon failure, 1if OK
506527 */
507528int
508529lo_export (PGconn * conn ,Oid lobjId ,const char * filename )
509530{
531+ int result = 1 ;
510532int fd ;
511533int nbytes ,
512534tmp ;
513535char buf [LO_BUFSIZE ];
514536int lobj ;
537+ char sebuf [256 ];
515538
516539/*
517540 * open the large object.
@@ -530,8 +553,6 @@ lo_export(PGconn *conn, Oid lobjId, const char *filename)
530553fd = open (filename ,O_CREAT |O_WRONLY |O_TRUNC |PG_BINARY ,0666 );
531554if (fd < 0 )
532555{/* error */
533- char sebuf [256 ];
534-
535556printfPQExpBuffer (& conn -> errorMessage ,
536557libpq_gettext ("could not open file \"%s\": %s\n" ),
537558filename ,pqStrerror (errno ,sebuf ,sizeof (sebuf )));
@@ -540,33 +561,39 @@ lo_export(PGconn *conn, Oid lobjId, const char *filename)
540561}
541562
542563/*
543- * read in from theinversion file and write to the Unix file
564+ * read in from thelarge object and write to the file
544565 */
545566while ((nbytes = lo_read (conn ,lobj ,buf ,LO_BUFSIZE ))> 0 )
546567{
547568tmp = write (fd ,buf ,nbytes );
548- if (tmp < nbytes )
569+ if (tmp != nbytes )
549570{
550571printfPQExpBuffer (& conn -> errorMessage ,
551- libpq_gettext ("error while writing to file \"%s\"\n" ),
552- filename );
572+ libpq_gettext ("error while writing to file \"%s\": %s \n" ),
573+ filename , pqStrerror ( errno , sebuf , sizeof ( sebuf )) );
553574(void )lo_close (conn ,lobj );
554575(void )close (fd );
555576return -1 ;
556577}
557578}
558579
559- (void )lo_close (conn ,lobj );
580+ if (lo_close (conn ,lobj )!= 0 || nbytes < 0 )
581+ {
582+ printfPQExpBuffer (& conn -> errorMessage ,
583+ libpq_gettext ("error while reading large object %u\n" ),
584+ lobjId );
585+ result = -1 ;
586+ }
560587
561588if (close (fd ))
562589{
563590printfPQExpBuffer (& conn -> errorMessage ,
564- libpq_gettext ("error while writing to file \"%s\"\n" ),
565- filename );
566- return -1 ;
591+ libpq_gettext ("error while writing to file \"%s\": %s \n" ),
592+ filename , pqStrerror ( errno , sebuf , sizeof ( sebuf )) );
593+ result = -1 ;
567594}
568595
569- return 1 ;
596+ return result ;
570597}
571598
572599