aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/os/connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/os/connection.c')
-rw-r--r--xorg-server/os/connection.c68
1 files changed, 48 insertions, 20 deletions
diff --git a/xorg-server/os/connection.c b/xorg-server/os/connection.c
index 1099752e4..039942f91 100644
--- a/xorg-server/os/connection.c
+++ b/xorg-server/os/connection.c
@@ -142,6 +142,7 @@ Bool AnyClientsWriteBlocked; /* true if some client blocked on write */
static Bool RunFromSmartParent; /* send SIGUSR1 to parent process */
Bool RunFromSigStopParent; /* send SIGSTOP to our own process; Upstart (or
equivalent) will send SIGCONT back. */
+static char dynamic_display[7]; /* display name */
Bool PartialNetwork; /* continue even if unable to bind all addrs */
static Pid_t ParentProcess;
@@ -350,6 +351,10 @@ void
NotifyParentProcess(void)
{
#if !defined(WIN32)
+ if (dynamic_display[0]) {
+ write(displayfd, dynamic_display, strlen(dynamic_display));
+ close(displayfd);
+ }
if (RunFromSmartParent) {
if (ParentProcess > 1) {
kill(ParentProcess, SIGUSR1);
@@ -360,6 +365,18 @@ NotifyParentProcess(void)
#endif
}
+static Bool
+TryCreateSocket(int num, int *partial)
+{
+ char port[20];
+
+ snprintf(port, sizeof(port), "%d", num);
+
+ return (_XSERVTransMakeAllCOTSServerListeners(port, partial,
+ &ListenTransCount,
+ &ListenTransConns) >= 0);
+}
+
/*****************
* CreateWellKnownSockets
* At initialization, create the sockets to listen on for new clients.
@@ -370,7 +387,6 @@ CreateWellKnownSockets(void)
{
int i;
int partial;
- char port[20];
FD_ZERO(&AllSockets);
FD_ZERO(&AllClients);
@@ -386,29 +402,41 @@ CreateWellKnownSockets(void)
FD_ZERO(&WellKnownConnections);
- snprintf(port, sizeof(port), "%d", atoi(display));
-
- if ((_XSERVTransMakeAllCOTSServerListeners(port, &partial,
- &ListenTransCount,
- &ListenTransConns) >= 0) &&
- (ListenTransCount >= 1)) {
- if (!PartialNetwork && partial) {
- FatalError("Failed to establish all listening sockets");
+ /* display is initialized to "0" by main(). It is then set to the display
+ * number if specified on the command line, or to NULL when the -displayfd
+ * option is used. */
+ if (display) {
+ if (TryCreateSocket(atoi(display), &partial) &&
+ ListenTransCount >= 1)
+ if (!PartialNetwork && partial)
+ FatalError ("Failed to establish all listening sockets");
+ }
+ else { /* -displayfd */
+ Bool found = 0;
+ for (i = 0; i < 65535 - X_TCP_PORT; i++) {
+ if (TryCreateSocket(i, &partial) && !partial) {
+ found = 1;
+ break;
+ }
+ else
+ CloseWellKnownConnections();
}
- else {
- ListenTransFds = malloc(ListenTransCount * sizeof(int));
+ if (!found)
+ FatalError("Failed to find a socket to listen on");
+ snprintf(dynamic_display, sizeof(dynamic_display), "%d", i);
+ display = dynamic_display;
+ }
- for (i = 0; i < ListenTransCount; i++) {
- int fd = _XSERVTransGetConnectionNumber(ListenTransConns[i]);
+ ListenTransFds = malloc(ListenTransCount * sizeof (int));
- ListenTransFds[i] = fd;
- FD_SET(fd, &WellKnownConnections);
+ for (i = 0; i < ListenTransCount; i++) {
+ int fd = _XSERVTransGetConnectionNumber(ListenTransConns[i]);
- if (!_XSERVTransIsLocal(ListenTransConns[i])) {
- DefineSelf(fd);
- }
- }
- }
+ ListenTransFds[i] = fd;
+ FD_SET(fd, &WellKnownConnections);
+
+ if (!_XSERVTransIsLocal(ListenTransConns[i]))
+ DefineSelf (fd);
}
if (!XFD_ANYSET(&WellKnownConnections))