137 #include <sys/stat.h>
146 #define FILE_PERM_MASK \
147 (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
163 #define EDIT_FILE_REUSE_AFTER_CRASH
168 #define EDIT_FILE_MODE (S_IRUSR | S_IWUSR)
174 #define EDIT_FILE_ALLOC(ep, path, mode) do { \
175 (ep) = (EDIT_FILE *) mymalloc(sizeof(EDIT_FILE)); \
176 (ep)->final_path = mystrdup(path); \
177 (ep)->final_mode = (mode); \
178 (ep)->tmp_path = concatenate((path), EDIT_FILE_SUFFIX, (char *) 0); \
182 #define EDIT_FILE_FREE(ep) do { \
183 myfree((ep)->final_path); \
184 myfree((ep)->tmp_path); \
185 myfree((void *) (ep)); \
192 struct stat before_lock;
193 struct stat after_lock;
250 || before_lock.st_dev != after_lock.st_dev
251 || before_lock.st_ino != after_lock.st_ino
253 || before_lock.st_gen != after_lock.st_gen
282 if (!S_ISREG(after_lock.st_mode)
284 || after_lock.st_size > 0
286 || after_lock.st_nlink > 1
288 if (unlink(ep->
tmp_path) < 0 && errno != ENOENT)
296 #ifdef EDIT_FILE_REUSE_AFTER_CRASH
312 if (unlink(ep->
tmp_path) < 0 && errno != ENOENT)
void edit_file_cleanup(EDIT_FILE *ep)
#define MYFLOCK_OP_EXCLUSIVE
VSTREAM * vstream_fopen(const char *path, int flags, mode_t mode)
int vstream_fclose(VSTREAM *stream)
#define EDIT_FILE_FREE(ep)
int myflock(int fd, int lock_style, int operation)
int edit_file_close(EDIT_FILE *ep)
NORETURN msg_fatal(const char *fmt,...)
int vstream_fflush(VSTREAM *stream)
#define EDIT_FILE_REUSE_AFTER_CRASH
#define EDIT_FILE_ALLOC(ep, path, mode)
#define vstream_fileno(vp)
EDIT_FILE * edit_file_open(const char *path, int flags, mode_t mode)