+ Socket *s = SOCKET(n);
+ SocketPort *p;
+ int r;
+
+ assert(s);
+
+ if (s->state == SOCKET_START_PRE ||
+ s->state == SOCKET_START_POST)
+ return 0;
+
+ if (s->state == SOCKET_LISTENING ||
+ s->state == SOCKET_RUNNING)
+ return -EALREADY;
+
+ if (s->state == SOCKET_STOP_PRE ||
+ s->state == SOCKET_STOP_POST)
+ return -EAGAIN;
+
+ assert(s->state == SOCKET_DEAD || s->state == SOCKET_MAINTAINANCE);
+
+ LIST_FOREACH(p, s->ports) {
+
+ assert(p->fd < 0);
+
+ if (p->type == SOCKET_SOCKET) {
+
+ if ((r = socket_address_listen(&p->address, s->backlog, s->bind_ipv6_only, &p->fd)) < 0)
+ goto rollback;
+
+ } else {
+ struct stat st;
+ assert(p->type == SOCKET_FIFO);
+
+ if (mkfifo(p->path, 0666 & ~s->exec_context.umask) < 0 && errno != EEXIST) {
+ r = -errno;
+ goto rollback;
+ }
+
+ if ((p->fd = open(p->path, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW)) < 0) {
+ r = -errno;
+ goto rollback;
+ }
+
+ if (fstat(p->fd, &st) < 0) {
+ r = -errno;
+ goto rollback;
+ }
+
+ /* FIXME verify user, access mode */
+
+ if (!S_ISFIFO(st.st_mode)) {
+ r = -EEXIST;
+ goto rollback;
+ }
+ }
+ }
+
+ socket_set_state(s, SOCKET_LISTENING);
+