From patchwork Mon Apr 4 02:30:53 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [6,of,7] chg: use relative path at connect From: Jun Wu X-Patchwork-Id: 14323 Message-Id: To: Date: Mon, 4 Apr 2016 03:30:53 +0100 # HG changeset patch # User Jun Wu # Date 1459736917 -3600 # Mon Apr 04 03:28:37 2016 +0100 # Node ID f7c6cfae4dba1c48a63bdea1b9aa816e7f634d02 # Parent f5414d2b4f32431a251029ebf46f48efdd9f013c chg: use relative path at connect We have made chgserver use relative path at bind(), now do the same change to the client at connect(). diff --git a/contrib/chg/hgclient.c b/contrib/chg/hgclient.c --- a/contrib/chg/hgclient.c +++ b/contrib/chg/hgclient.c @@ -424,12 +424,36 @@ if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) abortmsg("cannot set flags of socket (errno = %d)", errno); + /* use relative (shorter) path at connect() if possible. it is helpful + * because sizeof(addr.sun_path) can be very small (usually 108). */ + int bakwdfd = -1; + const char *lastsep = strrchr(sockname, '/'); + if (lastsep) { + bakwdfd = open(".", O_DIRECTORY); + size_t len = lastsep - sockname; + char dir[len + 1]; + memcpy(dir, sockname, len); + if (chdir(dir) != 0) + abortmsg("cannot chdir (errno = %d)", errno); + sockname = lastsep + 1; + } + struct sockaddr_un addr; addr.sun_family = AF_UNIX; + addr.sun_path[sizeof(addr.sun_path) - 1] = '\0'; strncpy(addr.sun_path, sockname, sizeof(addr.sun_path)); - addr.sun_path[sizeof(addr.sun_path) - 1] = '\0'; + if (addr.sun_path[sizeof(addr.sun_path) - 1] != '\0') + abortmsg("sockname %s is too long", sockname); int r = connect(fd, (struct sockaddr *)&addr, sizeof(addr)); + + /* restore workdir right after connect() */ + if (bakwdfd != -1) { + if (fchdir(bakwdfd) != 0) + abortmsg("cannot chdir back (errno = %d)", errno); + close(bakwdfd); + } + if (r < 0) { close(fd); if (errno == ENOENT || errno == ECONNREFUSED)