Emacs 客户端/服务器和 ClearCase 视图

发布于 2024-09-15 18:39:58 字数 2681 浏览 5 评论 0原文

所以我厌倦了等待 Emacs 每次重新加载,并查阅 Emacs Wiki,我给我写了一个调用脚本,例如:

#!/bin/bash
# @file: /usr/local/bin/emacs
# @version: 1

server=/tmp/emacs${UID}/server
if [ ! -S ${server} ] ; then
    /opt/emacs/bin/emacs --daemon
    until [ -S ${server} ] ; do
        sleep 1s
    done
fi

/opt/emacs/bin/emacsclient -c "$@"

立即,但是由于套接字过时而失败(由于不相关的原因,我的 emacs --daemon 意外被终止):所以我写道:

#!/bin/bash
# @file: /usr/local/bin/emacs
# @version: 2

server=/tmp/emacs${UID}/server

if ! /sbin/fuser ${server} 2> /dev/null ; then
    /sbin/funser -k ${server}
    rm -f ${server}
fi

if [ ! -S ${server} ] ; then
    /opt/emacs/bin/emacs --daemon
    until [ -S ${server} ] ; do
        sleep 1s
    done
fi

/opt/emacs/bin/emacsclient -c "$@"

这有效,但与 ClearCase 一起使用我注意到一个问题:

在 Unix 中,ClearCase 命令:

cleartool setview myview-myuser

创建一个子 shell,它具有修改后的文件系统层次结构:/vobs/ 下的几个新挂载使用 mvfs,并且仅对其可见壳。

对于每个这样的新 shell,我的 Emacs 调用脚本第一次运行时,命令 /sbin/fuser ${server} 返回 1(错误)。因此:

  • 对于版本 1:只有一个守护进程,但 Emacs 客户端无法看到 /vobs/ 下挂载的 mvfs。
  • 对于版本 2:有多个守护进程都使用相同的 ${server} 套接字。

因此,我的问题是:使用版本 2 可以吗?如果是,如果所有守护进程显然都使用相同的 ${server} 套接字,那么它如何工作?如果不是,我应该怎么做才能解决这个问题?


进展:

所以我得到了部分问题的答案(参见下面的答案),现在我陷入了困境 如何修复它?部分:

我正在考虑将 ${server} 放在 /vobs/ 下,从而让 ClearCase 本身解决我的问题问题。我只需要弄清楚 Emacs 是否以及如何让我这样做:

根据我的 /opt/emacs/share/emacs/23.2/lisp/server.elserver-socket- dir 植根于环境变量 ${TMPDIR} 的值,所以我尝试:

#!/bin/bash
# @file: /usr/local/bin/emacs
# @version: 3

[ "${CCVIEW}" ] && TMPDIR="/vbos/misc/tmp" || TMPDIR="/tmp"
export TMPDIR

function is_server_up() {
    local server=${TMPDIR}/emacs${UID}/server
    [ -e ${mysock} ] && /sbin/fuser ${server}
}

if ! is_server_up ; then
    /opt/emacs/bin/emacs --daemon
    until is_server_up ; do
        sleep 1s
        echo "DEBUG: sleeping"
    done
fi

/opt/emacs/bin/emacsclient -c "$@"

但是当从 ClearCase 视图运行时,我看到:

