/* $Id: tempfile.C,v 1.1 1999/09/28 02:40:22 dm Exp $ */ /* * * Copyright (C) 1999 David Mazieres (dm@uun.org) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * */ #include "tempfile.h" tempfile::tempfile (const str &p, mode_t mode) : err (0), path (p) { if (path) { fd = open (path, O_CREAT|O_EXCL|O_WRONLY, mode); if (fd < 0) err = errno; } else { fd = -1; err = EINVAL; } } void tempfile::destroy () { if (fd >= 0) { close (fd); unlink (path); } fd = -1; } void tempfile::flush (bool force) { if (err) buf.tosuio ()->clear (); else if ((force || buf.tosuio ()->resid () >= 8192) && buf.tosuio ()->output (fd) < 0) { err = errno; destroy (); } else if (force && buf.tosuio ()->resid ()) { err = EAGAIN; destroy (); } } bool tempfile::rename (str dest) { flush (true); int oerr = err; err = EINVAL; if (oerr) { destroy (); errno = oerr; return false; } int ofd = fd; fd = -1; if (fsync (ofd) < 0) { int saved_errno = errno; close (ofd); unlink (path); errno = saved_errno; return false; } if (close (ofd) < 0 || ::rename (path, dest) < 0) { int saved_errno = errno; unlink (path); errno = saved_errno; return false; } return true; }