[PATCH 02 of 14] chg: add connectat as a utility function
Jun Wu
quark at fb.com
Sun Apr 10 19:57:19 EDT 2016
# HG changeset patch
# User Jun Wu <quark at fb.com>
# Date 1460322456 -3600
# Sun Apr 10 22:07:36 2016 +0100
# Node ID 97fbb23cf84c03ce59325e9de94902f40c68c8c8
# Parent cecc773636dcaeaf6d5130831f400a77fb065a96
chg: add connectat as a utility function
We are going to use connectat and some platforms (namely FreeBSD) has it own
native implementation. The signature is the same with FreeBSD's so we can
switch to its native implementation easily with C macro later.
Note: Sadly, connectat() is broken on FreeBSD now, as tested with FreeBSD
10.3-RELEASE (r297264) amd64. It will error out with ENOTCAPABLE.
Using ktrace and kdump, I got:
2928 chg CALL connectat(0x3,0x4,0x7fffffffd7d8,0x6a)
2928 chg STRU struct sockaddr { AF_LOCAL, server }
2928 chg NAMI "server"
2928 chg CAP operation requires <CAP_LOOKUP>,
process holds <CAP_READ,CAP_WRITE,...,CAP_LOOKUP,...>
2928 chg RET connectat -1 errno 93 Capabilities insufficient
It looks like a bug in the capsicum framework. Let's just stick to our own
implementation for now.
diff --git a/contrib/chg/util.c b/contrib/chg/util.c
--- a/contrib/chg/util.c
+++ b/contrib/chg/util.c
@@ -8,6 +8,7 @@
*/
#include <errno.h>
+#include <fcntl.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
@@ -178,3 +179,18 @@
return -WTERMSIG(status);
return 127;
}
+
+int connectat(int fd, int s, const struct sockaddr *addr, socklen_t addrlen)
+{
+ if (fd == AT_FDCWD)
+ return connect(s, addr, addrlen);
+ int cwdfd = open(".", O_DIRECTORY);
+ if (cwdfd == -1)
+ abortmsgerrno("cannot open cwd");
+ fchdirx(fd);
+ int r = connect(s, addr, addrlen);
+ fchdirx(cwdfd);
+ close(cwdfd);
+ return r;
+}
+
diff --git a/contrib/chg/util.h b/contrib/chg/util.h
--- a/contrib/chg/util.h
+++ b/contrib/chg/util.h
@@ -10,6 +10,8 @@
#ifndef UTIL_H_
#define UTIL_H_
+#include <sys/socket.h>
+
#ifdef __GNUC__
#define PRINTF_FORMAT_ __attribute__((format(printf, 1, 2)))
#else
@@ -29,4 +31,6 @@
int runshellcmd(const char *cmd, const char *envp[], const char *cwd);
+int connectat(int fd, int s, const struct sockaddr *name, socklen_t namelen);
+
#endif /* UTIL_H_ */
More information about the Mercurial-devel
mailing list