Show
Ignore:
Timestamp:
11/29/11 21:26:35 (2 years ago)
Author:
Theo Schlossnagle <jesus@omniti.com>
git-committer:
Theo Schlossnagle <jesus@omniti.com> 1322601995 -0500
git-parent:

[e09f057cc61b7872af870562a9ca11fc52860502]

git-author:
Theo Schlossnagle <jesus@omniti.com> 1322601995 -0500
Message:

on-disk backing store implementation

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • src/noit_xml.c

    rc30a0fe r8e9cf57  
    3131 */ 
    3232 
     33#include "noit_defines.h" 
    3334#include "noit_xml.h" 
     35#include "utils/noit_log.h" 
     36#include "utils/noit_mkdir.h" 
     37#include <fcntl.h> 
     38#include <unistd.h> 
     39#include <errno.h> 
    3440#include <assert.h> 
    3541 
     
    8591} 
    8692 
     93int 
     94noit_xmlSaveToFile(xmlDocPtr doc, const char *filename) { 
     95  int rv = -1, fd, have_backup = 0, once; 
     96  char tmpfile[PATH_MAX], bakfile[PATH_MAX]; 
     97  xmlOutputBufferPtr out; 
     98  xmlCharEncodingHandlerPtr enc; 
     99 
     100  snprintf(tmpfile, sizeof(tmpfile), "%s.tmp", filename); 
     101  snprintf(bakfile, sizeof(bakfile), "%s.bak", filename); 
     102  once = 1; 
     103 mkbkup: 
     104  if(link(filename, bakfile) == 0) { 
     105    unlink(filename); 
     106    have_backup = 1; 
     107  } 
     108  else if (errno != ENOENT) { 
     109    if(!once) return -1; 
     110    once = 0; 
     111    if(errno == EEXIST) { 
     112      unlink(bakfile); 
     113      goto mkbkup; 
     114    } 
     115    noitL(noit_error, "Cannot create backup for %s: %s\n", 
     116          filename, strerror(errno)); 
     117    return -1; 
     118  } 
     119  else { 
     120    noitL(noit_debug, "link(%s,%s) -> %s\n", filename, bakfile, strerror(errno)); 
     121  } 
     122 
     123 retry: 
     124  fd = open(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0640); 
     125  if(fd < 0) { 
     126    if(!once) return -1; 
     127    once = 0; 
     128    if(errno == ENOENT) { 
     129      if(mkdir_for_file(tmpfile, 0750) == 0) goto retry; 
     130    } 
     131    if(errno == EEXIST) { 
     132      unlink(tmpfile); 
     133      goto retry; 
     134    } 
     135    return -1; 
     136  } 
     137  enc = xmlGetCharEncodingHandler(XML_CHAR_ENCODING_UTF8); 
     138  out = xmlOutputBufferCreateFd(fd, enc); 
     139  assert(out); 
     140  xmlSaveFormatFileTo(out, doc, "utf8", 1); 
     141  close(fd); 
     142  rv = 0; 
     143  if(link(tmpfile, filename)) { 
     144    rv = -1; 
     145    if(link(bakfile, filename) != 0) have_backup = 0; 
     146  } 
     147  unlink(tmpfile); 
     148  if(have_backup) 
     149    unlink(bakfile); 
     150  return rv; 
     151}