libpurple/util.c

changeset 21421
1d0f0d592011
parent 21389
e1dd8142bb87
child 21441
eab0555e2eab
equal deleted inserted replaced
21419:32f38f0d713f 21421:1d0f0d592011
2559 { 2559 {
2560 gchar *filename_temp; 2560 gchar *filename_temp;
2561 FILE *file; 2561 FILE *file;
2562 size_t real_size, byteswritten; 2562 size_t real_size, byteswritten;
2563 struct stat st; 2563 struct stat st;
2564 #ifndef HAVE_FILENO
2565 int fd;
2566 #endif
2564 2567
2565 purple_debug_info("util", "Writing file %s\n", 2568 purple_debug_info("util", "Writing file %s\n",
2566 filename_full); 2569 filename_full);
2567 2570
2568 g_return_val_if_fail((size >= -1), FALSE); 2571 g_return_val_if_fail((size >= -1), FALSE);
2593 2596
2594 /* Write to file */ 2597 /* Write to file */
2595 real_size = (size == -1) ? strlen(data) : (size_t) size; 2598 real_size = (size == -1) ? strlen(data) : (size_t) size;
2596 byteswritten = fwrite(data, 1, real_size, file); 2599 byteswritten = fwrite(data, 1, real_size, file);
2597 2600
2601 #ifdef HAVE_FILENO
2602 /* Apparently XFS (and possibly other filesystems) do not
2603 * guarantee that file data is flushed before file metadata,
2604 * so this procedure is insufficient without some flushage. */
2605 if (fsync(fileno(file)) < 0) {
2606 purple_debug_error("util", "Error syncing file contents for %s: %s\n",
2607 filename_temp, g_strerror(errno));
2608 g_free(filename_temp);
2609 fclose(file);
2610 return FALSE;
2611 }
2612 #endif
2613
2598 /* Close file */ 2614 /* Close file */
2599 if (fclose(file) != 0) 2615 if (fclose(file) != 0)
2600 { 2616 {
2601 purple_debug_error("util", "Error closing file %s: %s\n", 2617 purple_debug_error("util", "Error closing file %s: %s\n",
2602 filename_temp, g_strerror(errno)); 2618 filename_temp, g_strerror(errno));
2603 g_free(filename_temp); 2619 g_free(filename_temp);
2604 return FALSE; 2620 return FALSE;
2605 } 2621 }
2622
2623 #ifndef HAVE_FILENO
2624 /* This is the same effect (we hope) as the HAVE_FILENO block
2625 * above, but for systems without fileno(). */
2626 if ((fd = open(filename_temp, O_RDWR)) < 0) {
2627 purple_debug_error("util", "Error opening file %s for flush: %s\n",
2628 filename_temp, g_strerror(errno));
2629 g_free(filename_temp);
2630 return FALSE;
2631 }
2632 if (fsync(fd) < 0) {
2633 purple_debug_error("util", "Error syncing %s: %s\n",
2634 filename_temp, g_strerror(errno));
2635 g_free(filename_temp);
2636 close(fd);
2637 return FALSE;
2638 }
2639 if (close(fd) < 0) {
2640 purple_debug_error("util", "Error closing %s after sync: %s\n",
2641 filename_temp, g_strerror(errno));
2642 g_free(filename_temp);
2643 return FALSE;
2644 }
2645 #endif
2606 2646
2607 /* Ensure the file is the correct size */ 2647 /* Ensure the file is the correct size */
2608 if (byteswritten != real_size) 2648 if (byteswritten != real_size)
2609 { 2649 {
2610 purple_debug_error("util", "Error writing to file %s: Wrote %" 2650 purple_debug_error("util", "Error writing to file %s: Wrote %"

mercurial