* lo_export - * exports an (inversion) large object. * returns -1 upon failure, 1 if OK */
| 754 | * returns -1 upon failure, 1 if OK |
| 755 | */ |
| 756 | int |
| 757 | lo_export(PGconn *conn, Oid lobjId, const char *filename) |
| 758 | { |
| 759 | int result = 1; |
| 760 | int fd; |
| 761 | int nbytes, |
| 762 | tmp; |
| 763 | char buf[LO_BUFSIZE]; |
| 764 | int lobj; |
| 765 | char sebuf[PG_STRERROR_R_BUFLEN]; |
| 766 | |
| 767 | /* |
| 768 | * open the large object. |
| 769 | */ |
| 770 | lobj = lo_open(conn, lobjId, INV_READ); |
| 771 | if (lobj == -1) |
| 772 | { |
| 773 | /* we assume lo_open() already set a suitable error message */ |
| 774 | return -1; |
| 775 | } |
| 776 | |
| 777 | /* |
| 778 | * create the file to be written to |
| 779 | */ |
| 780 | fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC | PG_BINARY, 0666); |
| 781 | if (fd < 0) |
| 782 | { |
| 783 | /* We must do lo_close before setting the errorMessage */ |
| 784 | int save_errno = errno; |
| 785 | |
| 786 | (void) lo_close(conn, lobj); |
| 787 | /* deliberately overwrite any error from lo_close */ |
| 788 | printfPQExpBuffer(&conn->errorMessage, |
| 789 | libpq_gettext("could not open file \"%s\": %s\n"), |
| 790 | filename, |
| 791 | strerror_r(save_errno, sebuf, sizeof(sebuf))); |
| 792 | return -1; |
| 793 | } |
| 794 | |
| 795 | /* |
| 796 | * read in from the large object and write to the file |
| 797 | */ |
| 798 | while ((nbytes = lo_read(conn, lobj, buf, LO_BUFSIZE)) > 0) |
| 799 | { |
| 800 | tmp = write(fd, buf, nbytes); |
| 801 | if (tmp != nbytes) |
| 802 | { |
| 803 | /* We must do lo_close before setting the errorMessage */ |
| 804 | int save_errno = errno; |
| 805 | |
| 806 | (void) lo_close(conn, lobj); |
| 807 | (void) close(fd); |
| 808 | /* deliberately overwrite any error from lo_close */ |
| 809 | printfPQExpBuffer(&conn->errorMessage, |
| 810 | libpq_gettext("could not write to file \"%s\": %s\n"), |
| 811 | filename, |
| 812 | strerror_r(save_errno, sebuf, sizeof(sebuf))); |
| 813 | return -1; |