PageRenderTime 50ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/minix/servers/vfs/select.c

http://www.minix3.org/
C | 1166 lines | 686 code | 158 blank | 322 comment | 265 complexity | 9eba3bff4f4228ea80704d5abb8f571c MD5 | raw file
Possible License(s): MIT, WTFPL, AGPL-1.0, BSD-3-Clause, GPL-3.0, LGPL-2.0, JSON, 0BSD
  1. /* Implement entry point to select system call.
  2. *
  3. * The entry points into this file are
  4. * do_select: perform the SELECT system call
  5. * select_callback: notify select system of possible fd operation
  6. * select_unsuspend_by_endpt: cancel a blocking select on exiting driver
  7. *
  8. * The select code uses minimal locking, so that the replies from character
  9. * drivers can be processed without blocking. Filps are locked only for pipes.
  10. * We make the assumption that any other structures and fields are safe to
  11. * check (and possibly change) as long as we know that a process is blocked on
  12. * a select(2) call, meaning that all involved filps are guaranteed to stay
  13. * open until either we finish the select call, it the process gets interrupted
  14. * by a signal.
  15. */
  16. #include "fs.h"
  17. #include <sys/fcntl.h>
  18. #include <sys/time.h>
  19. #include <sys/select.h>
  20. #include <sys/stat.h>
  21. #include <minix/callnr.h>
  22. #include <minix/u64.h>
  23. #include <string.h>
  24. #include <assert.h>
  25. #include "file.h"
  26. #include "vnode.h"
  27. /* max. number of simultaneously pending select() calls */
  28. #define MAXSELECTS 25
  29. #define FROM_PROC 0
  30. #define TO_PROC 1
  31. #define USECPERSEC 1000000 /* number of microseconds in a second */
  32. typedef fd_set *ixfer_fd_set_ptr;
  33. static struct selectentry {
  34. struct fproc *requestor; /* slot is free iff this is NULL */
  35. endpoint_t req_endpt;
  36. fd_set readfds, writefds, errorfds;
  37. fd_set ready_readfds, ready_writefds, ready_errorfds;
  38. ixfer_fd_set_ptr vir_readfds, vir_writefds, vir_errorfds;
  39. struct filp *filps[OPEN_MAX];
  40. int type[OPEN_MAX];
  41. int nfds, nreadyfds;
  42. int error;
  43. char block;
  44. char starting;
  45. clock_t expiry;
  46. minix_timer_t timer; /* if expiry > 0 */
  47. } selecttab[MAXSELECTS];
  48. static int copy_fdsets(struct selectentry *se, int nfds, int direction);
  49. static void filp_status(struct filp *fp, int status);
  50. static int is_deferred(struct selectentry *se);
  51. static void restart_proc(struct selectentry *se);
  52. static void ops2tab(int ops, int fd, struct selectentry *e);
  53. static int is_regular_file(struct filp *f);
  54. static int is_pipe(struct filp *f);
  55. static int is_char_device(struct filp *f);
  56. static void select_lock_filp(struct filp *f, int ops);
  57. static int select_request_file(struct filp *f, int *ops, int block,
  58. struct fproc *rfp);
  59. static int select_request_char(struct filp *f, int *ops, int block,
  60. struct fproc *rfp);
  61. static int select_request_pipe(struct filp *f, int *ops, int block,
  62. struct fproc *rfp);
  63. static void select_cancel_all(struct selectentry *e);
  64. static void select_cancel_filp(struct filp *f);
  65. static void select_return(struct selectentry *);
  66. static void select_restart_filps(void);
  67. static int tab2ops(int fd, struct selectentry *e);
  68. static void wipe_select(struct selectentry *s);
  69. void select_timeout_check(int s);
  70. static struct fdtype {
  71. int (*select_request)(struct filp *, int *ops, int block,
  72. struct fproc *rfp);
  73. int (*type_match)(struct filp *f);
  74. } fdtypes[] = {
  75. { select_request_char, is_char_device },
  76. { select_request_file, is_regular_file },
  77. { select_request_pipe, is_pipe },
  78. };
  79. #define SEL_FDS (sizeof(fdtypes) / sizeof(fdtypes[0]))
  80. /*===========================================================================*
  81. * do_select *
  82. *===========================================================================*/
  83. int do_select(void)
  84. {
  85. /* Implement the select(nfds, readfds, writefds, errorfds, timeout) system
  86. * call. First we copy the arguments and verify their sanity. Then we check
  87. * whether there are file descriptors that satisfy the select call right off
  88. * the bat. If so, or if there are no ready file descriptors but the process
  89. * requested to return immediately, we return the result. Otherwise we set a
  90. * timeout and wait for either the file descriptors to become ready or the
  91. * timer to go off. If no timeout value was provided, we wait indefinitely.
  92. */
  93. int r, nfds, do_timeout, fd, s;
  94. struct filp *f;
  95. unsigned int type, ops;
  96. struct timeval timeout;
  97. struct selectentry *se;
  98. vir_bytes vtimeout;
  99. clock_t ticks;
  100. nfds = job_m_in.m_lc_vfs_select.nfds;
  101. vtimeout = job_m_in.m_lc_vfs_select.timeout;
  102. /* Sane amount of file descriptors? */
  103. if (nfds < 0 || nfds > OPEN_MAX) return(EINVAL);
  104. /* Find a slot to store this select request */
  105. for (s = 0; s < MAXSELECTS; s++)
  106. if (selecttab[s].requestor == NULL) /* Unused slot */
  107. break;
  108. if (s >= MAXSELECTS) return(ENOSPC);
  109. se = &selecttab[s];
  110. wipe_select(se); /* Clear results of previous usage */
  111. se->requestor = fp;
  112. se->req_endpt = who_e;
  113. se->vir_readfds = job_m_in.m_lc_vfs_select.readfds;
  114. se->vir_writefds = job_m_in.m_lc_vfs_select.writefds;
  115. se->vir_errorfds = job_m_in.m_lc_vfs_select.errorfds;
  116. /* Copy fdsets from the process */
  117. if ((r = copy_fdsets(se, nfds, FROM_PROC)) != OK) {
  118. se->requestor = NULL;
  119. return(r);
  120. }
  121. /* Did the process set a timeout value? If so, retrieve it. */
  122. if (vtimeout != 0) {
  123. r = sys_datacopy_wrapper(who_e, vtimeout, SELF, (vir_bytes) &timeout,
  124. sizeof(timeout));
  125. /* No nonsense in the timeval */
  126. if (r == OK && (timeout.tv_sec < 0 || timeout.tv_usec < 0 ||
  127. timeout.tv_usec >= USECPERSEC))
  128. r = EINVAL;
  129. if (r != OK) {
  130. se->requestor = NULL;
  131. return(r);
  132. }
  133. do_timeout = 1;
  134. } else
  135. do_timeout = 0;
  136. /* If there is no timeout, we block forever. Otherwise, we block up to the
  137. * specified time interval.
  138. */
  139. if (!do_timeout) /* No timeout value set */
  140. se->block = 1;
  141. else if (do_timeout && (timeout.tv_sec > 0 || timeout.tv_usec > 0))
  142. se->block = 1;
  143. else /* timeout set as (0,0) - this effects a poll */
  144. se->block = 0;
  145. se->expiry = 0; /* no timer set (yet) */
  146. /* We are going to lock filps, and that means that while locking a second
  147. * filp, we might already get the results for the first one. In that case,
  148. * the incoming results must not cause the select call to finish prematurely.
  149. */
  150. se->starting = TRUE;
  151. /* Verify that file descriptors are okay to select on */
  152. for (fd = 0; fd < nfds; fd++) {
  153. /* Because the select() interface implicitly includes file descriptors
  154. * you might not want to select on, we have to figure out whether we're
  155. * interested in them. Typically, these file descriptors include fd's
  156. * inherited from the parent proc and file descriptors that have been
  157. * close()d, but had a lower fd than one in the current set.
  158. */
  159. if (!(ops = tab2ops(fd, se)))
  160. continue; /* No operations set; nothing to do for this fd */
  161. /* Get filp belonging to this fd */
  162. f = se->filps[fd] = get_filp(fd, VNODE_READ);
  163. if (f == NULL) {
  164. if (err_code == EBADF)
  165. r = err_code;
  166. else /* File descriptor is 'ready' to return EIO */
  167. r = EINTR;
  168. se->requestor = NULL;
  169. return(r);
  170. }
  171. /* Check file types. According to POSIX 2008:
  172. * "The pselect() and select() functions shall support regular files,
  173. * terminal and pseudo-terminal devices, FIFOs, pipes, and sockets. The
  174. * behavior of pselect() and select() on file descriptors that refer to
  175. * other types of file is unspecified."
  176. *
  177. * In our case, terminal and pseudo-terminal devices are handled by the
  178. * TTY major and sockets by either INET major (socket type AF_INET) or
  179. * UDS major (socket type AF_UNIX). Additionally, we give other
  180. * character drivers the chance to handle select for any of their
  181. * device nodes. Some may not implement support for select and let
  182. * libchardriver return EBADF, which we then pass to the calling
  183. * process once we receive the reply.
  184. */
  185. se->type[fd] = -1;
  186. for (type = 0; type < SEL_FDS; type++) {
  187. if (fdtypes[type].type_match(f)) {
  188. se->type[fd] = type;
  189. se->nfds = fd+1;
  190. se->filps[fd]->filp_selectors++;
  191. break;
  192. }
  193. }
  194. unlock_filp(f);
  195. if (se->type[fd] == -1) { /* Type not found */
  196. se->requestor = NULL;
  197. return(EBADF);
  198. }
  199. }
  200. /* Check all file descriptors in the set whether one is 'ready' now */
  201. for (fd = 0; fd < nfds; fd++) {
  202. /* Again, check for involuntarily selected fd's */
  203. if (!(ops = tab2ops(fd, se)))
  204. continue; /* No operations set; nothing to do for this fd */
  205. /* File descriptors selected for reading that are not opened for
  206. * reading should be marked as readable, as read calls would fail
  207. * immediately. The same applies to writing.
  208. */
  209. f = se->filps[fd];
  210. if ((ops & SEL_RD) && !(f->filp_mode & R_BIT)) {
  211. ops2tab(SEL_RD, fd, se);
  212. ops &= ~SEL_RD;
  213. }
  214. if ((ops & SEL_WR) && !(f->filp_mode & W_BIT)) {
  215. ops2tab(SEL_WR, fd, se);
  216. ops &= ~SEL_WR;
  217. }
  218. /* Test filp for select operations if not already done so. e.g.,
  219. * processes sharing a filp and both doing a select on that filp. */
  220. if ((f->filp_select_ops & ops) != ops) {
  221. int wantops;
  222. wantops = (f->filp_select_ops |= ops);
  223. type = se->type[fd];
  224. select_lock_filp(f, wantops);
  225. r = fdtypes[type].select_request(f, &wantops, se->block, fp);
  226. unlock_filp(f);
  227. if (r != OK && r != SUSPEND) {
  228. se->error = r;
  229. break; /* Error or bogus return code; abort */
  230. }
  231. /* The select request above might have turned on/off some
  232. * operations because they were 'ready' or not meaningful.
  233. * Either way, we might have a result and we need to store them
  234. * in the select table entry. */
  235. if (wantops & ops) ops2tab(wantops, fd, se);
  236. }
  237. }
  238. /* At this point there won't be any blocking calls anymore. */
  239. se->starting = FALSE;
  240. if ((se->nreadyfds > 0 || se->error != OK || !se->block) &&
  241. !is_deferred(se)) {
  242. /* An error occurred, or fd's were found that were ready to go right
  243. * away, and/or we were instructed not to block at all. Must return
  244. * immediately. Do not copy FD sets if an error occurred.
  245. */
  246. if (se->error != OK)
  247. r = se->error;
  248. else
  249. r = copy_fdsets(se, se->nfds, TO_PROC);
  250. select_cancel_all(se);
  251. se->requestor = NULL;
  252. if (r != OK)
  253. return(r);
  254. return(se->nreadyfds);
  255. }
  256. /* Convert timeval to ticks and set the timer. If it fails, undo
  257. * all, return error.
  258. */
  259. if (do_timeout && se->block) {
  260. /* Open Group:
  261. * "If the requested timeout interval requires a finer
  262. * granularity than the implementation supports, the
  263. * actual timeout interval shall be rounded up to the next
  264. * supported value."
  265. */
  266. if (timeout.tv_sec >= (TMRDIFF_MAX - 1) / system_hz) {
  267. ticks = TMRDIFF_MAX; /* silently truncate */
  268. } else {
  269. ticks = timeout.tv_sec * system_hz +
  270. (timeout.tv_usec * system_hz + USECPERSEC-1) / USECPERSEC;
  271. }
  272. assert(ticks != 0 && ticks <= TMRDIFF_MAX);
  273. se->expiry = ticks;
  274. set_timer(&se->timer, ticks, select_timeout_check, s);
  275. }
  276. /* process now blocked */
  277. suspend(FP_BLOCKED_ON_SELECT);
  278. return(SUSPEND);
  279. }
  280. /*===========================================================================*
  281. * is_deferred *
  282. *===========================================================================*/
  283. static int is_deferred(struct selectentry *se)
  284. {
  285. /* Find out whether this select has pending initial replies */
  286. int fd;
  287. struct filp *f;
  288. /* The select call must have finished its initialization at all. */
  289. if (se->starting) return(TRUE);
  290. for (fd = 0; fd < se->nfds; fd++) {
  291. if ((f = se->filps[fd]) == NULL) continue;
  292. if (f->filp_select_flags & (FSF_UPDATE|FSF_BUSY)) return(TRUE);
  293. }
  294. return(FALSE);
  295. }
  296. /*===========================================================================*
  297. * is_regular_file *
  298. *===========================================================================*/
  299. static int is_regular_file(struct filp *f)
  300. {
  301. return(f && f->filp_vno && S_ISREG(f->filp_vno->v_mode));
  302. }
  303. /*===========================================================================*
  304. * is_pipe *
  305. *===========================================================================*/
  306. static int is_pipe(struct filp *f)
  307. {
  308. /* Recognize either anonymous pipe or named pipe (FIFO) */
  309. return(f && f->filp_vno && S_ISFIFO(f->filp_vno->v_mode));
  310. }
  311. /*===========================================================================*
  312. * is_char_device *
  313. *===========================================================================*/
  314. static int is_char_device(struct filp *f)
  315. {
  316. /* See if this filp is a handle on a character device. This function MUST NOT
  317. * block its calling thread. The given filp may or may not be locked.
  318. */
  319. return (f && f->filp_vno && S_ISCHR(f->filp_vno->v_mode));
  320. }
  321. /*===========================================================================*
  322. * select_request_char *
  323. *===========================================================================*/
  324. static int select_request_char(struct filp *f, int *ops, int block,
  325. struct fproc *rfp)
  326. {
  327. /* Check readiness status on a character device. Unless suitable results are
  328. * available right now, this will only initiate the polling process, causing
  329. * result processing to be deferred. This function MUST NOT block its calling
  330. * thread. The given filp may or may not be locked.
  331. */
  332. dev_t dev;
  333. int r, rops;
  334. struct dmap *dp;
  335. /* Start by remapping the device node number to a "real" device number. Those
  336. * two are different only for CTTY_MAJOR aka /dev/tty, but that one single
  337. * exception requires quite some extra effort here: the select code matches
  338. * character driver replies to their requests based on the device number, so
  339. * it needs to be aware that device numbers may be mapped. The idea is to
  340. * perform the mapping once and store the result in the filp object, so that
  341. * at least we don't run into problems when a process loses its controlling
  342. * terminal while doing a select (see also free_proc). It should be noted
  343. * that it is possible that multiple processes share the same /dev/tty filp,
  344. * and they may not all have a controlling terminal. The ctty-less processes
  345. * should never pass the mapping; a more problematic case is checked below.
  346. *
  347. * The cdev_map call also checks the major number for rough validity, so that
  348. * we can use it to index the dmap array safely a bit later.
  349. */
  350. if ((dev = cdev_map(f->filp_vno->v_sdev, rfp)) == NO_DEV)
  351. return(ENXIO);
  352. if (f->filp_char_select_dev != NO_DEV && f->filp_char_select_dev != dev) {
  353. /* Currently, this case can occur as follows: a process with a
  354. * controlling terminal opens /dev/tty and forks, the new child starts
  355. * a new session, opens a new controlling terminal, and both parent and
  356. * child call select on the /dev/tty file descriptor. If this case ever
  357. * becomes real, a better solution may be to force-close a filp for
  358. * /dev/tty when a new controlling terminal is opened.
  359. */
  360. printf("VFS: file pointer has multiple controlling TTYs!\n");
  361. return(EIO);
  362. }
  363. f->filp_char_select_dev = dev; /* set before possibly suspending */
  364. rops = *ops;
  365. /* By default, nothing to do */
  366. *ops = 0;
  367. /*
  368. * If we have previously asked the driver to notify us about certain ready
  369. * operations, but it has not notified us yet, then we can safely assume that
  370. * those operations are not ready right now. Therefore, if this call is not
  371. * supposed to block, we can disregard the pending operations as not ready.
  372. * We must make absolutely sure that the flags are "stable" right now though:
  373. * we are neither waiting to query the driver about them (FSF_UPDATE) nor
  374. * querying the driver about them right now (FSF_BUSY). This is a dangerous
  375. * case of premature optimization and may be removed altogether if it proves
  376. * to continue to be a source of bugs.
  377. */
  378. if (!block && !(f->filp_select_flags & (FSF_UPDATE | FSF_BUSY)) &&
  379. (f->filp_select_flags & FSF_BLOCKED)) {
  380. if ((rops & SEL_RD) && (f->filp_select_flags & FSF_RD_BLOCK))
  381. rops &= ~SEL_RD;
  382. if ((rops & SEL_WR) && (f->filp_select_flags & FSF_WR_BLOCK))
  383. rops &= ~SEL_WR;
  384. if ((rops & SEL_ERR) && (f->filp_select_flags & FSF_ERR_BLOCK))
  385. rops &= ~SEL_ERR;
  386. if (!(rops & (SEL_RD|SEL_WR|SEL_ERR)))
  387. return(OK);
  388. }
  389. f->filp_select_flags |= FSF_UPDATE;
  390. if (block) {
  391. rops |= SEL_NOTIFY;
  392. if (rops & SEL_RD) f->filp_select_flags |= FSF_RD_BLOCK;
  393. if (rops & SEL_WR) f->filp_select_flags |= FSF_WR_BLOCK;
  394. if (rops & SEL_ERR) f->filp_select_flags |= FSF_ERR_BLOCK;
  395. }
  396. if (f->filp_select_flags & FSF_BUSY)
  397. return(SUSPEND);
  398. dp = &dmap[major(dev)];
  399. if (dp->dmap_sel_busy)
  400. return(SUSPEND);
  401. f->filp_select_flags &= ~FSF_UPDATE;
  402. r = cdev_select(dev, rops);
  403. if (r != OK)
  404. return(r);
  405. dp->dmap_sel_busy = TRUE;
  406. dp->dmap_sel_filp = f;
  407. f->filp_select_flags |= FSF_BUSY;
  408. return(SUSPEND);
  409. }
  410. /*===========================================================================*
  411. * select_request_file *
  412. *===========================================================================*/
  413. static int select_request_file(struct filp *UNUSED(f), int *UNUSED(ops),
  414. int UNUSED(block), struct fproc *UNUSED(rfp))
  415. {
  416. /* Files are always ready, so output *ops is input *ops */
  417. return(OK);
  418. }
  419. /*===========================================================================*
  420. * select_request_pipe *
  421. *===========================================================================*/
  422. static int select_request_pipe(struct filp *f, int *ops, int block,
  423. struct fproc *UNUSED(rfp))
  424. {
  425. /* Check readiness status on a pipe. The given filp is locked. This function
  426. * may block its calling thread if necessary.
  427. */
  428. int orig_ops, r = 0, err;
  429. orig_ops = *ops;
  430. if ((*ops & (SEL_RD|SEL_ERR))) {
  431. /* Check if we can read 1 byte */
  432. err = pipe_check(f, READING, f->filp_flags & ~O_NONBLOCK, 1,
  433. 1 /* Check only */);
  434. if (err != SUSPEND)
  435. r |= SEL_RD;
  436. if (err < 0 && err != SUSPEND)
  437. r |= SEL_ERR;
  438. }
  439. if ((*ops & (SEL_WR|SEL_ERR))) {
  440. /* Check if we can write 1 byte */
  441. err = pipe_check(f, WRITING, f->filp_flags & ~O_NONBLOCK, 1,
  442. 1 /* Check only */);
  443. if (err != SUSPEND)
  444. r |= SEL_WR;
  445. if (err < 0 && err != SUSPEND)
  446. r |= SEL_ERR;
  447. }
  448. /* Some options we collected might not be requested. */
  449. *ops = r & orig_ops;
  450. if (!*ops && block)
  451. f->filp_pipe_select_ops |= orig_ops;
  452. return(OK);
  453. }
  454. /*===========================================================================*
  455. * tab2ops *
  456. *===========================================================================*/
  457. static int tab2ops(int fd, struct selectentry *e)
  458. {
  459. int ops = 0;
  460. if (FD_ISSET(fd, &e->readfds)) ops |= SEL_RD;
  461. if (FD_ISSET(fd, &e->writefds)) ops |= SEL_WR;
  462. if (FD_ISSET(fd, &e->errorfds)) ops |= SEL_ERR;
  463. return(ops);
  464. }
  465. /*===========================================================================*
  466. * ops2tab *
  467. *===========================================================================*/
  468. static void ops2tab(int ops, int fd, struct selectentry *e)
  469. {
  470. if ((ops & SEL_RD) && e->vir_readfds && FD_ISSET(fd, &e->readfds) &&
  471. !FD_ISSET(fd, &e->ready_readfds)) {
  472. FD_SET(fd, &e->ready_readfds);
  473. e->nreadyfds++;
  474. }
  475. if ((ops & SEL_WR) && e->vir_writefds && FD_ISSET(fd, &e->writefds) &&
  476. !FD_ISSET(fd, &e->ready_writefds)) {
  477. FD_SET(fd, &e->ready_writefds);
  478. e->nreadyfds++;
  479. }
  480. if ((ops & SEL_ERR) && e->vir_errorfds && FD_ISSET(fd, &e->errorfds) &&
  481. !FD_ISSET(fd, &e->ready_errorfds)) {
  482. FD_SET(fd, &e->ready_errorfds);
  483. e->nreadyfds++;
  484. }
  485. }
  486. /*===========================================================================*
  487. * copy_fdsets *
  488. *===========================================================================*/
  489. static int copy_fdsets(struct selectentry *se, int nfds, int direction)
  490. {
  491. /* Copy FD sets from or to the user process calling select(2). This function
  492. * MUST NOT block the calling thread.
  493. */
  494. int r;
  495. size_t fd_setsize;
  496. endpoint_t src_e, dst_e;
  497. fd_set *src_fds, *dst_fds;
  498. if (nfds < 0 || nfds > OPEN_MAX)
  499. panic("select copy_fdsets: nfds wrong: %d", nfds);
  500. /* Only copy back as many bits as the user expects. */
  501. fd_setsize = (size_t) (howmany(nfds, __NFDBITS) * sizeof(__fd_mask));
  502. /* Set source and destination endpoints */
  503. src_e = (direction == FROM_PROC) ? se->req_endpt : SELF;
  504. dst_e = (direction == FROM_PROC) ? SELF : se->req_endpt;
  505. /* read set */
  506. src_fds = (direction == FROM_PROC) ? se->vir_readfds : &se->ready_readfds;
  507. dst_fds = (direction == FROM_PROC) ? &se->readfds : se->vir_readfds;
  508. if (se->vir_readfds) {
  509. r = sys_datacopy_wrapper(src_e, (vir_bytes) src_fds, dst_e,
  510. (vir_bytes) dst_fds, fd_setsize);
  511. if (r != OK) return(r);
  512. }
  513. /* write set */
  514. src_fds = (direction == FROM_PROC) ? se->vir_writefds : &se->ready_writefds;
  515. dst_fds = (direction == FROM_PROC) ? &se->writefds : se->vir_writefds;
  516. if (se->vir_writefds) {
  517. r = sys_datacopy_wrapper(src_e, (vir_bytes) src_fds, dst_e,
  518. (vir_bytes) dst_fds, fd_setsize);
  519. if (r != OK) return(r);
  520. }
  521. /* error set */
  522. src_fds = (direction == FROM_PROC) ? se->vir_errorfds : &se->ready_errorfds;
  523. dst_fds = (direction == FROM_PROC) ? &se->errorfds : se->vir_errorfds;
  524. if (se->vir_errorfds) {
  525. r = sys_datacopy_wrapper(src_e, (vir_bytes) src_fds, dst_e,
  526. (vir_bytes) dst_fds, fd_setsize);
  527. if (r != OK) return(r);
  528. }
  529. return(OK);
  530. }
  531. /*===========================================================================*
  532. * select_cancel_all *
  533. *===========================================================================*/
  534. static void select_cancel_all(struct selectentry *se)
  535. {
  536. /* Cancel select, possibly on success. Decrease select usage and cancel timer.
  537. * This function MUST NOT block its calling thread.
  538. */
  539. int fd;
  540. struct filp *f;
  541. for (fd = 0; fd < se->nfds; fd++) {
  542. if ((f = se->filps[fd]) == NULL) continue;
  543. se->filps[fd] = NULL;
  544. select_cancel_filp(f);
  545. }
  546. if (se->expiry > 0) {
  547. cancel_timer(&se->timer);
  548. se->expiry = 0;
  549. }
  550. se->requestor = NULL;
  551. }
  552. /*===========================================================================*
  553. * select_cancel_filp *
  554. *===========================================================================*/
  555. static void select_cancel_filp(struct filp *f)
  556. {
  557. /* Reduce the number of select users of this filp. This function MUST NOT block
  558. * its calling thread.
  559. */
  560. devmajor_t major;
  561. assert(f);
  562. assert(f->filp_selectors > 0);
  563. assert(f->filp_count > 0);
  564. f->filp_selectors--;
  565. if (f->filp_selectors == 0) {
  566. /* No one selecting on this filp anymore, forget about select state */
  567. f->filp_select_ops = 0;
  568. f->filp_select_flags = 0;
  569. f->filp_pipe_select_ops = 0;
  570. /* If this filp is the subject of an ongoing select query to a
  571. * character device, mark the query as stale, so that this filp will
  572. * not be checked when the result arrives. The filp select device may
  573. * still be NO_DEV if do_select fails on the initial fd check.
  574. */
  575. if (is_char_device(f) && f->filp_char_select_dev != NO_DEV) {
  576. major = major(f->filp_char_select_dev);
  577. if (dmap[major].dmap_sel_busy &&
  578. dmap[major].dmap_sel_filp == f)
  579. dmap[major].dmap_sel_filp = NULL; /* leave _busy set */
  580. f->filp_char_select_dev = NO_DEV;
  581. }
  582. }
  583. }
  584. /*===========================================================================*
  585. * select_return *
  586. *===========================================================================*/
  587. static void select_return(struct selectentry *se)
  588. {
  589. /* Return the results of a select call to the user process and revive the
  590. * process. This function MUST NOT block its calling thread.
  591. */
  592. int r;
  593. assert(!is_deferred(se)); /* Not done yet, first wait for async reply */
  594. select_cancel_all(se);
  595. if (se->error != OK)
  596. r = se->error;
  597. else
  598. r = copy_fdsets(se, se->nfds, TO_PROC);
  599. if (r == OK)
  600. r = se->nreadyfds;
  601. revive(se->req_endpt, r);
  602. }
  603. /*===========================================================================*
  604. * select_callback *
  605. *===========================================================================*/
  606. void select_callback(struct filp *f, int status)
  607. {
  608. /* The status of a filp has changed, with the given ready operations or error.
  609. * This function is currently called only for pipes, and holds the lock to
  610. * the filp.
  611. */
  612. filp_status(f, status);
  613. }
  614. /*===========================================================================*
  615. * init_select *
  616. *===========================================================================*/
  617. void init_select(void)
  618. {
  619. int s;
  620. for (s = 0; s < MAXSELECTS; s++)
  621. init_timer(&selecttab[s].timer);
  622. }
  623. /*===========================================================================*
  624. * select_forget *
  625. *===========================================================================*/
  626. void select_forget(void)
  627. {
  628. /* The calling thread's associated process is expected to be unpaused, due to
  629. * a signal that is supposed to interrupt the current system call. Totally
  630. * forget about the select(). This function may block its calling thread if
  631. * necessary (but it doesn't).
  632. */
  633. int slot;
  634. struct selectentry *se;
  635. for (slot = 0; slot < MAXSELECTS; slot++) {
  636. se = &selecttab[slot];
  637. if (se->requestor == fp)
  638. break;
  639. }
  640. if (slot >= MAXSELECTS) return; /* Entry not found */
  641. assert(se->starting == FALSE);
  642. /* Do NOT test on is_deferred here. We can safely cancel ongoing queries. */
  643. select_cancel_all(se);
  644. }
  645. /*===========================================================================*
  646. * select_timeout_check *
  647. *===========================================================================*/
  648. void select_timeout_check(int s)
  649. {
  650. /* An alarm has gone off for one of the select queries. This function MUST NOT
  651. * block its calling thread.
  652. */
  653. struct selectentry *se;
  654. if (s < 0 || s >= MAXSELECTS) return; /* Entry does not exist */
  655. se = &selecttab[s];
  656. if (se->requestor == NULL) return;
  657. if (se->expiry == 0) return; /* Strange, did we even ask for a timeout? */
  658. se->expiry = 0;
  659. if (!is_deferred(se))
  660. select_return(se);
  661. else
  662. se->block = 0; /* timer triggered "too soon", treat as nonblocking */
  663. }
  664. /*===========================================================================*
  665. * select_unsuspend_by_endpt *
  666. *===========================================================================*/
  667. void select_unsuspend_by_endpt(endpoint_t proc_e)
  668. {
  669. /* Revive blocked processes when a driver has disappeared */
  670. devmajor_t major;
  671. int fd, s;
  672. struct selectentry *se;
  673. struct filp *f;
  674. for (s = 0; s < MAXSELECTS; s++) {
  675. int wakehim = 0;
  676. se = &selecttab[s];
  677. if (se->requestor == NULL) continue;
  678. if (se->requestor->fp_endpoint == proc_e) {
  679. assert(se->requestor->fp_flags & FP_EXITING);
  680. select_cancel_all(se);
  681. continue;
  682. }
  683. for (fd = 0; fd < se->nfds; fd++) {
  684. if ((f = se->filps[fd]) == NULL || !is_char_device(f))
  685. continue;
  686. assert(f->filp_char_select_dev != NO_DEV);
  687. major = major(f->filp_char_select_dev);
  688. if (dmap_driver_match(proc_e, major)) {
  689. se->filps[fd] = NULL;
  690. se->error = EIO;
  691. select_cancel_filp(f);
  692. wakehim = 1;
  693. }
  694. }
  695. if (wakehim && !is_deferred(se))
  696. select_return(se);
  697. }
  698. }
  699. /*===========================================================================*
  700. * select_reply1 *
  701. *===========================================================================*/
  702. void select_reply1(endpoint_t driver_e, devminor_t minor, int status)
  703. {
  704. /* Handle the initial reply to CDEV_SELECT request. This function MUST NOT
  705. * block its calling thread.
  706. */
  707. devmajor_t major;
  708. dev_t dev;
  709. struct filp *f;
  710. struct dmap *dp;
  711. /* Figure out which device is replying */
  712. if ((dp = get_dmap(driver_e)) == NULL) return;
  713. major = dp-dmap;
  714. dev = makedev(major, minor);
  715. /* Get filp belonging to character special file */
  716. if (!dp->dmap_sel_busy) {
  717. printf("VFS (%s:%d): major %d was not expecting a CDEV_SELECT reply\n",
  718. __FILE__, __LINE__, major);
  719. return;
  720. }
  721. /* The select filp may have been set to NULL if the requestor has been
  722. * unpaused in the meantime. In that case, we ignore the result, but we do
  723. * look for other filps to restart later.
  724. */
  725. if ((f = dp->dmap_sel_filp) != NULL) {
  726. /* Find vnode and check we got a reply from the device we expected */
  727. assert(is_char_device(f));
  728. assert(f->filp_char_select_dev != NO_DEV);
  729. if (f->filp_char_select_dev != dev) {
  730. /* This should never happen. The driver may be misbehaving.
  731. * For now we assume that the reply we want will arrive later..
  732. */
  733. printf("VFS (%s:%d): expected reply from dev %llx not %llx\n",
  734. __FILE__, __LINE__, f->filp_char_select_dev, dev);
  735. return;
  736. }
  737. }
  738. /* No longer waiting for a reply from this device */
  739. dp->dmap_sel_busy = FALSE;
  740. dp->dmap_sel_filp = NULL;
  741. /* Process the select result only if the filp is valid. */
  742. if (f != NULL) {
  743. assert(f->filp_count >= 1);
  744. assert(f->filp_select_flags & FSF_BUSY);
  745. f->filp_select_flags &= ~FSF_BUSY;
  746. /* The select call is done now, except when
  747. * - another process started a select on the same filp with possibly a
  748. * different set of operations.
  749. * - a process does a select on the same filp but using different file
  750. * descriptors.
  751. * - the select has a timeout. Upon receiving this reply the operations
  752. * might not be ready yet, so we want to wait for that to ultimately
  753. * happen.
  754. * Therefore we need to keep remembering what the operations are.
  755. */
  756. if (!(f->filp_select_flags & (FSF_UPDATE|FSF_BLOCKED)))
  757. f->filp_select_ops = 0; /* done selecting */
  758. else if (status > 0 && !(f->filp_select_flags & FSF_UPDATE))
  759. /* there may be operations pending */
  760. f->filp_select_ops &= ~status;
  761. /* Record new filp status */
  762. if (!(status == 0 && (f->filp_select_flags & FSF_BLOCKED))) {
  763. if (status > 0) { /* operations ready */
  764. if (status & SEL_RD)
  765. f->filp_select_flags &= ~FSF_RD_BLOCK;
  766. if (status & SEL_WR)
  767. f->filp_select_flags &= ~FSF_WR_BLOCK;
  768. if (status & SEL_ERR)
  769. f->filp_select_flags &= ~FSF_ERR_BLOCK;
  770. } else if (status < 0) { /* error */
  771. /* Always unblock upon error */
  772. f->filp_select_flags &= ~FSF_BLOCKED;
  773. }
  774. }
  775. filp_status(f, status); /* Tell filp owners about the results */
  776. }
  777. select_restart_filps();
  778. }
  779. /*===========================================================================*
  780. * select_reply2 *
  781. *===========================================================================*/
  782. void select_reply2(endpoint_t driver_e, devminor_t minor, int status)
  783. {
  784. /* Handle secondary reply to DEV_SELECT request. A secondary reply occurs when
  785. * the select request is 'blocking' until an operation becomes ready. This
  786. * function MUST NOT block its calling thread.
  787. */
  788. int slot, found, fd;
  789. devmajor_t major;
  790. dev_t dev;
  791. struct filp *f;
  792. struct dmap *dp;
  793. struct selectentry *se;
  794. if (status == 0) {
  795. printf("VFS (%s:%d): weird status (%d) to report\n",
  796. __FILE__, __LINE__, status);
  797. return;
  798. }
  799. /* Figure out which device is replying */
  800. if ((dp = get_dmap(driver_e)) == NULL) {
  801. printf("VFS (%s:%d): endpoint %d is not a known driver endpoint\n",
  802. __FILE__, __LINE__, driver_e);
  803. return;
  804. }
  805. major = dp-dmap;
  806. dev = makedev(major, minor);
  807. /* Find all file descriptors selecting for this device */
  808. for (slot = 0; slot < MAXSELECTS; slot++) {
  809. se = &selecttab[slot];
  810. if (se->requestor == NULL) continue; /* empty slot */
  811. found = FALSE;
  812. for (fd = 0; fd < se->nfds; fd++) {
  813. if ((f = se->filps[fd]) == NULL) continue;
  814. if (!is_char_device(f)) continue;
  815. assert(f->filp_char_select_dev != NO_DEV);
  816. if (f->filp_char_select_dev != dev) continue;
  817. if (status > 0) { /* Operations ready */
  818. /* Clear the replied bits from the request
  819. * mask unless FSF_UPDATE is set.
  820. */
  821. if (!(f->filp_select_flags & FSF_UPDATE))
  822. f->filp_select_ops &= ~status;
  823. if (status & SEL_RD)
  824. f->filp_select_flags &= ~FSF_RD_BLOCK;
  825. if (status & SEL_WR)
  826. f->filp_select_flags &= ~FSF_WR_BLOCK;
  827. if (status & SEL_ERR)
  828. f->filp_select_flags &= ~FSF_ERR_BLOCK;
  829. ops2tab(status, fd, se);
  830. } else {
  831. f->filp_select_flags &= ~FSF_BLOCKED;
  832. se->error = status;
  833. }
  834. found = TRUE;
  835. }
  836. /* Even if 'found' is set now, nothing may have changed for this call,
  837. * as it may not have been interested in the operations that were
  838. * reported as ready. Let restart_proc check.
  839. */
  840. if (found)
  841. restart_proc(se);
  842. }
  843. select_restart_filps();
  844. }
  845. /*===========================================================================*
  846. * select_restart_filps *
  847. *===========================================================================*/
  848. static void select_restart_filps(void)
  849. {
  850. /* We got a result from a character driver, and now we need to check if we can
  851. * restart deferred polling operations. This function MUST NOT block its
  852. * calling thread.
  853. */
  854. int fd, slot;
  855. struct filp *f;
  856. struct selectentry *se;
  857. /* Locate filps that can be restarted */
  858. for (slot = 0; slot < MAXSELECTS; slot++) {
  859. se = &selecttab[slot];
  860. if (se->requestor == NULL) continue; /* empty slot */
  861. /* Only 'deferred' processes are eligible to restart */
  862. if (!is_deferred(se)) continue;
  863. /* Find filps that are not waiting for a reply, but have an updated
  864. * status (i.e., another select on the same filp with possibly a
  865. * different set of operations is to be done), and thus requires the
  866. * select request to be sent again).
  867. */
  868. for (fd = 0; fd < se->nfds; fd++) {
  869. int r, wantops, ops;
  870. if ((f = se->filps[fd]) == NULL) continue;
  871. if (f->filp_select_flags & FSF_BUSY) /* Still waiting for */
  872. continue; /* initial reply */
  873. if (!(f->filp_select_flags & FSF_UPDATE)) /* Must be in */
  874. continue; /* 'update' state */
  875. /* This function is suitable only for character devices. In
  876. * particular, checking pipes the same way would introduce a
  877. * serious locking problem.
  878. */
  879. assert(is_char_device(f));
  880. wantops = ops = f->filp_select_ops;
  881. r = select_request_char(f, &wantops, se->block, se->requestor);
  882. if (r != OK && r != SUSPEND) {
  883. se->error = r;
  884. restart_proc(se);
  885. break; /* Error or bogus return code; abort */
  886. }
  887. if (wantops & ops) ops2tab(wantops, fd, se);
  888. }
  889. }
  890. }
  891. /*===========================================================================*
  892. * filp_status *
  893. *===========================================================================*/
  894. static void filp_status(f, status)
  895. struct filp *f;
  896. int status;
  897. {
  898. /* Tell processes that need to know about the status of this filp. This
  899. * function MUST NOT block its calling thread.
  900. */
  901. int fd, slot, found;
  902. struct selectentry *se;
  903. for (slot = 0; slot < MAXSELECTS; slot++) {
  904. se = &selecttab[slot];
  905. if (se->requestor == NULL) continue; /* empty slot */
  906. found = FALSE;
  907. for (fd = 0; fd < se->nfds; fd++) {
  908. if (se->filps[fd] != f) continue;
  909. if (status < 0)
  910. se->error = status;
  911. else
  912. ops2tab(status, fd, se);
  913. found = TRUE;
  914. }
  915. if (found)
  916. restart_proc(se);
  917. }
  918. }
  919. /*===========================================================================*
  920. * restart_proc *
  921. *===========================================================================*/
  922. static void restart_proc(se)
  923. struct selectentry *se;
  924. {
  925. /* Tell process about select results (if any) unless there are still results
  926. * pending. This function MUST NOT block its calling thread.
  927. */
  928. if ((se->nreadyfds > 0 || se->error != OK || !se->block) && !is_deferred(se))
  929. select_return(se);
  930. }
  931. /*===========================================================================*
  932. * wipe_select *
  933. *===========================================================================*/
  934. static void wipe_select(struct selectentry *se)
  935. {
  936. se->nfds = 0;
  937. se->nreadyfds = 0;
  938. se->error = OK;
  939. se->block = 0;
  940. memset(se->filps, 0, sizeof(se->filps));
  941. FD_ZERO(&se->readfds);
  942. FD_ZERO(&se->writefds);
  943. FD_ZERO(&se->errorfds);
  944. FD_ZERO(&se->ready_readfds);
  945. FD_ZERO(&se->ready_writefds);
  946. FD_ZERO(&se->ready_errorfds);
  947. }
  948. /*===========================================================================*
  949. * select_lock_filp *
  950. *===========================================================================*/
  951. static void select_lock_filp(struct filp *f, int ops)
  952. {
  953. /* Lock a filp and vnode based on which operations are requested. This function
  954. * may block its calling thread, obviously.
  955. */
  956. tll_access_t locktype;
  957. locktype = VNODE_READ; /* By default */
  958. if (ops & (SEL_WR|SEL_ERR))
  959. /* Selecting for error or writing requires exclusive access */
  960. locktype = VNODE_WRITE;
  961. lock_filp(f, locktype);
  962. }
  963. /*
  964. * Dump the state of the entire select table, for debugging purposes.
  965. */
  966. void
  967. select_dump(void)
  968. {
  969. struct selectentry *se;
  970. struct filp *f;
  971. struct dmap *dp;
  972. dev_t dev;
  973. int s, fd;
  974. for (s = 0; s < MAXSELECTS; s++) {
  975. se = &selecttab[s];
  976. if (se->requestor == NULL)
  977. continue;
  978. printf("select %d: endpt %d nfds %d nreadyfds %d error %d "
  979. "block %d starting %d expiry %u is_deferred %d\n",
  980. s, se->req_endpt, se->nfds, se->nreadyfds, se->error,
  981. se->block, se->starting, se->expiry, is_deferred(se));
  982. for (fd = 0; !se->starting && fd < se->nfds; fd++) {
  983. /* Save on output: do not print NULL filps at all. */
  984. if ((f = se->filps[fd]) == NULL)
  985. continue;
  986. printf("- [%d] filp %p flags %x type ", fd, f,
  987. f->filp_select_flags);
  988. if (is_regular_file(f))
  989. printf("regular\n");
  990. else if (is_pipe(f))
  991. printf("pipe\n");
  992. else if (is_char_device(f)) {
  993. dev = cdev_map(f->filp_vno->v_sdev,
  994. se->requestor);
  995. printf("char (dev <%d,%d>, dmap ",
  996. major(dev), minor(dev));
  997. if (dev != NO_DEV) {
  998. dp = &dmap[major(dev)];
  999. printf("busy %d filp %p)\n",
  1000. dp->dmap_sel_busy,
  1001. dp->dmap_sel_filp);
  1002. } else
  1003. printf("unknown)\n");
  1004. } else
  1005. printf("unknown\n");
  1006. }
  1007. }
  1008. }