|
Lines 2-7
Link Here
|
| 2 |
* - added Native Language Support |
2 |
* - added Native Language Support |
| 3 |
* Sun Mar 21 1999 - Arnaldo Carvalho de Melo <acme@conectiva.com.br> |
3 |
* Sun Mar 21 1999 - Arnaldo Carvalho de Melo <acme@conectiva.com.br> |
| 4 |
* - fixed strerr(errno) in gettext calls |
4 |
* - fixed strerr(errno) in gettext calls |
|
|
5 |
* 2003-08-08 Thomas Hood <jdthood@yahoo.co.uk> with help from Patrick McLean |
| 6 |
* - Write through a symlink at /etc/mtab if it doesn't point into /proc/ |
| 5 |
*/ |
7 |
*/ |
| 6 |
|
8 |
|
| 7 |
#include <unistd.h> |
9 |
#include <unistd.h> |
|
Lines 13-71
Link Here
|
| 13 |
#include <time.h> |
15 |
#include <time.h> |
| 14 |
#include "mount_mntent.h" |
16 |
#include "mount_mntent.h" |
| 15 |
#include "fstab.h" |
17 |
#include "fstab.h" |
|
|
18 |
#include "realpath.h" |
| 16 |
#include "sundries.h" |
19 |
#include "sundries.h" |
| 17 |
#include "xmalloc.h" |
20 |
#include "xmalloc.h" |
| 18 |
#include "fsprobe.h" |
21 |
#include "fsprobe.h" |
| 19 |
#include "mount_paths.h" |
22 |
#include "mount_paths.h" |
| 20 |
#include "nls.h" |
23 |
#include "nls.h" |
| 21 |
|
24 |
|
| 22 |
#define streq(s, t) (strcmp ((s), (t)) == 0) |
25 |
/* A 64 bit number can be displayed in 20 decimal digits */ |
| 23 |
|
26 |
#define LEN_LARGEST_PID 20 |
| 24 |
#define PROC_MOUNTS "/proc/mounts" |
27 |
#define MTAB_PATH_MAX (PATH_MAX - (sizeof(MTAB_LOCK_SUFFIX) - 1) - LEN_LARGEST_PID) |
| 25 |
|
|
|
| 26 |
|
28 |
|
| 27 |
/* Information about mtab. ------------------------------------*/ |
29 |
/* Information about mtab. ------------------------------------*/ |
| 28 |
static int have_mtab_info = 0; |
30 |
static char mtab_path[MTAB_PATH_MAX]; |
| 29 |
static int var_mtab_does_not_exist = 0; |
31 |
static char mtab_lock_path[PATH_MAX]; |
| 30 |
static int var_mtab_is_a_symlink = 0; |
32 |
static char mtab_lock_targ[PATH_MAX]; |
|
|
33 |
static char mtab_temp_path[PATH_MAX]; |
| 31 |
|
34 |
|
| 32 |
static void |
35 |
/* |
|
|
36 |
* Set mtab_path to the real path of the mtab file |
| 37 |
* or to the null string if that path is inaccessible |
| 38 |
* |
| 39 |
* Run this early |
| 40 |
*/ |
| 41 |
void |
| 33 |
get_mtab_info(void) { |
42 |
get_mtab_info(void) { |
| 34 |
struct stat mtab_stat; |
43 |
struct stat mtab_stat; |
| 35 |
|
44 |
|
| 36 |
if (!have_mtab_info) { |
45 |
if (lstat(MOUNTED, &mtab_stat)) { |
| 37 |
if (lstat(MOUNTED, &mtab_stat)) |
46 |
/* Assume that the lstat error means that the file does not exist */ |
| 38 |
var_mtab_does_not_exist = 1; |
47 |
/* (Maybe we should check errno here) */ |
| 39 |
else if (S_ISLNK(mtab_stat.st_mode)) |
48 |
strcpy(mtab_path, MOUNTED); |
| 40 |
var_mtab_is_a_symlink = 1; |
49 |
} else if (S_ISLNK(mtab_stat.st_mode)) { |
| 41 |
have_mtab_info = 1; |
50 |
/* Is a symlink */ |
|
|
51 |
int len; |
| 52 |
char *r = myrealpath(MOUNTED, mtab_path, MTAB_PATH_MAX); |
| 53 |
mtab_path[MTAB_PATH_MAX - 1] = 0; /* Just to be sure */ |
| 54 |
len = strlen(mtab_path); |
| 55 |
if ( |
| 56 |
r == NULL |
| 57 |
|| len == 0 |
| 58 |
|| len >= (MTAB_PATH_MAX - 1) |
| 59 |
|| streqn(mtab_path, PATH_PROC, sizeof(PATH_PROC) - 1) |
| 60 |
) { |
| 61 |
/* Real path invalid or inaccessible */ |
| 62 |
mtab_path[0] = '\0'; |
| 63 |
return; |
| 64 |
} |
| 65 |
/* mtab_path now contains mtab's real path */ |
| 66 |
} else { |
| 67 |
/* Exists and is not a symlink */ |
| 68 |
strcpy(mtab_path, MOUNTED); |
| 42 |
} |
69 |
} |
|
|
70 |
|
| 71 |
sprintf(mtab_lock_path, "%s%s", mtab_path, MTAB_LOCK_SUFFIX); |
| 72 |
sprintf(mtab_lock_targ, "%s%s%d", mtab_path, MTAB_LOCK_SUFFIX, getpid()); |
| 73 |
sprintf(mtab_temp_path, "%s%s", mtab_path, MTAB_TEMP_SUFFIX); |
| 43 |
} |
74 |
} |
| 44 |
|
75 |
|
|
|
76 |
|
| 77 |
/* |
| 78 |
* Tell whether or not the mtab real path is accessible |
| 79 |
* |
| 80 |
* get_mtab_info() must have been run |
| 81 |
*/ |
| 82 |
static int |
| 83 |
mtab_is_accessible(void) { |
| 84 |
return (mtab_path[0] != '\0'); |
| 85 |
} |
| 86 |
|
| 87 |
/* |
| 88 |
* Tell whether or not the mtab file currently exists |
| 89 |
* |
| 90 |
* Note that the answer here is independent of whether or |
| 91 |
* not the file is writable, so if you are planning to create |
| 92 |
* the mtab file then check mtab_is_writable() too. |
| 93 |
* |
| 94 |
* get_mtab_info() must have been run |
| 95 |
*/ |
| 45 |
int |
96 |
int |
| 46 |
mtab_does_not_exist(void) { |
97 |
mtab_does_not_exist(void) { |
| 47 |
get_mtab_info(); |
98 |
struct stat mtab_stat; |
| 48 |
return var_mtab_does_not_exist; |
|
|
| 49 |
} |
| 50 |
|
99 |
|
| 51 |
static int |
100 |
if (!mtab_is_accessible()) |
| 52 |
mtab_is_a_symlink(void) { |
101 |
return 1; |
| 53 |
get_mtab_info(); |
102 |
|
| 54 |
return var_mtab_is_a_symlink; |
103 |
if (lstat(mtab_path, &mtab_stat)) |
|
|
104 |
return 1; |
| 105 |
|
| 106 |
return 0; |
| 55 |
} |
107 |
} |
| 56 |
|
108 |
|
|
|
109 |
/* |
| 110 |
* Tell whether or not mtab is writable (whether or not it currently exists) |
| 111 |
* |
| 112 |
* This depends on whether or not the real path is accessible and, |
| 113 |
* if so, whether or not the file can be opened. This function |
| 114 |
* has the side effect of creating the file if it is writable. |
| 115 |
* |
| 116 |
* get_mtab_info() must have been run |
| 117 |
*/ |
| 57 |
int |
118 |
int |
| 58 |
mtab_is_writable() { |
119 |
mtab_is_writable() { |
| 59 |
int fd; |
120 |
int fd; |
| 60 |
|
121 |
|
| 61 |
/* Should we write to /etc/mtab upon an update? |
122 |
if (!mtab_is_accessible()) |
| 62 |
Probably not if it is a symlink to /proc/mounts, since that |
|
|
| 63 |
would create a file /proc/mounts in case the proc filesystem |
| 64 |
is not mounted. */ |
| 65 |
if (mtab_is_a_symlink()) |
| 66 |
return 0; |
123 |
return 0; |
| 67 |
|
124 |
|
| 68 |
fd = open(MOUNTED, O_RDWR | O_CREAT, 0644); |
125 |
fd = open(mtab_path, O_RDWR | O_CREAT, 0644); |
| 69 |
if (fd >= 0) { |
126 |
if (fd >= 0) { |
| 70 |
close(fd); |
127 |
close(fd); |
| 71 |
return 1; |
128 |
return 1; |
|
Lines 161-181
Link Here
|
| 161 |
got_mtab = 1; |
218 |
got_mtab = 1; |
| 162 |
mc->nxt = mc->prev = NULL; |
219 |
mc->nxt = mc->prev = NULL; |
| 163 |
|
220 |
|
| 164 |
fnam = MOUNTED; |
221 |
fnam = mtab_path; |
| 165 |
mfp = my_setmntent (fnam, "r"); |
222 |
mfp = my_setmntent (fnam, "r"); |
| 166 |
if (mfp == NULL || mfp->mntent_fp == NULL) { |
223 |
if (mfp == NULL || mfp->mntent_fp == NULL) { |
| 167 |
int errsv = errno; |
224 |
int errsv = errno; |
| 168 |
fnam = PROC_MOUNTS; |
225 |
fnam = PATH_PROC_MOUNTS; |
| 169 |
mfp = my_setmntent (fnam, "r"); |
226 |
mfp = my_setmntent (fnam, "r"); |
| 170 |
if (mfp == NULL || mfp->mntent_fp == NULL) { |
227 |
if (mfp == NULL || mfp->mntent_fp == NULL) { |
| 171 |
error(_("warning: can't open %s: %s"), |
228 |
error(_("warning: can't open %s: %s"), |
| 172 |
MOUNTED, strerror (errsv)); |
229 |
mtab_path, strerror (errsv)); |
| 173 |
return; |
230 |
return; |
| 174 |
} |
231 |
} |
| 175 |
if (verbose) |
232 |
if (verbose) |
| 176 |
printf (_("mount: could not open %s - " |
233 |
printf (_("mount: could not open %s - " |
| 177 |
"using %s instead\n"), |
234 |
"using %s instead\n"), |
| 178 |
MOUNTED, PROC_MOUNTS); |
235 |
mtab_path, PATH_PROC_MOUNTS); |
| 179 |
} |
236 |
} |
| 180 |
read_mntentchn(mfp, fnam, mc); |
237 |
read_mntentchn(mfp, fnam, mc); |
| 181 |
} |
238 |
} |
|
Lines 482-488
Link Here
|
| 482 |
if (we_created_lockfile) { |
539 |
if (we_created_lockfile) { |
| 483 |
close(lockfile_fd); |
540 |
close(lockfile_fd); |
| 484 |
lockfile_fd = -1; |
541 |
lockfile_fd = -1; |
| 485 |
unlink (MOUNTED_LOCK); |
542 |
unlink (mtab_lock_path); |
| 486 |
we_created_lockfile = 0; |
543 |
we_created_lockfile = 0; |
| 487 |
} |
544 |
} |
| 488 |
} |
545 |
} |
|
Lines 501-512
Link Here
|
| 501 |
to delete the lock afterwards. Now the use of flock() is in principle |
558 |
to delete the lock afterwards. Now the use of flock() is in principle |
| 502 |
superfluous, but avoids an arbitrary sleep(). */ |
559 |
superfluous, but avoids an arbitrary sleep(). */ |
| 503 |
|
560 |
|
| 504 |
/* Where does the link point to? Obvious choices are mtab and mtab~~. |
|
|
| 505 |
HJLu points out that the latter leads to races. Right now we use |
| 506 |
mtab~.<pid> instead. Use 20 as upper bound for the length of %d. */ |
| 507 |
#define MOUNTLOCK_LINKTARGET MOUNTED_LOCK "%d" |
| 508 |
#define MOUNTLOCK_LINKTARGET_LTH (sizeof(MOUNTED_LOCK)+20) |
| 509 |
|
| 510 |
/* |
561 |
/* |
| 511 |
* The original mount locking code has used sleep(1) between attempts and |
562 |
* The original mount locking code has used sleep(1) between attempts and |
| 512 |
* maximal number of attemps has been 5. |
563 |
* maximal number of attemps has been 5. |
|
Lines 533-539
Link Here
|
| 533 |
int i; |
584 |
int i; |
| 534 |
struct timespec waittime; |
585 |
struct timespec waittime; |
| 535 |
struct timeval maxtime; |
586 |
struct timeval maxtime; |
| 536 |
char linktargetfile[MOUNTLOCK_LINKTARGET_LTH]; |
|
|
| 537 |
|
587 |
|
| 538 |
at_die = unlock_mtab; |
588 |
at_die = unlock_mtab; |
| 539 |
|
589 |
|
|
Lines 556-573
Link Here
|
| 556 |
signals_have_been_setup = 1; |
606 |
signals_have_been_setup = 1; |
| 557 |
} |
607 |
} |
| 558 |
|
608 |
|
| 559 |
sprintf(linktargetfile, MOUNTLOCK_LINKTARGET, getpid ()); |
609 |
i = open (mtab_lock_targ, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR); |
| 560 |
|
|
|
| 561 |
i = open (linktargetfile, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR); |
| 562 |
if (i < 0) { |
610 |
if (i < 0) { |
| 563 |
int errsv = errno; |
611 |
int errsv = errno; |
| 564 |
/* linktargetfile does not exist (as a file) |
612 |
/* mtab_lock_targ does not exist (as a file) |
| 565 |
and we cannot create it. Read-only filesystem? |
613 |
and we cannot create it. Read-only filesystem? |
| 566 |
Too many files open in the system? |
614 |
Too many files open in the system? |
| 567 |
Filesystem full? */ |
615 |
Filesystem full? */ |
| 568 |
die (EX_FILEIO, _("can't create lock file %s: %s " |
616 |
die (EX_FILEIO, _("can't create lock file %s: %s " |
| 569 |
"(use -n flag to override)"), |
617 |
"(use -n flag to override)"), |
| 570 |
linktargetfile, strerror (errsv)); |
618 |
mtab_lock_targ, strerror (errsv)); |
| 571 |
} |
619 |
} |
| 572 |
close(i); |
620 |
close(i); |
| 573 |
|
621 |
|
|
Lines 583-602
Link Here
|
| 583 |
struct flock flock; |
631 |
struct flock flock; |
| 584 |
int errsv, j; |
632 |
int errsv, j; |
| 585 |
|
633 |
|
| 586 |
j = link(linktargetfile, MOUNTED_LOCK); |
634 |
j = link(mtab_lock_targ, mtab_lock_path); |
| 587 |
errsv = errno; |
635 |
errsv = errno; |
| 588 |
|
636 |
|
| 589 |
if (j == 0) |
637 |
if (j == 0) |
| 590 |
we_created_lockfile = 1; |
638 |
we_created_lockfile = 1; |
| 591 |
|
639 |
|
| 592 |
if (j < 0 && errsv != EEXIST) { |
640 |
if (j < 0 && errsv != EEXIST) { |
| 593 |
(void) unlink(linktargetfile); |
641 |
(void) unlink(mtab_lock_targ); |
| 594 |
die (EX_FILEIO, _("can't link lock file %s: %s " |
642 |
die (EX_FILEIO, _("can't link lock file %s: %s " |
| 595 |
"(use -n flag to override)"), |
643 |
"(use -n flag to override)"), |
| 596 |
MOUNTED_LOCK, strerror (errsv)); |
644 |
mtab_lock_path, strerror (errsv)); |
| 597 |
} |
645 |
} |
| 598 |
|
646 |
|
| 599 |
lockfile_fd = open (MOUNTED_LOCK, O_WRONLY); |
647 |
lockfile_fd = open (mtab_lock_path, O_WRONLY); |
| 600 |
|
648 |
|
| 601 |
if (lockfile_fd < 0) { |
649 |
if (lockfile_fd < 0) { |
| 602 |
/* Strange... Maybe the file was just deleted? */ |
650 |
/* Strange... Maybe the file was just deleted? */ |
|
Lines 606-615
Link Here
|
| 606 |
we_created_lockfile = 0; |
654 |
we_created_lockfile = 0; |
| 607 |
continue; |
655 |
continue; |
| 608 |
} |
656 |
} |
| 609 |
(void) unlink(linktargetfile); |
657 |
(void) unlink(mtab_lock_targ); |
| 610 |
die (EX_FILEIO, _("can't open lock file %s: %s " |
658 |
die (EX_FILEIO, _("can't open lock file %s: %s " |
| 611 |
"(use -n flag to override)"), |
659 |
"(use -n flag to override)"), |
| 612 |
MOUNTED_LOCK, strerror (errsv)); |
660 |
mtab_lock_path, strerror (errsv)); |
| 613 |
} |
661 |
} |
| 614 |
|
662 |
|
| 615 |
flock.l_type = F_WRLCK; |
663 |
flock.l_type = F_WRLCK; |
|
Lines 623-633
Link Here
|
| 623 |
if (verbose) { |
671 |
if (verbose) { |
| 624 |
int errsv = errno; |
672 |
int errsv = errno; |
| 625 |
printf(_("Can't lock lock file %s: %s\n"), |
673 |
printf(_("Can't lock lock file %s: %s\n"), |
| 626 |
MOUNTED_LOCK, strerror (errsv)); |
674 |
mtab_lock_path, strerror (errsv)); |
| 627 |
} |
675 |
} |
| 628 |
/* proceed, since it was us who created the lockfile anyway */ |
676 |
/* proceed, since it was us who created the lockfile anyway */ |
| 629 |
} |
677 |
} |
| 630 |
(void) unlink(linktargetfile); |
678 |
(void) unlink(mtab_lock_targ); |
| 631 |
} else { |
679 |
} else { |
| 632 |
/* Someone else made the link. Wait. */ |
680 |
/* Someone else made the link. Wait. */ |
| 633 |
gettimeofday(&now, NULL); |
681 |
gettimeofday(&now, NULL); |
|
Lines 635-653
Link Here
|
| 635 |
alarm(maxtime.tv_sec - now.tv_sec); |
683 |
alarm(maxtime.tv_sec - now.tv_sec); |
| 636 |
if (fcntl (lockfile_fd, F_SETLKW, &flock) == -1) { |
684 |
if (fcntl (lockfile_fd, F_SETLKW, &flock) == -1) { |
| 637 |
int errsv = errno; |
685 |
int errsv = errno; |
| 638 |
(void) unlink(linktargetfile); |
686 |
(void) unlink(mtab_lock_targ); |
| 639 |
die (EX_FILEIO, _("can't lock lock file %s: %s"), |
687 |
die (EX_FILEIO, _("can't lock lock file %s: %s"), |
| 640 |
MOUNTED_LOCK, (errno == EINTR) ? |
688 |
mtab_lock_path, (errno == EINTR) ? |
| 641 |
_("timed out") : strerror (errsv)); |
689 |
_("timed out") : strerror (errsv)); |
| 642 |
} |
690 |
} |
| 643 |
alarm(0); |
691 |
alarm(0); |
| 644 |
|
692 |
|
| 645 |
nanosleep(&waittime, NULL); |
693 |
nanosleep(&waittime, NULL); |
| 646 |
} else { |
694 |
} else { |
| 647 |
(void) unlink(linktargetfile); |
695 |
(void) unlink(mtab_lock_targ); |
| 648 |
die (EX_FILEIO, _("Cannot create link %s\n" |
696 |
die (EX_FILEIO, _("Cannot create link %s\n" |
| 649 |
"Perhaps there is a stale lock file?\n"), |
697 |
"Perhaps there is a stale lock file?\n"), |
| 650 |
MOUNTED_LOCK); |
698 |
mtab_lock_path); |
| 651 |
} |
699 |
} |
| 652 |
close(lockfile_fd); |
700 |
close(lockfile_fd); |
| 653 |
} |
701 |
} |
|
Lines 667-682
Link Here
|
| 667 |
void |
715 |
void |
| 668 |
update_mtab (const char *dir, struct my_mntent *instead) { |
716 |
update_mtab (const char *dir, struct my_mntent *instead) { |
| 669 |
mntFILE *mfp, *mftmp; |
717 |
mntFILE *mfp, *mftmp; |
| 670 |
const char *fnam = MOUNTED; |
718 |
const char *fnam = mtab_path; |
| 671 |
struct mntentchn mtabhead; /* dummy */ |
719 |
struct mntentchn mtabhead; /* dummy */ |
| 672 |
struct mntentchn *mc, *mc0, *absent = NULL; |
720 |
struct mntentchn *mc, *mc0, *absent = NULL; |
| 673 |
|
721 |
|
| 674 |
if (mtab_does_not_exist() || !mtab_is_writable()) |
722 |
if (mtab_does_not_exist()) |
| 675 |
return; |
723 |
return; |
| 676 |
|
724 |
|
| 677 |
lock_mtab(); |
725 |
lock_mtab(); |
| 678 |
|
726 |
|
| 679 |
/* having locked mtab, read it again */ |
727 |
/* having gotten the lock, we read mtab again */ |
| 680 |
mc0 = mc = &mtabhead; |
728 |
mc0 = mc = &mtabhead; |
| 681 |
mc->nxt = mc->prev = NULL; |
729 |
mc->nxt = mc->prev = NULL; |
| 682 |
|
730 |
|
|
Lines 733-743
Link Here
|
| 733 |
} |
781 |
} |
| 734 |
|
782 |
|
| 735 |
/* write chain to mtemp */ |
783 |
/* write chain to mtemp */ |
| 736 |
mftmp = my_setmntent (MOUNTED_TEMP, "w"); |
784 |
mftmp = my_setmntent (mtab_temp_path, "w"); |
| 737 |
if (mftmp == NULL || mftmp->mntent_fp == NULL) { |
785 |
if (mftmp == NULL || mftmp->mntent_fp == NULL) { |
| 738 |
int errsv = errno; |
786 |
int errsv = errno; |
| 739 |
error (_("cannot open %s (%s) - mtab not updated"), |
787 |
error (_("cannot open %s (%s) - mtab not updated"), |
| 740 |
MOUNTED_TEMP, strerror (errsv)); |
788 |
mtab_temp_path, strerror (errsv)); |
| 741 |
discard_mntentchn(mc0); |
789 |
discard_mntentchn(mc0); |
| 742 |
goto leave; |
790 |
goto leave; |
| 743 |
} |
791 |
} |
|
Lines 746-752
Link Here
|
| 746 |
if (my_addmntent(mftmp, &(mc->m)) == 1) { |
794 |
if (my_addmntent(mftmp, &(mc->m)) == 1) { |
| 747 |
int errsv = errno; |
795 |
int errsv = errno; |
| 748 |
die (EX_FILEIO, _("error writing %s: %s"), |
796 |
die (EX_FILEIO, _("error writing %s: %s"), |
| 749 |
MOUNTED_TEMP, strerror (errsv)); |
797 |
mtab_temp_path, strerror (errsv)); |
| 750 |
} |
798 |
} |
| 751 |
} |
799 |
} |
| 752 |
|
800 |
|
|
Lines 756-780
Link Here
|
| 756 |
S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) { |
804 |
S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) { |
| 757 |
int errsv = errno; |
805 |
int errsv = errno; |
| 758 |
fprintf(stderr, _("error changing mode of %s: %s\n"), |
806 |
fprintf(stderr, _("error changing mode of %s: %s\n"), |
| 759 |
MOUNTED_TEMP, strerror (errsv)); |
807 |
mtab_temp_path, strerror (errsv)); |
| 760 |
} |
808 |
} |
| 761 |
my_endmntent (mftmp); |
809 |
my_endmntent (mftmp); |
| 762 |
|
810 |
|
| 763 |
{ /* |
811 |
{ /* |
| 764 |
* If mount is setuid and some non-root user mounts sth, |
812 |
* If mount is setuid and some non-root user mounts sth, |
| 765 |
* then mtab.tmp might get the group of this user. Copy uid/gid |
813 |
* then the temp file might get the group of this user. |
| 766 |
* from the present mtab before renaming. |
814 |
* Copy uid/gid from the present mtab before renaming. |
| 767 |
*/ |
815 |
*/ |
| 768 |
struct stat sbuf; |
816 |
struct stat sbuf; |
| 769 |
if (stat (MOUNTED, &sbuf) == 0) |
817 |
if (stat (mtab_path, &sbuf) == 0) |
| 770 |
chown (MOUNTED_TEMP, sbuf.st_uid, sbuf.st_gid); |
818 |
chown (mtab_temp_path, sbuf.st_uid, sbuf.st_gid); |
| 771 |
} |
819 |
} |
| 772 |
|
820 |
|
| 773 |
/* rename mtemp to mtab */ |
821 |
/* rename mtemp to mtab */ |
| 774 |
if (rename (MOUNTED_TEMP, MOUNTED) < 0) { |
822 |
if (rename (mtab_temp_path, mtab_path) < 0) { |
| 775 |
int errsv = errno; |
823 |
int errsv = errno; |
| 776 |
fprintf(stderr, _("can't rename %s to %s: %s\n"), |
824 |
fprintf(stderr, _("can't rename %s to %s: %s\n"), |
| 777 |
MOUNTED_TEMP, MOUNTED, strerror(errsv)); |
825 |
mtab_temp_path, mtab_path, strerror(errsv)); |
| 778 |
} |
826 |
} |
| 779 |
|
827 |
|
| 780 |
leave: |
828 |
leave: |