aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2022-01-11 08:58:18 -0800
committerPaul Eggert2022-01-11 08:58:39 -0800
commita980795fd0bd2ae5fb0dba27fafbb811bc2ff75d (patch)
tree875f7b4859be26f4f5dd70655b2cba8c777cdcfe /src
parent68f2d772e51a0f436559bbfe26868eaca23af390 (diff)
downloademacs-a980795fd0bd2ae5fb0dba27fafbb811bc2ff75d.tar.gz
emacs-a980795fd0bd2ae5fb0dba27fafbb811bc2ff75d.zip
Clean up filelock code related to errno
Reduce dependency on Haiku internals, by not assuming that Haiku errno values (which are negative) are neither -1 nor -2. This removes an #ifdef HAIKU while still maintaining portability to Haiku. * src/filelock.c (NEGATIVE_ERRNO, ANOTHER_OWNS_IT, I_OWN_IT): New constants, which should work regardless of whether we are on Haiku or B_USE_POSITIVE_POSIX_ERRORS is defined. (current_lock_owner, lock_if_free, lock_file, unlock_file) (Ffile_locked_p): Use them, without assuming anything about errno value sign.
Diffstat (limited to 'src')
-rw-r--r--src/filelock.c69
1 files changed, 38 insertions, 31 deletions
diff --git a/src/filelock.c b/src/filelock.c
index 3555cfc2519..eb8d9ab5e01 100644
--- a/src/filelock.c
+++ b/src/filelock.c
@@ -490,15 +490,29 @@ read_lock_data (char *lfname, char lfinfo[MAX_LFINFO + 1])
490 return nbytes; 490 return nbytes;
491} 491}
492 492
493/* True if errno values are negative. Although the C standard
494 requires them to be positive, they are negative in Haiku. */
495enum { NEGATIVE_ERRNO = EDOM < 0 };
496
497/* Nonzero values that are not errno values. */
498enum
499 {
500 /* Another process on this machine owns it. */
501 ANOTHER_OWNS_IT = NEGATIVE_ERRNO ? 1 : -1,
502
503 /* This Emacs process owns it. */
504 I_OWN_IT = 2 * ANOTHER_OWNS_IT
505 };
506
493/* Return 0 if nobody owns the lock file LFNAME or the lock is obsolete, 507/* Return 0 if nobody owns the lock file LFNAME or the lock is obsolete,
494 -1 if another process owns it (and set OWNER (if non-null) to info), 508 ANOTHER_OWNS_IT if another process owns it
495 -2 if the current process owns it, 509 (and set OWNER (if non-null) to info),
510 I_OWN_IT if the current process owns it,
496 or an errno value if something is wrong with the locking mechanism. */ 511 or an errno value if something is wrong with the locking mechanism. */
497 512
498static int 513static int
499current_lock_owner (lock_info_type *owner, char *lfname) 514current_lock_owner (lock_info_type *owner, char *lfname)
500{ 515{
501 int ret;
502 lock_info_type local_owner; 516 lock_info_type local_owner;
503 ptrdiff_t lfinfolen; 517 ptrdiff_t lfinfolen;
504 intmax_t pid, boot_time; 518 intmax_t pid, boot_time;
@@ -571,13 +585,13 @@ current_lock_owner (lock_info_type *owner, char *lfname)
571 && memcmp (at + 1, SSDATA (system_name), SBYTES (system_name)) == 0) 585 && memcmp (at + 1, SSDATA (system_name), SBYTES (system_name)) == 0)
572 { 586 {
573 if (pid == getpid ()) 587 if (pid == getpid ())
574 ret = -2; /* We own it. */ 588 return I_OWN_IT;
575 else if (0 < pid && pid <= TYPE_MAXIMUM (pid_t) 589 else if (0 < pid && pid <= TYPE_MAXIMUM (pid_t)
576 && (kill (pid, 0) >= 0 || errno == EPERM) 590 && (kill (pid, 0) >= 0 || errno == EPERM)
577 && (boot_time == 0 591 && (boot_time == 0
578 || (boot_time <= TYPE_MAXIMUM (time_t) 592 || (boot_time <= TYPE_MAXIMUM (time_t)
579 && within_one_second (boot_time, get_boot_time ())))) 593 && within_one_second (boot_time, get_boot_time ()))))
580 ret = -1; /* An existing process on this machine owns it. */ 594 return ANOTHER_OWNS_IT;
581 /* The owner process is dead or has a strange pid, so try to 595 /* The owner process is dead or has a strange pid, so try to
582 zap the lockfile. */ 596 zap the lockfile. */
583 else 597 else
@@ -586,18 +600,16 @@ current_lock_owner (lock_info_type *owner, char *lfname)
586 else 600 else
587 { /* If we wanted to support the check for stale locks on remote machines, 601 { /* If we wanted to support the check for stale locks on remote machines,
588 here's where we'd do it. */ 602 here's where we'd do it. */
589 ret = -1; 603 return ANOTHER_OWNS_IT;
590 } 604 }
591
592 return ret;
593} 605}
594 606
595 607
596/* Lock the lock named LFNAME if possible. 608/* Lock the lock named LFNAME if possible.
597 Return 0 in that case. 609 Return 0 in that case.
598 Return negative if some other process owns the lock, and info about 610 Return ANOTHER_OWNS_IT if some other process owns the lock, and info about
599 that process in CLASHER. 611 that process in CLASHER.
600 Return positive errno value if cannot lock for any other reason. */ 612 Return errno value if cannot lock for any other reason. */
601 613
602static int 614static int
603lock_if_free (lock_info_type *clasher, char *lfname) 615lock_if_free (lock_info_type *clasher, char *lfname)
@@ -606,24 +618,17 @@ lock_if_free (lock_info_type *clasher, char *lfname)
606 while ((err = lock_file_1 (lfname, 0)) == EEXIST) 618 while ((err = lock_file_1 (lfname, 0)) == EEXIST)
607 { 619 {
608 err = current_lock_owner (clasher, lfname); 620 err = current_lock_owner (clasher, lfname);
621
622 /* Return if we locked it, or another process owns it, or it is
623 a strange error. */
609 if (err != 0) 624 if (err != 0)
610 { 625 return err == I_OWN_IT ? 0 : err;
611 if (err == -1 || err == -2)
612 return -2 - err; /* We locked it, or someone else has it. */
613 break; /* current_lock_owner returned strange error. */
614 }
615 626
616 /* We deleted a stale lock; try again to lock the file. */ 627 /* We deleted a stale lock or some other process deleted the lock;
628 try again to lock the file. */
617 } 629 }
618 630
619#if !defined HAIKU \
620 || defined B_USE_POSITIVE_POSIX_ERRORS
621 return err; 631 return err;
622#else
623 /* On Haiku, POSIX errno values are negative by default, but this
624 code's callers assume that all errno values are positive. */
625 return -err;
626#endif
627} 632}
628 633
629static Lisp_Object 634static Lisp_Object
@@ -681,12 +686,12 @@ lock_file (Lisp_Object fn)
681 if (!NILP (subject_buf) 686 if (!NILP (subject_buf)
682 && NILP (Fverify_visited_file_modtime (subject_buf)) 687 && NILP (Fverify_visited_file_modtime (subject_buf))
683 && !NILP (Ffile_exists_p (fn)) 688 && !NILP (Ffile_exists_p (fn))
684 && current_lock_owner (NULL, lfname) != -2) 689 && current_lock_owner (NULL, lfname) != I_OWN_IT)
685 call1 (intern ("userlock--ask-user-about-supersession-threat"), fn); 690 call1 (intern ("userlock--ask-user-about-supersession-threat"), fn);
686 691
687 /* Try to lock the lock. FIXME: This ignores errors when 692 /* Try to lock the lock. FIXME: This ignores errors when
688 lock_if_free returns a positive errno value. */ 693 lock_if_free returns an errno value. */
689 if (lock_if_free (&lock_info, lfname) < 0) 694 if (lock_if_free (&lock_info, lfname) == ANOTHER_OWNS_IT)
690 { 695 {
691 /* Someone else has the lock. Consider breaking it. */ 696 /* Someone else has the lock. Consider breaking it. */
692 Lisp_Object attack; 697 Lisp_Object attack;
@@ -717,9 +722,9 @@ unlock_file (Lisp_Object fn)
717 lfname = SSDATA (ENCODE_FILE (lock_filename)); 722 lfname = SSDATA (ENCODE_FILE (lock_filename));
718 723
719 int err = current_lock_owner (0, lfname); 724 int err = current_lock_owner (0, lfname);
720 if (err == -2 && unlink (lfname) != 0 && errno != ENOENT) 725 if (! (err == 0 || err == ANOTHER_OWNS_IT
721 err = errno; 726 || (err == I_OWN_IT
722 if (0 < err) 727 && (unlink (lfname) == 0 || (err = errno) == ENOENT))))
723 report_file_errno ("Unlocking file", fn, err); 728 report_file_errno ("Unlocking file", fn, err);
724 729
725 return Qnil; 730 return Qnil;
@@ -865,8 +870,10 @@ t if it is locked by you, else a string saying which user has locked it. */)
865 owner = current_lock_owner (&locker, lfname); 870 owner = current_lock_owner (&locker, lfname);
866 switch (owner) 871 switch (owner)
867 { 872 {
868 case -2: ret = Qt; break; 873 case I_OWN_IT: ret = Qt; break;
869 case -1: ret = make_string (locker.user, locker.at - locker.user); break; 874 case ANOTHER_OWNS_IT:
875 ret = make_string (locker.user, locker.at - locker.user);
876 break;
870 case 0: ret = Qnil; break; 877 case 0: ret = Qnil; break;
871 default: report_file_errno ("Testing file lock", filename, owner); 878 default: report_file_errno ("Testing file lock", filename, owner);
872 } 879 }