1/* 2 * Copyright (c) 2005, Junio C Hamano 3 */ 4#include"cache.h" 5#include"sigchain.h" 6 7static struct lock_file *lock_file_list; 8 9static voidremove_lock_file(void) 10{ 11 pid_t me =getpid(); 12 13while(lock_file_list) { 14if(lock_file_list->owner == me && 15 lock_file_list->filename[0]) { 16if(lock_file_list->fd >=0) 17close(lock_file_list->fd); 18unlink_or_warn(lock_file_list->filename); 19} 20 lock_file_list = lock_file_list->next; 21} 22} 23 24static voidremove_lock_file_on_signal(int signo) 25{ 26remove_lock_file(); 27sigchain_pop(signo); 28raise(signo); 29} 30 31/* 32 * p = absolute or relative path name 33 * 34 * Return a pointer into p showing the beginning of the last path name 35 * element. If p is empty or the root directory ("/"), just return p. 36 */ 37static char*last_path_elm(char*p) 38{ 39/* r starts pointing to null at the end of the string */ 40char*r =strchr(p,'\0'); 41 42if(r == p) 43return p;/* just return empty string */ 44 45 r--;/* back up to last non-null character */ 46 47/* back up past trailing slashes, if any */ 48while(r > p && *r =='/') 49 r--; 50 51/* 52 * then go backwards until I hit a slash, or the beginning of 53 * the string 54 */ 55while(r > p && *(r-1) !='/') 56 r--; 57return r; 58} 59 60 61/* We allow "recursive" symbolic links. Only within reason, though */ 62#define MAXDEPTH 5 63 64/* 65 * p = path that may be a symlink 66 * s = full size of p 67 * 68 * If p is a symlink, attempt to overwrite p with a path to the real 69 * file or directory (which may or may not exist), following a chain of 70 * symlinks if necessary. Otherwise, leave p unmodified. 71 * 72 * This is a best-effort routine. If an error occurs, p will either be 73 * left unmodified or will name a different symlink in a symlink chain 74 * that started with p's initial contents. 75 * 76 * Always returns p. 77 */ 78 79static char*resolve_symlink(char*p,size_t s) 80{ 81int depth = MAXDEPTH; 82 83while(depth--) { 84char link[PATH_MAX]; 85int link_len =readlink(p, link,sizeof(link)); 86if(link_len <0) { 87/* not a symlink anymore */ 88return p; 89} 90else if(link_len <sizeof(link)) 91/* readlink() never null-terminates */ 92 link[link_len] ='\0'; 93else{ 94warning("%s: symlink too long", p); 95return p; 96} 97 98if(is_absolute_path(link)) { 99/* absolute path simply replaces p */ 100if(link_len < s) 101strcpy(p, link); 102else{ 103warning("%s: symlink too long", p); 104return p; 105} 106}else{ 107/* 108 * link is a relative path, so I must replace the 109 * last element of p with it. 110 */ 111char*r = (char*)last_path_elm(p); 112if(r - p + link_len < s) 113strcpy(r, link); 114else{ 115warning("%s: symlink too long", p); 116return p; 117} 118} 119} 120return p; 121} 122 123/* Make sure errno contains a meaningful value on error */ 124static intlock_file(struct lock_file *lk,const char*path,int flags) 125{ 126/* 127 * subtract 5 from size to make sure there's room for adding 128 * ".lock" for the lock file name 129 */ 130static const size_t max_path_len =sizeof(lk->filename) -5; 131 132if(strlen(path) >= max_path_len) { 133 errno = ENAMETOOLONG; 134return-1; 135} 136strcpy(lk->filename, path); 137if(!(flags & LOCK_NODEREF)) 138resolve_symlink(lk->filename, max_path_len); 139strcat(lk->filename,".lock"); 140 lk->fd =open(lk->filename, O_RDWR | O_CREAT | O_EXCL,0666); 141if(0<= lk->fd) { 142if(!lock_file_list) { 143sigchain_push_common(remove_lock_file_on_signal); 144atexit(remove_lock_file); 145} 146 lk->owner =getpid(); 147if(!lk->on_list) { 148 lk->next = lock_file_list; 149 lock_file_list = lk; 150 lk->on_list =1; 151} 152if(adjust_shared_perm(lk->filename)) { 153int save_errno = errno; 154error("cannot fix permission bits on%s", 155 lk->filename); 156 errno = save_errno; 157return-1; 158} 159} 160else 161 lk->filename[0] =0; 162return lk->fd; 163} 164 165voidunable_to_lock_message(const char*path,int err,struct strbuf *buf) 166{ 167if(err == EEXIST) { 168strbuf_addf(buf,"Unable to create '%s.lock':%s.\n\n" 169"If no other git process is currently running, this probably means a\n" 170"git process crashed in this repository earlier. Make sure no other git\n" 171"process is running and remove the file manually to continue.", 172absolute_path(path),strerror(err)); 173}else 174strbuf_addf(buf,"Unable to create '%s.lock':%s", 175absolute_path(path),strerror(err)); 176} 177 178intunable_to_lock_error(const char*path,int err) 179{ 180struct strbuf buf = STRBUF_INIT; 181 182unable_to_lock_message(path, err, &buf); 183error("%s", buf.buf); 184strbuf_release(&buf); 185return-1; 186} 187 188NORETURN voidunable_to_lock_index_die(const char*path,int err) 189{ 190struct strbuf buf = STRBUF_INIT; 191 192unable_to_lock_message(path, err, &buf); 193die("%s", buf.buf); 194} 195 196/* This should return a meaningful errno on failure */ 197inthold_lock_file_for_update(struct lock_file *lk,const char*path,int flags) 198{ 199int fd =lock_file(lk, path, flags); 200if(fd <0&& (flags & LOCK_DIE_ON_ERROR)) 201unable_to_lock_index_die(path, errno); 202return fd; 203} 204 205inthold_lock_file_for_append(struct lock_file *lk,const char*path,int flags) 206{ 207int fd, orig_fd; 208 209 fd =lock_file(lk, path, flags); 210if(fd <0) { 211if(flags & LOCK_DIE_ON_ERROR) 212unable_to_lock_index_die(path, errno); 213return fd; 214} 215 216 orig_fd =open(path, O_RDONLY); 217if(orig_fd <0) { 218if(errno != ENOENT) { 219if(flags & LOCK_DIE_ON_ERROR) 220die("cannot open '%s' for copying", path); 221close(fd); 222returnerror("cannot open '%s' for copying", path); 223} 224}else if(copy_fd(orig_fd, fd)) { 225if(flags & LOCK_DIE_ON_ERROR) 226exit(128); 227close(orig_fd); 228close(fd); 229return-1; 230}else{ 231close(orig_fd); 232} 233return fd; 234} 235 236intclose_lock_file(struct lock_file *lk) 237{ 238int fd = lk->fd; 239 lk->fd = -1; 240returnclose(fd); 241} 242 243intreopen_lock_file(struct lock_file *lk) 244{ 245if(0<= lk->fd) 246die(_("BUG: reopen a lockfile that is still open")); 247if(!lk->filename[0]) 248die(_("BUG: reopen a lockfile that has been committed")); 249 lk->fd =open(lk->filename, O_WRONLY); 250return lk->fd; 251} 252 253intcommit_lock_file(struct lock_file *lk) 254{ 255char result_file[PATH_MAX]; 256size_t i; 257if(lk->fd >=0&&close_lock_file(lk)) 258return-1; 259strcpy(result_file, lk->filename); 260 i =strlen(result_file) -5;/* .lock */ 261 result_file[i] =0; 262if(rename(lk->filename, result_file)) 263return-1; 264 lk->filename[0] =0; 265return0; 266} 267 268inthold_locked_index(struct lock_file *lk,int die_on_error) 269{ 270returnhold_lock_file_for_update(lk,get_index_file(), 271 die_on_error 272? LOCK_DIE_ON_ERROR 273:0); 274} 275 276voidrollback_lock_file(struct lock_file *lk) 277{ 278if(lk->filename[0]) { 279if(lk->fd >=0) 280close(lk->fd); 281unlink_or_warn(lk->filename); 282} 283 lk->filename[0] =0; 284}