static int del_conn(struct iscsi_target *target, unsigned long ptr) { int err; struct iscsi_session *session; struct conn_info info; if ((err = copy_from_user(&info, (void *) ptr, sizeof(info))) < 0) return err; if (!(session = session_lookup(target, info.sid))) return -ENOENT; return conn_del(session, &info); }
static int send_to_one(conn_t *conn, const char *fmt, ...) { int ret; va_list ap; char buf[US_SOCK_BUF_LEN]; va_start(ap, fmt); vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); ret = write(conn->fd, buf, strlen(buf)); if ((ret < 1) || (ret != (int) strlen(buf))) { upsdebugx(2, "write to fd %d failed", conn->fd); close(conn->fd); conn_del(conn); return 0; /* failed */ } return 1; /* OK */ }
static void start_daemon(int lockfd) { int maxfd, pid, pipefd, ret; struct timeval tv; fd_set rfds; conn_t *tmp, *tmpnext; us_serialize(SERIALIZE_INIT); if ((pid = fork()) < 0) fatal_with_errno(EXIT_FAILURE, "Unable to enter background"); if (pid != 0) { /* parent */ /* wait for child to set up the listener */ us_serialize(SERIALIZE_WAIT); return; } /* child */ close(0); close(1); close(2); /* make fds 0-2 point somewhere defined */ if (open("/dev/null", O_RDWR) != 0) fatal_with_errno(EXIT_FAILURE, "open /dev/null"); if (dup(0) == -1) fatal_with_errno(EXIT_FAILURE, "dup"); if (dup(0) == -1) fatal_with_errno(EXIT_FAILURE, "dup"); pipefd = open_sock(); if (verbose) upslogx(LOG_INFO, "Timer daemon started"); /* release the parent */ us_serialize(SERIALIZE_SET); /* drop the lock now that the background is running */ unlink(lockfn); close(lockfd); /* now watch for activity */ for (;;) { /* wait at most 1s so we can check our timers regularly */ tv.tv_sec = 1; tv.tv_usec = 0; FD_ZERO(&rfds); FD_SET(pipefd, &rfds); maxfd = pipefd; for (tmp = connhead; tmp != NULL; tmp = tmp->next) { FD_SET(tmp->fd, &rfds); if (tmp->fd > maxfd) maxfd = tmp->fd; } ret = select(maxfd + 1, &rfds, NULL, NULL, &tv); if (ret > 0) { if (FD_ISSET(pipefd, &rfds)) conn_add(pipefd); tmp = connhead; while (tmp) { tmpnext = tmp->next; if (FD_ISSET(tmp->fd, &rfds)) { if (sock_read(tmp) < 0) { close(tmp->fd); conn_del(tmp); } } tmp = tmpnext; } } checktimers(); } }