Created
May 1, 2013 19:02
-
-
Save jimblandy/5497508 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add support for Unix-domain sockets to nsIServerSocket.idl and @mozilla.org/network/server-socket;1. | |
diff --git a/netwerk/base/public/nsIServerSocket.idl b/netwerk/base/public/nsIServerSocket.idl | |
--- a/netwerk/base/public/nsIServerSocket.idl | |
+++ b/netwerk/base/public/nsIServerSocket.idl | |
@@ -95,6 +95,54 @@ interface nsIServerSocket : nsISupports | |
[noscript] void initWithAddress([const] in PRNetAddrPtr aAddr, in long aBackLog); | |
/** | |
+ * initWithFilename | |
+ * | |
+ * This method initializes a Unix-domain or "local" server socket. Such | |
+ * a socket has a name in the filesystem, like an ordinary file. To | |
+ * connect, a client supplies the socket's filename, and the usual | |
+ * permission checks on socket apply. | |
+ * | |
+ * This makes Unix-domain sockets useful for communication between the | |
+ * programs a specific user on a single machine: the operating system | |
+ * takes care of authentication, and the user's home directory or | |
+ * profile directory provide natural per-user rendezvous points. | |
+ * | |
+ * This call requires execute permission on all directories containing | |
+ * the one in which the socket is to be created, and write and execute | |
+ * permission on the directory itself. Otherwise, this returns | |
+ * NS_ERROR_FILE_ACCESS_DENIED. | |
+ * | |
+ * This call creates the socket's directory entry. There must not | |
+ * be any existing file, directory, or socket with the given name. If | |
+ * there is, this returns NS_ERROR_FILE_ALREADY_EXISTS. | |
+ * | |
+ * The directory in which the socket is to be created must already | |
+ * exist. Otherwise, this returns NS_ERROR_FILE_NOT_FOUND. | |
+ * | |
+ * The system-level socket API may impose restrictions on the length of | |
+ * the filename that are stricter than those of the underlying | |
+ * filesystem. If the file name is too long, this returns | |
+ * NS_ERROR_FILE_NAME_TOO_LONG. | |
+ * | |
+ * @param aPath nsIFile | |
+ * The file name at which the socket should be created. | |
+ * | |
+ * @param aPermissions unsigned long | |
+ * Unix-style permission bits to be applied to the new socket. | |
+ * | |
+ * Note about permissions: Linux's unix(7) man page claims that some | |
+ * BSD-derived systems ignore permissions on UNIX-domain sockets; | |
+ * NetBSD's bind(2) man page agrees, but says it does check now (dated | |
+ * 2005). POSIX has required 'connect' to fail if write permission on | |
+ * the socket itself is not granted since 2003 (Issue 6). NetBSD says | |
+ * that the permissions on the containing directory (execute) have | |
+ * always applied, so creating sockets in appropriately protected | |
+ * directories should be secure on both old and new systems. | |
+ */ | |
+ void initWithFilename(in nsIFile aPath, in unsigned long aPermissions, | |
+ in long aBacklog); | |
+ | |
+ /** | |
* close | |
* | |
* This method closes a server socket. This does not affect already | |
diff --git a/netwerk/base/src/nsServerSocket.cpp b/netwerk/base/src/nsServerSocket.cpp | |
--- a/netwerk/base/src/nsServerSocket.cpp | |
+++ b/netwerk/base/src/nsServerSocket.cpp | |
@@ -258,6 +258,26 @@ nsServerSocket::Init(int32_t aPort, bool | |
} | |
NS_IMETHODIMP | |
+nsServerSocket::InitWithFilename(nsIFile aPath, unsigned long aPermissions, int32_t aBacklog) | |
+{ | |
+ nsresult rv; | |
+ | |
+ nsAutoCString path; | |
+ rv = aPath->GetNativePath(aPath); | |
+ if (NS_FAILED(rv)) return rv; | |
+ | |
+ // Create a Unix-domain PRNetAddr referring to the given path. | |
+ PRNetAddr addr; | |
+ if (path.Length() + 1 > sizeof(addr.local.path)) | |
+ return NS_ERROR_FILE_NAME_TOO_LONG; | |
+ addr.local.family = AF_UNIX; | |
+ memcpy(addr.local.path, path.get(), path.Length()); | |
+ addr.local.path[path.Length()] = '\0'; | |
+ | |
+ return InitWithAddress(&addr, aBacklog); | |
+} | |
+ | |
+NS_IMETHODIMP | |
nsServerSocket::InitSpecialConnection(int32_t aPort, nsServerSocketFlag aFlags, | |
int32_t aBackLog) | |
{ | |
diff --git a/xpcom/io/nsIFile.idl b/xpcom/io/nsIFile.idl | |
--- a/xpcom/io/nsIFile.idl | |
+++ b/xpcom/io/nsIFile.idl | |
@@ -18,9 +18,21 @@ | |
interface nsISimpleEnumerator; | |
/** | |
- * This is the only correct cross-platform way to specify a file. | |
- * Strings are not such a way. If you grew up on windows or unix, you | |
- * may think they are. Welcome to reality. | |
+ * An nsIFile is an abstract representation of a filename. It manages | |
+ * filename encoding issues, pathname components separators ('/' vs. '\\' | |
+ * vs. ':') and weird stuff like differing volumes with identical names, as | |
+ * on pre-Darwin Macintoshes. | |
+ * | |
+ * This file has long introduced itself to new hackers with this opening | |
+ * paragraph: | |
+ * | |
+ * This is the only correct cross-platform way to specify a file. | |
+ * Strings are not such a way. If you grew up on windows or unix, you | |
+ * may think they are. Welcome to reality. | |
+ * | |
+ * While taking the attitude here at face value would be uncalled for, one | |
+ * may still safely conclude that writing cross-platform code is an | |
+ * embittering experience. | |
* | |
* All methods with string parameters have two forms. The preferred | |
* form operates on UCS-2 encoded characters strings. An alternate | |
@@ -28,7 +40,7 @@ interface nsISimpleEnumerator; | |
* | |
* A string containing characters encoded in the native charset cannot | |
* be safely passed to javascript via xpconnect. Therefore, the "native | |
- * methods" are not scriptable. | |
+ * methods" are not scriptable. | |
*/ | |
[scriptable, uuid(272a5020-64f5-485c-a8c4-44b2882ae0a2), builtinclass] | |
interface nsIFile : nsISupports |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment