+
+ file = fopen(tmpfile, "a+");
+ if (!file) {
+ VLOG_FATAL("%s: create failed (%s)", tmpfile, ovs_strerror(errno));
+ }
+
+ error = lock_pidfile(file, F_SETLK);
+ if (error) {
+ /* Looks like we failed to acquire the lock. Note that, if we failed
+ * for some other reason (and '!overwrite_pidfile'), we will have
+ * left 'tmpfile' as garbage in the file system. */
+ VLOG_FATAL("%s: fcntl(F_SETLK) failed (%s)", tmpfile,
+ ovs_strerror(error));
+ }
+
+ if (!overwrite_pidfile) {
+ /* We acquired the lock. Make sure to clean up on exit, and verify
+ * that we're allowed to create the actual pidfile. */
+ fatal_signal_add_file_to_unlink(tmpfile);
+ check_already_running();
+ }
+
+ if (fstat(fileno(file), &s) == -1) {
+ VLOG_FATAL("%s: fstat failed (%s)", tmpfile, ovs_strerror(errno));
+ }
+
+ if (ftruncate(fileno(file), 0) == -1) {
+ VLOG_FATAL("%s: truncate failed (%s)", tmpfile, ovs_strerror(errno));
+ }
+
+ fprintf(file, "%ld\n", pid);
+ if (fflush(file) == EOF) {
+ VLOG_FATAL("%s: write failed (%s)", tmpfile, ovs_strerror(errno));
+ }
+
+ error = rename(tmpfile, pidfile);
+
+ /* Due to a race, 'tmpfile' may be owned by a different process, so we
+ * shouldn't delete it on exit. */
+ fatal_signal_remove_file_to_unlink(tmpfile);
+
+ if (error < 0) {
+ VLOG_FATAL("failed to rename \"%s\" to \"%s\" (%s)",
+ tmpfile, pidfile, ovs_strerror(errno));
+ }
+
+ /* Ensure that the pidfile will get deleted on exit. */
+ fatal_signal_add_file_to_unlink(pidfile);
+
+ /* Clean up.
+ *
+ * We don't close 'file' because its file descriptor must remain open to
+ * hold the lock. */
+ pidfile_dev = s.st_dev;
+ pidfile_ino = s.st_ino;
+ free(tmpfile);