- file = fopen(pidfile, "w");
- if (file) {
- fprintf(file, "%ld\n", (long int) pid);
- fclose(file);
+ tmpfile = xasprintf("%s.tmp%ld", pidfile, pid);
+ fatal_signal_add_file_to_unlink(tmpfile);
+ fd = open(tmpfile, O_CREAT | O_WRONLY | O_TRUNC, 0666);
+ if (fd >= 0) {
+ struct flock lck;
+ lck.l_type = F_WRLCK;
+ lck.l_whence = SEEK_SET;
+ lck.l_start = 0;
+ lck.l_len = 0;
+ if (fcntl(fd, F_SETLK, &lck) >= 0) {
+ char *text = xasprintf("%ld\n", pid);
+ if (write(fd, text, strlen(text)) == strlen(text)) {
+ fatal_signal_add_file_to_unlink(pidfile);
+ if (rename(tmpfile, pidfile) < 0) {
+ VLOG_ERR("failed to rename \"%s\" to \"%s\": %s",
+ tmpfile, pidfile, strerror(errno));
+ fatal_signal_remove_file_to_unlink(pidfile);
+ close(fd);
+ } else {
+ /* Keep 'fd' open to retain the lock. */
+ }
+ } else {
+ VLOG_ERR("%s: write failed: %s", tmpfile, strerror(errno));
+ close(fd);
+ }
+ } else {
+ VLOG_ERR("%s: fcntl failed: %s", tmpfile, strerror(errno));
+ close(fd);
+ }