Loading ~/.emacs.d/this-module.el (source)...
Loading ~/.emacs.d/this-module.el (source)...done
Loading ~/.emacs.d/that-module.el (source)...
Loading ~/.emacs.d/that-module.el (source)...done
... snip ...
Starting Emacs daemon.
ESC [ A
 ESC
 ESC [
 ESC [ a
M-[ A is undefined

...并且它永远不会退出。

我还尝试修补 server.el 并使用不同的环境变量,但无济于事。

So I got tired of waiting for Emacs to load every time anew, and consulting Emacs Wiki, I wrote me an invocation script such as:

#!/bin/bash
# @file: /usr/local/bin/emacs
# @version: 1

server=/tmp/emacs${UID}/server
if [ ! -S ${server} ] ; then
    /opt/emacs/bin/emacs --daemon
    until [ -S ${server} ] ; do
        sleep 1s
    done
fi

/opt/emacs/bin/emacsclient -c "$@"

Immediately, however it failed due to a stale socket (for unrelated reasons my emacs --daemon was killed unexpectedly): So I wrote:

#!/bin/bash
# @file: /usr/local/bin/emacs
# @version: 2

server=/tmp/emacs${UID}/server

if ! /sbin/fuser ${server} 2> /dev/null ; then
    /sbin/funser -k ${server}
    rm -f ${server}
fi

if [ ! -S ${server} ] ; then
    /opt/emacs/bin/emacs --daemon
    until [ -S ${server} ] ; do
        sleep 1s
    done
fi

/opt/emacs/bin/emacsclient -c "$@"

This worked, but working with ClearCase views I noticed a wrinkle:

In a Unix the ClearCase command:

cleartool setview myview-myuser

creates a sub shell, that has a modified file system hierarchy: several new mounts under /vobs/ that are using mvfs, and visible only to that shell.

For each such new shell, the command /sbin/fuser ${server} returns 1 (error), the first time my Emacs invocation script runs. Thus:

  • For version 1: There is only one daemon, but the Emacs clients are unable to see the mvfs mounts under /vobs/.
  • For version 2: There are several daemons all using the same ${server} socket.

Thus, my questions are: Is it OK to use version 2? If yes, how can it work if all of the daemons apparently are using the same ${server} socket? If no, what should I do to fix this?


Progress:

So I got an answer (see answers below) to part of the question, and now I am stuck with
the how to fix it? part:

I am looking into putting the ${server} under /vobs/ and thus let ClearCase itself solve my problem. I only need to figure out if and how Emacs can let me do that:

According to my /opt/emacs/share/emacs/23.2/lisp/server.el the server-socket-dir is rooted at the value of the environment variable ${TMPDIR}, so I tried:

#!/bin/bash
# @file: /usr/local/bin/emacs
# @version: 3

[ "${CCVIEW}" ] && TMPDIR="/vbos/misc/tmp" || TMPDIR="/tmp"
export TMPDIR

function is_server_up() {
    local server=${TMPDIR}/emacs${UID}/server
    [ -e ${mysock} ] && /sbin/fuser ${server}
}

if ! is_server_up ; then
    /opt/emacs/bin/emacs --daemon
    until is_server_up ; do
        sleep 1s
        echo "DEBUG: sleeping"
    done
fi

/opt/emacs/bin/emacsclient -c "$@"

But when running form a ClearCase view, I see:

Loading ~/.emacs.d/this-module.el (source)...
Loading ~/.emacs.d/this-module.el (source)...done
Loading ~/.emacs.d/that-module.el (source)...
Loading ~/.emacs.d/that-module.el (source)...done
... snip ...
Starting Emacs daemon.
ESC [ A
 ESC
 ESC [
 ESC [ a
M-[ A is undefined

... and it never exits.

I also tried to patch server.el and use a different environment variable, but to no avail.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

少年亿悲伤 2024-09-22 18:39:58

只是一个注释,真的,但我会避免使用 setview

  • 正如您所注意到的,它创建了一个 shell(及其与守护进程通信方面的所有问题),
  • 它一次仅用于一个视图。使用 /vobs 路径时,您始终需要执行 cleartool pwv 来确保当前在哪个视图中工作。

我更喜欢使用动态视图的完整路径:

/view/myView/vobs/...

这样,就没有spawn shell,没有歧义,没有麻烦。

Just a note, really, but I would avoid using setview.

  • As you have noted, it creates a shell (with all its issues in term of communication with daemons)
  • Its is only for one view at a time. You always need to do a cleartool pwv to make sure in which view you are currently working when using the /vobs path.

I prefer using the full path of a dynamic view:

/view/myView/vobs/...

That way, no spawn shell, no disambiguation, no trouble.

末が日狂欢 2024-09-22 18:39:58

好吧,部分谜团已经解决:

不应该使用版本 2。它似乎有效,因为:

  1. /sbin/fuser -k ${server} 实际上并没有杀死服务器进程。也许 /sbin/fuser -k -SIGKILL ${server} 会,但我还没有尝试过。这也可能是由于 ClearCase 的视图魔法(用于内核级别的操作)。
  2. rm -f ${server} 取消文件链接,但不释放套接字,因为它仍被正在运行的进程使用。

因此,第一次运行调用脚本的最后一个视图将是 ${server} 套接字文件的所有者,并且 Emacs 的后续调用将使用该套接字,并将看到该视图的版本文件。

想象一下调试这个的乐趣……


至于如何修复它?部分,我会采取懦弱的方式,在 ClearCase 视图中恢复到独立的 Emacs:

#!/bin/bash
# @file: /usr/local/bin/emacs
# @version: 4

if [ "${CCVIEW}" ] ; then
    /opt/emacs/bin/emacs $@
    exit $?
fi

function is_server_up() {
    local server=/tmp/emacs${UID}/server
    [ -e ${mysock} ] && /sbin/fuser ${server}
}

if ! is_server_up ; then
    /opt/emacs/bin/emacs --daemon
    until is_server_up ; do
        sleep 1s
    done
fi

/opt/emacs/bin/emacsclient -c "$@"

OK, part of the mystery is solved:

Version 2 should not be used. It seems to work because:

  1. /sbin/fuser -k ${server} does not actually kill the server process. Perhaps /sbin/fuser -k -SIGKILL ${server} will, but I haven't tried that. It also can be due to ClearCase's view magic (used by manipulation at the kernel level).
  2. rm -f ${server} unlinks the file, but don't release the socket because it is still used by running processes.

Thus the last view to run the invocation script for the first time will be the owner of the ${server} socket file, and subsequent invocations of Emacs will use that socket, and will see the version files of that view.

Just imagine the hours of fun debugging this...


As for the how to fix it? part, I will take the cowardly way out, and just revert to stand alone Emacs in ClearCase views:

#!/bin/bash
# @file: /usr/local/bin/emacs
# @version: 4

if [ "${CCVIEW}" ] ; then
    /opt/emacs/bin/emacs $@
    exit $?
fi

function is_server_up() {
    local server=/tmp/emacs${UID}/server
    [ -e ${mysock} ] && /sbin/fuser ${server}
}

if ! is_server_up ; then
    /opt/emacs/bin/emacs --daemon
    until is_server_up ; do
        sleep 1s
    done
fi

/opt/emacs/bin/emacsclient -c "$@"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文