/* Tries to raise file lock Returns 1 on success, 0 on failure, -1 if abort Warning: Might do screen refresh and lose edit->force */ int edit_lock_file (char *fname) { char *lockfname, *newlock, *msg, *lock; struct stat statbuf; struct lock_s *lockinfo; /* Just to be sure (and don't lock new file) */ if (!fname || !*fname) return 0; /* Locking on VFS is not supported */ if (!vfs_file_is_local (fname)) return 0; /* Check if already locked */ lockfname = g_strconcat (".#", fname, NULL); if (lstat (lockfname, &statbuf) == 0) { lock = lock_get_info (lockfname); if (!lock) { g_free (lockfname); return 0; } lockinfo = lock_extract_info (lock); /* Check if locking process alive, ask user if required */ if (!lockinfo->pid || !(kill (lockinfo->pid, 0) == -1 && errno == ESRCH)) { msg = g_strdup_printf (_ ("File \"%s\" is already being edited\n" "User: %s\nProcess ID: %d"), fname, lockinfo->who, lockinfo->pid); /* TODO: Implement "Abort" - needs to rewind undo stack */ switch (edit_query_dialog2 (_("File locked"), msg, _("&Grab lock"), _("&Ignore lock"))) { case 0: break; case 1: case -1: g_free (lockfname); g_free (msg); return 0; } g_free (msg); } unlink (lockfname); } /* Create lock symlink */ newlock = lock_build_name (fname); if (symlink (newlock, lockfname) == -1) { g_free (lockfname); g_free (newlock); return 0; } g_free (lockfname); g_free (newlock); return 1; }
int lock_file (const vfs_path_t * fname_vpath) { char *lockfname = NULL, *newlock, *msg, *lock; struct stat statbuf; struct lock_s *lockinfo; gboolean is_local; gboolean symlink_ok = FALSE; const char *elpath; if (fname_vpath == NULL) return 0; elpath = vfs_path_get_by_index (fname_vpath, 0)->path; /* Just to be sure (and don't lock new file) */ if (*elpath == '\0') return 0; /* Locking on VFS is not supported */ is_local = vfs_file_is_local (fname_vpath); if (is_local) { /* Check if already locked */ lockfname = lock_build_symlink_name (fname_vpath); } if (!is_local || lockfname == NULL) return 0; if (lstat (lockfname, &statbuf) == 0) { lock = lock_get_info (lockfname); if (lock == NULL) goto ret; lockinfo = lock_extract_info (lock); /* Check if locking process alive, ask user if required */ if (lockinfo->pid == 0 || !(kill (lockinfo->pid, 0) == -1 && errno == ESRCH)) { msg = g_strdup_printf (_ ("File \"%s\" is already being edited.\n" "User: %s\nProcess ID: %d"), x_basename (lockfname) + 2, lockinfo->who, (int) lockinfo->pid); /* TODO: Implement "Abort" - needs to rewind undo stack */ switch (query_dialog (_("File locked"), msg, D_NORMAL, 2, _("&Grab lock"), _("&Ignore lock"))) { case 0: break; case 1: case -1: g_free (msg); goto ret; break; /* FIXME: unneeded? */ } g_free (msg); } unlink (lockfname); } /* Create lock symlink */ newlock = lock_build_name (); symlink_ok = (symlink (newlock, lockfname) != -1); g_free (newlock); ret: g_free (lockfname); return symlink_ok ? 1 : 0; }