diff options
| author | Paul Eggert | 2016-10-12 09:01:03 -0700 |
|---|---|---|
| committer | Paul Eggert | 2016-10-12 09:19:44 -0700 |
| commit | 40c426a150c5d885d8a2509358831c9bb1e1c6ad (patch) | |
| tree | 36838cfcc85c5926098c34301a5bb6db98fdef5e /src/filelock.c | |
| parent | 2deb20c1bdef2940629dc2c586d9176b9ea7e203 (diff) | |
| download | emacs-40c426a150c5d885d8a2509358831c9bb1e1c6ad.tar.gz emacs-40c426a150c5d885d8a2509358831c9bb1e1c6ad.zip | |
Work around Samba bug with ':' in symlink contents
* src/filelock.c (current_lock_owner): When reading the contents
of a lock, treat the UTF-8 for U+F022 as if it were ':' (Bug#24656).
Backport from master.
Diffstat (limited to 'src/filelock.c')
| -rw-r--r-- | src/filelock.c | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/src/filelock.c b/src/filelock.c index 8aaa656438d..23bb4b83bd5 100644 --- a/src/filelock.c +++ b/src/filelock.c | |||
| @@ -71,8 +71,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 71 | 71 | ||
| 72 | /* Normally use a symbolic link to represent a lock. | 72 | /* Normally use a symbolic link to represent a lock. |
| 73 | The strategy: to lock a file FN, create a symlink .#FN in FN's | 73 | The strategy: to lock a file FN, create a symlink .#FN in FN's |
| 74 | directory, with link data `user@host.pid'. This avoids a single | 74 | directory, with link data USER@HOST.PID:BOOT. This avoids a single |
| 75 | mount (== failure) point for lock files. | 75 | mount (== failure) point for lock files. The :BOOT is omitted if |
| 76 | the boot time is not available. | ||
| 76 | 77 | ||
| 77 | When the host in the lock data is the current host, we can check if | 78 | When the host in the lock data is the current host, we can check if |
| 78 | the pid is valid with kill. | 79 | the pid is valid with kill. |
| @@ -101,13 +102,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 101 | 102 | ||
| 102 | This is compatible with the locking scheme used by Interleaf (which | 103 | This is compatible with the locking scheme used by Interleaf (which |
| 103 | has contributed this implementation for Emacs), and was designed by | 104 | has contributed this implementation for Emacs), and was designed by |
| 104 | Ethan Jacobson, Kimbo Mundy, and others. | 105 | Karl Berry, Ethan Jacobson, Kimbo Mundy, and others. |
| 105 | |||
| 106 | --karl@cs.umb.edu/karl@hq.ileaf.com. | ||
| 107 | 106 | ||
| 108 | On some file systems, notably those of MS-Windows, symbolic links | 107 | On some file systems, notably those of MS-Windows, symbolic links |
| 109 | do not work well, so instead of a symlink .#FN -> 'user@host.pid', | 108 | do not work well, so instead of a symlink .#FN -> USER@HOST.PID:BOOT, |
| 110 | the lock is a regular file .#FN with contents 'user@host.pid'. To | 109 | the lock is a regular file .#FN with contents USER@HOST.PID:BOOT. To |
| 111 | establish a lock, a nonce file is created and then renamed to .#FN. | 110 | establish a lock, a nonce file is created and then renamed to .#FN. |
| 112 | On MS-Windows this renaming is atomic unless the lock is forcibly | 111 | On MS-Windows this renaming is atomic unless the lock is forcibly |
| 113 | acquired. On other systems the renaming is atomic if the lock is | 112 | acquired. On other systems the renaming is atomic if the lock is |
| @@ -298,8 +297,8 @@ enum { MAX_LFINFO = 8 * 1024 }; | |||
| 298 | 297 | ||
| 299 | typedef struct | 298 | typedef struct |
| 300 | { | 299 | { |
| 301 | /* Location of '@', '.', ':' in USER. If there's no colon, COLON | 300 | /* Location of '@', '.', and ':' (or equivalent) in USER. If there's |
| 302 | points to the end of USER. */ | 301 | no colon or equivalent, COLON points to the end of USER. */ |
| 303 | char *at, *dot, *colon; | 302 | char *at, *dot, *colon; |
| 304 | 303 | ||
| 305 | /* Lock file contents USER@HOST.PID with an optional :BOOT_TIME | 304 | /* Lock file contents USER@HOST.PID with an optional :BOOT_TIME |
| @@ -557,7 +556,7 @@ current_lock_owner (lock_info_type *owner, char *lfname) | |||
| 557 | if (!dot) | 556 | if (!dot) |
| 558 | return -1; | 557 | return -1; |
| 559 | 558 | ||
| 560 | /* The PID is everything from the last `.' to the `:'. */ | 559 | /* The PID is everything from the last '.' to the ':' or equivalent. */ |
| 561 | if (! c_isdigit (dot[1])) | 560 | if (! c_isdigit (dot[1])) |
| 562 | return -1; | 561 | return -1; |
| 563 | errno = 0; | 562 | errno = 0; |
| @@ -565,7 +564,8 @@ current_lock_owner (lock_info_type *owner, char *lfname) | |||
| 565 | if (errno == ERANGE) | 564 | if (errno == ERANGE) |
| 566 | pid = -1; | 565 | pid = -1; |
| 567 | 566 | ||
| 568 | /* After the `:', if there is one, comes the boot time. */ | 567 | /* After the ':' or equivalent, if there is one, comes the boot time. */ |
| 568 | char *boot = owner->colon + 1; | ||
| 569 | switch (owner->colon[0]) | 569 | switch (owner->colon[0]) |
| 570 | { | 570 | { |
| 571 | case 0: | 571 | case 0: |
| @@ -573,10 +573,19 @@ current_lock_owner (lock_info_type *owner, char *lfname) | |||
| 573 | lfinfo_end = owner->colon; | 573 | lfinfo_end = owner->colon; |
| 574 | break; | 574 | break; |
| 575 | 575 | ||
| 576 | case '\357': | ||
| 577 | /* Treat "\357\200\242" (U+F022 in UTF-8) as if it were ":". | ||
| 578 | This works around a bug in Samba, which can mistakenly | ||
| 579 | transliterate ':' to U+F022 in symlink contents (Bug#24656). | ||
| 580 | See <https://bugzilla.redhat.com/show_bug.cgi?id=1271407#c8>. */ | ||
| 581 | if (! (boot[0] == '\200' && boot[1] == '\242')) | ||
| 582 | return -1; | ||
| 583 | boot += 2; | ||
| 584 | /* Fall through. */ | ||
| 576 | case ':': | 585 | case ':': |
| 577 | if (! c_isdigit (owner->colon[1])) | 586 | if (! c_isdigit (boot[0])) |
| 578 | return -1; | 587 | return -1; |
| 579 | boot_time = strtoimax (owner->colon + 1, &lfinfo_end, 10); | 588 | boot_time = strtoimax (boot, &lfinfo_end, 10); |
| 580 | break; | 589 | break; |
| 581 | 590 | ||
| 582 | default: | 591 | default: |