From owner-freebsd-hackers@FreeBSD.ORG Mon Nov 3 04:02:48 2014 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 7547D1EB; Mon, 3 Nov 2014 04:02:48 +0000 (UTC) Received: from ustc.edu.cn (email6.ustc.edu.cn [IPv6:2001:da8:d800::8]) by mx1.freebsd.org (Postfix) with ESMTP id 30737F78; Mon, 3 Nov 2014 04:02:46 +0000 (UTC) Received: from freebsd.my.domain (unknown [58.211.218.74]) by newmailweb.ustc.edu.cn (Coremail) with SMTP id LkAmygDXuRZV_lZUxd3FAA--.18577S2; Mon, 03 Nov 2014 12:02:39 +0800 (CST) From: Tiwei Bie To: mjg@freebsd.org Subject: [PATCH] Finish the task 'sysctl reporting current working directory' Date: Mon, 3 Nov 2014 12:02:05 +0800 Message-Id: <1414987325-23280-1-git-send-email-btw@mail.ustc.edu.cn> X-Mailer: git-send-email 2.1.0 X-CM-TRANSID: LkAmygDXuRZV_lZUxd3FAA--.18577S2 X-Coremail-Antispam: 1UD129KBjvJXoWxAFy3CF47GF15trWxCr45Wrg_yoWrZFykpa nxArnrtw47GF18Kr4kKr45u3WSkw18XF48WFWkuw43ZFsYqr10gr1Iqr90vF1S93y5W39I vF45tFyrGw10yFJanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUkFb7Iv0xC_Kw4lb4IE77IF4wAFF20E14v26r1j6r4UM7CY07I2 0VC2zVCF04k26cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28lY4IEw2IIxxk0rw A2F7IY1VAKz4vEj48ve4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_Ar0_tr1l84ACjcxK6xII jxv20xvEc7CjxVAFwI0_Cr0_Gr1UM28EF7xvwVC2z280aVAFwI0_GcCE3s1l84ACjcxK6I 8E87Iv6xkF7I0E14v26rxl6s0DM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI 64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v26r1Y6r17McIj6I8E87Iv67AKxVW8JVWxJw Am72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lc2xSY4AK67AK6r45MxAIw28I cxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2 IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUXVWUAwCIc40Y0x0EwIxGrwCI 42IY6xIIjxv20xvE14v26r1j6r1xMIIF0xvE2Ix0cI8IcVCY1x0267AKxVWUJVW8JwCI42 IY6xAIw20EY4v20xvaj40_WFyUJVCq3wCI42IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I8E 87Iv6xkF7I0E14v26r1j6r4UYxBIdaVFxhVjvjDU0xZFpf9x07b7a9-UUUUU= X-CM-SenderInfo: xewzqzxdloh3xvwfhvlgxou0/1tbiAQUQAVQhl8xmIgAKs1 Cc: freebsd-hackers@freebsd.org X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 03 Nov 2014 04:02:48 -0000 Hi, Mateusz! I have finished the task: sysctl reporting current working directory [1]. The patch for tmux is against tmux-1.9a [2]. #1. Patch for FreeBSD: diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 11ab4ba..4652cb9 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -3409,6 +3409,72 @@ static SYSCTL_NODE(_kern_proc, KERN_PROC_FILEDESC, filedesc, CTLFLAG_RD|CTLFLAG_MPSAFE, sysctl_kern_proc_filedesc, "Process filedesc entries"); +/* + * Store a process current working directory information to sbuf. + * + * Takes a locked proc as argument, and returns with the proc unlocked. + */ +int +kern_proc_cwd_out(struct proc *p, struct sbuf *sb, ssize_t maxlen) +{ + struct filedesc *fdp; + struct export_fd_buf *efbuf; + int error = 0; + + PROC_LOCK_ASSERT(p, MA_OWNED); + + fdp = fdhold(p); + PROC_UNLOCK(p); + + if (fdp == NULL) + return (error); + + efbuf = malloc(sizeof(*efbuf), M_TEMP, M_WAITOK); + efbuf->fdp = fdp; + efbuf->sb = sb; + efbuf->remainder = maxlen; + + FILEDESC_SLOCK(fdp); + /* working directory */ + if (fdp->fd_cdir != NULL) { + vref(fdp->fd_cdir); + export_vnode_to_sb(fdp->fd_cdir, KF_FD_TYPE_CWD, FREAD, efbuf); + } + FILEDESC_SUNLOCK(fdp); + fddrop(fdp); + free(efbuf, M_TEMP); + return (error); +} + +/* + * Get per-process current working directory. + */ +static int +sysctl_kern_proc_cwd(SYSCTL_HANDLER_ARGS) +{ + struct sbuf sb; + struct proc *p; + ssize_t maxlen; + int error, error2, *name; + + name = (int *)arg1; + + sbuf_new_for_sysctl(&sb, NULL, sizeof(struct kinfo_file), req); + error = pget((pid_t)name[0], PGET_CANDEBUG | PGET_NOTWEXIT, &p); + if (error != 0) { + sbuf_delete(&sb); + return (error); + } + maxlen = req->oldptr != NULL ? req->oldlen : -1; + error = kern_proc_cwd_out(p, &sb, maxlen); + error2 = sbuf_finish(&sb); + sbuf_delete(&sb); + return (error != 0 ? error : error2); +} + +static SYSCTL_NODE(_kern_proc, KERN_PROC_CWD, cwd, CTLFLAG_RD|CTLFLAG_MPSAFE, + sysctl_kern_proc_cwd, "Process current working directory"); + #ifdef DDB /* * For the purposes of debugging, generate a human-readable string for the diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h index d782375..f3173c2 100644 --- a/sys/sys/sysctl.h +++ b/sys/sys/sysctl.h @@ -657,6 +657,7 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry); #define KERN_PROC_UMASK 39 /* process umask */ #define KERN_PROC_OSREL 40 /* osreldate for process binary */ #define KERN_PROC_SIGTRAMP 41 /* signal trampoline location */ +#define KERN_PROC_CWD 42 /* process current working directory */ /* * KERN_IPC identifiers diff --git a/sys/sys/user.h b/sys/sys/user.h index f0d059e..c3b3bc5 100644 --- a/sys/sys/user.h +++ b/sys/sys/user.h @@ -530,6 +530,7 @@ struct sbuf; */ int kern_proc_filedesc_out(struct proc *p, struct sbuf *sb, ssize_t maxlen); +int kern_proc_cwd_out(struct proc *p, struct sbuf *sb, ssize_t maxlen); int kern_proc_out(struct proc *p, struct sbuf *sb, int flags); int kern_proc_vmmap_out(struct proc *p, struct sbuf *sb); -- 2.1.0 #2. Patch for tmux: diff --git a/osdep-freebsd.c b/osdep-freebsd.c index d596eab..f2443b7 100644 --- a/osdep-freebsd.c +++ b/osdep-freebsd.c @@ -136,26 +136,39 @@ char * osdep_get_cwd(int fd) { static char wd[PATH_MAX]; - struct kinfo_file *info = NULL; pid_t pgrp; - int nrecords, i; + int mib[4]; + size_t len; + struct kinfo_file *info; + char *buf; + int error; if ((pgrp = tcgetpgrp(fd)) == -1) return (NULL); - if ((info = kinfo_getfile(pgrp, &nrecords)) == NULL) + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_CWD; + mib[3] = pgrp; + + error = sysctl(mib, 4, NULL, &len, NULL, 0); + if (error) return (NULL); - for (i = 0; i < nrecords; i++) { - if (info[i].kf_fd == KF_FD_TYPE_CWD) { - strlcpy(wd, info[i].kf_path, sizeof wd); - free(info); - return (wd); - } + buf = malloc(len); + if (buf == NULL) + return (NULL); + error = sysctl(mib, 4, buf, &len, NULL, 0); + if (error) { + free(buf); + return (NULL); } - free(info); - return (NULL); + info = (struct kinfo_file *)buf; + strlcpy(wd, info->kf_path, sizeof wd); + + free(buf); + return (wd); } struct event_base * -- 2.1.0 [1] https://wiki.freebsd.org/JuniorJobs#sysctl_reporting_current_working_directory [2] http://cznic.dl.sourceforge.net/project/tmux/tmux/tmux-1.9/tmux-1.9a.tar.gz Tiwei Bie