checks if the SCB file exists, creates a new one in case it doesn't. */
| 105 | |
| 106 | /* checks if the SCB file exists, creates a new one in case it doesn't. */ |
| 107 | static void maybe_create_new_scb(struct plugin *p, |
| 108 | struct scb_chan **channels) |
| 109 | { |
| 110 | |
| 111 | /* Note that this is opened for write-only, even though the permissions |
| 112 | * are set to read-only. That's perfectly valid! */ |
| 113 | int fd = open("emergency.recover", O_CREAT|O_EXCL|O_WRONLY, 0400); |
| 114 | if (fd < 0) { |
| 115 | /* Don't do anything if the file already exists. */ |
| 116 | if (errno == EEXIST) |
| 117 | return; |
| 118 | plugin_err(p, "creating: %s", strerror(errno)); |
| 119 | } |
| 120 | |
| 121 | /* Comes here only if the file haven't existed before */ |
| 122 | unlink_noerr("emergency.recover"); |
| 123 | |
| 124 | /* This couldn't give EEXIST because we call unlink_noerr("scb.tmp") |
| 125 | * in INIT */ |
| 126 | fd = open("scb.tmp", O_CREAT|O_EXCL|O_WRONLY, 0400); |
| 127 | if (fd < 0) |
| 128 | plugin_err(p, "Opening: %s", strerror(errno)); |
| 129 | |
| 130 | plugin_log(p, LOG_INFORM, "Creating Emergency Recovery"); |
| 131 | |
| 132 | write_scb(p, fd, channels); |
| 133 | |
| 134 | /* fsync (mostly!) ensures that the file has reached the disk. */ |
| 135 | if (fsync(fd) != 0) { |
| 136 | unlink_noerr("scb.tmp"); |
| 137 | plugin_err(p, "fsync : %s", strerror(errno)); |
| 138 | } |
| 139 | |
| 140 | /* This should never fail if fsync succeeded. But paranoia good, and |
| 141 | * bugs exist. */ |
| 142 | if (close(fd) != 0) { |
| 143 | unlink_noerr("scb.tmp"); |
| 144 | plugin_err(p, "closing: %s", strerror(errno)); |
| 145 | } |
| 146 | |
| 147 | /* We actually need to sync the *directory itself* to make sure the |
| 148 | * file exists! You're only allowed to open directories read-only in |
| 149 | * modern Unix though. */ |
| 150 | fd = open(".", O_RDONLY); |
| 151 | if (fd < 0) |
| 152 | plugin_err(p, "Opening: %s", strerror(errno)); |
| 153 | |
| 154 | if (fsync(fd) != 0) { |
| 155 | unlink_noerr("scb.tmp"); |
| 156 | plugin_err(p, "closing: %s", strerror(errno)); |
| 157 | } |
| 158 | |
| 159 | /* This will never fail, if fsync worked! */ |
| 160 | close(fd); |
| 161 | |
| 162 | /* This will update the scb file */ |
| 163 | rename("scb.tmp", "emergency.recover"); |
| 164 | } |
no test coverage detected