local_sockif.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843
  1. /****************************************************************************
  2. * net/local/local_sockif.c
  3. *
  4. * Copyright (C) 2017 Gregory Nutt. All rights reserved.
  5. * Author: Gregory Nutt <gnutt@nuttx.org>
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in
  15. * the documentation and/or other materials provided with the
  16. * distribution.
  17. * 3. Neither the name NuttX nor the names of its contributors may be
  18. * used to endorse or promote products derived from this software
  19. * without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  24. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  25. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  26. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  27. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  28. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  29. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  31. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  32. * POSSIBILITY OF SUCH DAMAGE.
  33. *
  34. ****************************************************************************/
  35. /****************************************************************************
  36. * Included Files
  37. ****************************************************************************/
  38. #include <nuttx/config.h>
  39. #include <sys/types.h>
  40. #include <sys/socket.h>
  41. #include <stdbool.h>
  42. #include <string.h>
  43. #include <assert.h>
  44. #include <errno.h>
  45. #include <debug.h>
  46. #include <netinet/in.h>
  47. #include <nuttx/net/net.h>
  48. #include <socket/socket.h>
  49. #include "local/local.h"
  50. #ifdef CONFIG_NET_LOCAL
  51. /****************************************************************************
  52. * Private Function Prototypes
  53. ****************************************************************************/
  54. static int local_setup(FAR struct socket *psock, int protocol);
  55. static sockcaps_t local_sockcaps(FAR struct socket *psock);
  56. static void local_addref(FAR struct socket *psock);
  57. static int local_bind(FAR struct socket *psock,
  58. FAR const struct sockaddr *addr, socklen_t addrlen);
  59. static int local_getsockname(FAR struct socket *psock,
  60. FAR struct sockaddr *addr, FAR socklen_t *addrlen);
  61. static int local_getpeername(FAR struct socket *psock,
  62. FAR struct sockaddr *addr, FAR socklen_t *addrlen);
  63. #ifndef CONFIG_NET_LOCAL_STREAM
  64. static int local_listen(FAR struct socket *psock, int backlog);
  65. #endif
  66. static int local_connect(FAR struct socket *psock,
  67. FAR const struct sockaddr *addr, socklen_t addrlen);
  68. #ifndef CONFIG_NET_LOCAL_STREAM
  69. static int local_accept(FAR struct socket *psock,
  70. FAR struct sockaddr *addr, FAR socklen_t *addrlen,
  71. FAR struct socket *newsock);
  72. #endif
  73. #ifndef CONFIG_DISABLE_POLL
  74. static int local_poll(FAR struct socket *psock,
  75. FAR struct pollfd *fds, bool setup);
  76. #endif
  77. static ssize_t local_send(FAR struct socket *psock, FAR const void *buf,
  78. size_t len, int flags);
  79. static ssize_t local_sendto(FAR struct socket *psock, FAR const void *buf,
  80. size_t len, int flags, FAR const struct sockaddr *to,
  81. socklen_t tolen);
  82. static int local_close(FAR struct socket *psock);
  83. /****************************************************************************
  84. * Public Data
  85. ****************************************************************************/
  86. const struct sock_intf_s g_local_sockif =
  87. {
  88. local_setup, /* si_setup */
  89. local_sockcaps, /* si_sockcaps */
  90. local_addref, /* si_addref */
  91. local_bind, /* si_bind */
  92. local_getsockname, /* si_getsockname */
  93. local_getpeername, /* si_getpeername */
  94. local_listen, /* si_listen */
  95. local_connect, /* si_connect */
  96. local_accept, /* si_accept */
  97. #ifndef CONFIG_DISABLE_POLL
  98. local_poll, /* si_poll */
  99. #endif
  100. local_send, /* si_send */
  101. local_sendto, /* si_sendto */
  102. #ifdef CONFIG_NET_SENDFILE
  103. NULL, /* si_sendfile */
  104. #endif
  105. local_recvfrom, /* si_recvfrom */
  106. local_close /* si_close */
  107. };
  108. /****************************************************************************
  109. * Private Functions
  110. ****************************************************************************/
  111. /****************************************************************************
  112. * Name: local_sockif_alloc
  113. *
  114. * Description:
  115. * Allocate and attach a local, Unix domain connection structure.
  116. *
  117. ****************************************************************************/
  118. #if defined(CONFIG_NET_LOCAL_STREAM) || defined(CONFIG_NET_LOCAL_DGRAM)
  119. static int local_sockif_alloc(FAR struct socket *psock)
  120. {
  121. /* Allocate the local connection structure */
  122. FAR struct local_conn_s *conn = local_alloc();
  123. if (conn == NULL)
  124. {
  125. /* Failed to reserve a connection structure */
  126. return -ENOMEM;
  127. }
  128. /* Set the reference count on the connection structure. This reference
  129. * count will be incremented only if the socket is dup'ed
  130. */
  131. DEBUGASSERT(conn->lc_crefs == 0);
  132. conn->lc_crefs = 1;
  133. /* Save the pre-allocated connection in the socket structure */
  134. psock->s_conn = conn;
  135. return OK;
  136. }
  137. #endif
  138. /****************************************************************************
  139. * Name: local_setup
  140. *
  141. * Description:
  142. * Called for socket() to verify that the provided socket type and
  143. * protocol are usable by this address family. Perform any family-
  144. * specific socket fields.
  145. *
  146. * Input Parameters:
  147. * psock A pointer to a user allocated socket structure to be initialized.
  148. * protocol (see sys/socket.h)
  149. *
  150. * Returned Value:
  151. * Zero (OK) is returned on success. Otherwise, a negated errno value is
  152. * returned.
  153. *
  154. ****************************************************************************/
  155. static int local_setup(FAR struct socket *psock, int protocol)
  156. {
  157. /* Allocate the appropriate connection structure. This reserves the
  158. * the connection structure is is unallocated at this point. It will
  159. * not actually be initialized until the socket is connected.
  160. *
  161. * REVIST: Only SOCK_STREAM and SOCK_DGRAM are supported. Should also
  162. * support SOCK_RAW.
  163. */
  164. switch (psock->s_type)
  165. {
  166. #ifdef CONFIG_NET_LOCAL_STREAM
  167. case SOCK_STREAM:
  168. if (protocol != 0 && protocol != IPPROTO_TCP)
  169. {
  170. return -EPROTONOSUPPORT;
  171. }
  172. /* Allocate and attach the local connection structure */
  173. return local_sockif_alloc(psock);
  174. #endif /* CONFIG_NET_LOCAL_STREAM */
  175. #ifdef CONFIG_NET_LOCAL_DGRAM
  176. case SOCK_DGRAM:
  177. if (protocol != 0 && protocol != IPPROTO_UDP)
  178. {
  179. return -EPROTONOSUPPORT;
  180. }
  181. /* Allocate and attach the local connection structure */
  182. return local_sockif_alloc(psock);
  183. #endif /* CONFIG_NET_LOCAL_DGRAM */
  184. default:
  185. return -EPROTONOSUPPORT;
  186. }
  187. }
  188. /****************************************************************************
  189. * Name: local_sockcaps
  190. *
  191. * Description:
  192. * Return the bit encoded capabilities of this socket.
  193. *
  194. * Input Parameters:
  195. * psock - Socket structure of the socket whose capabilities are being
  196. * queried.
  197. *
  198. * Returned Value:
  199. * The set of socket cababilities is returned.
  200. *
  201. ****************************************************************************/
  202. static sockcaps_t local_sockcaps(FAR struct socket *psock)
  203. {
  204. return SOCKCAP_NONBLOCKING;
  205. }
  206. /****************************************************************************
  207. * Name: local_addref
  208. *
  209. * Description:
  210. * Increment the refernce count on the underlying connection structure.
  211. *
  212. * Input Parameters:
  213. * psock - Socket structure of the socket whose reference count will be
  214. * incremented.
  215. *
  216. * Returned Value:
  217. * None
  218. *
  219. ****************************************************************************/
  220. static void local_addref(FAR struct socket *psock)
  221. {
  222. FAR struct local_conn_s *conn;
  223. DEBUGASSERT(psock != NULL && psock->s_conn != NULL &&
  224. psock->s_domain == PF_LOCAL);
  225. conn = psock->s_conn;
  226. DEBUGASSERT(conn->lc_crefs > 0 && conn->lc_crefs < 255);
  227. conn->lc_crefs++;
  228. }
  229. /****************************************************************************
  230. * Name: local_bind
  231. *
  232. * Description:
  233. * local_bind() gives the socket 'psock' the local address 'addr'. 'addr'
  234. * is 'addrlen' bytes long. Traditionally, this is called "assigning a
  235. * name to a socket." When a socket is created with socket(), it exists
  236. * in a name space (address family) but has no name assigned.
  237. *
  238. * Input Parameters:
  239. * psock Socket structure of the socket to bind
  240. * addr Socket local address
  241. * addrlen Length of 'addr'
  242. *
  243. * Returned Value:
  244. * 0 on success; A negated errno value is returned on failure. See
  245. * bind() for a list a appropriate error values.
  246. *
  247. ****************************************************************************/
  248. static int local_bind(FAR struct socket *psock,
  249. FAR const struct sockaddr *addr, socklen_t addrlen)
  250. {
  251. int ret;
  252. /* Verify that a valid address has been provided */
  253. if (addr->sa_family != AF_LOCAL || addrlen < sizeof(sa_family_t))
  254. {
  255. nerr("ERROR: Invalid address length: %d < %d\n",
  256. addrlen, sizeof(sa_family_t));
  257. return -EBADF;
  258. }
  259. /* Perform the binding depending on the protocol type */
  260. switch (psock->s_type)
  261. {
  262. /* Bind a local TCP/IP stream or datagram socket */
  263. #if defined(CONFIG_NET_LOCAL_STREAM) || defined(CONFIG_NET_LOCAL_DGRAM)
  264. #ifdef CONFIG_NET_LOCAL_STREAM
  265. case SOCK_STREAM:
  266. #endif
  267. #ifdef CONFIG_NET_LOCAL_DGRAM
  268. case SOCK_DGRAM:
  269. #endif
  270. {
  271. /* Bind the Unix domain connection structure */
  272. ret = psock_local_bind(psock, addr, addrlen);
  273. /* Mark the socket bound */
  274. if (ret >= 0)
  275. {
  276. psock->s_flags |= _SF_BOUND;
  277. }
  278. }
  279. break;
  280. #endif /* CONFIG_NET_LOCAL_STREAM || CONFIG_NET_LOCAL_DGRAM */
  281. default:
  282. ret = -EBADF;
  283. break;
  284. }
  285. return ret;
  286. }
  287. /****************************************************************************
  288. * Name: local_getsockname
  289. *
  290. * Description:
  291. * The local_getsockname() function retrieves the locally-bound name of
  292. * the specified local socket, stores this address in the sockaddr
  293. * structure pointed to by the 'addr' argument, and stores the length of
  294. * this address in the object pointed to by the 'addrlen' argument.
  295. *
  296. * If the actual length of the address is greater than the length of the
  297. * supplied sockaddr structure, the stored address will be truncated.
  298. *
  299. * If the socket has not been bound to a local name, the value stored in
  300. * the object pointed to by address is unspecified.
  301. *
  302. * Input Parameters:
  303. * psock Socket structure of the socket to be queried
  304. * addr sockaddr structure to receive data [out]
  305. * addrlen Length of sockaddr structure [in/out]
  306. *
  307. * Returned Value:
  308. * On success, 0 is returned, the 'addr' argument points to the address
  309. * of the socket, and the 'addrlen' argument points to the length of the
  310. * address. Otherwise, a negated errno value is returned. See
  311. * getsockname() for the list of appropriate error numbers.
  312. *
  313. ****************************************************************************/
  314. static int local_getsockname(FAR struct socket *psock,
  315. FAR struct sockaddr *addr,
  316. FAR socklen_t *addrlen)
  317. {
  318. FAR struct sockaddr_un *unaddr = (FAR struct sockaddr_un *)addr;
  319. FAR struct local_conn_s *conn;
  320. DEBUGASSERT(psock != NULL && psock->s_conn != NULL &&
  321. unaddr != NULL && addrlen != NULL &&
  322. *addrlen >= sizeof(sa_family_t));
  323. if (*addrlen < sizeof(sa_family_t))
  324. {
  325. /* This is apparently not an error */
  326. *addrlen = 0;
  327. return OK;
  328. }
  329. conn = (FAR struct local_conn_s *)psock->s_conn;
  330. /* Save the address family */
  331. unaddr->sun_family = AF_LOCAL;
  332. if (*addrlen > sizeof(sa_family_t))
  333. {
  334. /* Now copy the address description. */
  335. if (conn->lc_type == LOCAL_TYPE_UNNAMED)
  336. {
  337. /* Zero-length sun_path... This is an abstract Unix domain socket */
  338. *addrlen = sizeof(sa_family_t);
  339. }
  340. else /* conn->lctype = LOCAL_TYPE_PATHNAME */
  341. {
  342. /* Get the full length of the socket name (including null terminator) */
  343. int namelen = strlen(conn->lc_path) + 1;
  344. /* Get the available length in the user-provided buffer. */
  345. int pathlen = *addrlen - sizeof(sa_family_t);
  346. /* Clip the socket name size so that if fits in the user buffer */
  347. if (pathlen < namelen)
  348. {
  349. namelen = pathlen;
  350. }
  351. /* Copy the path into the user address structure */
  352. (void)strncpy(unaddr->sun_path, conn->lc_path, namelen);
  353. unaddr->sun_path[pathlen - 1] = '\0';
  354. *addrlen = sizeof(sa_family_t) + namelen;
  355. }
  356. }
  357. return OK;
  358. }
  359. /****************************************************************************
  360. * Name: local_getpeername
  361. *
  362. * Description:
  363. * The local_getpeername() function retrieves the remote-connected name of
  364. * the specified local socket, stores this address in the sockaddr
  365. * structure pointed to by the 'addr' argument, and stores the length of
  366. * this address in the object pointed to by the 'addrlen' argument.
  367. *
  368. * If the actual length of the address is greater than the length of the
  369. * supplied sockaddr structure, the stored address will be truncated.
  370. *
  371. * If the socket has not been bound to a local name, the value stored in
  372. * the object pointed to by address is unspecified.
  373. *
  374. * Parameters:
  375. * psock Socket structure of the socket to be queried
  376. * addr sockaddr structure to receive data [out]
  377. * addrlen Length of sockaddr structure [in/out]
  378. *
  379. * Returned Value:
  380. * On success, 0 is returned, the 'addr' argument points to the address
  381. * of the socket, and the 'addrlen' argument points to the length of the
  382. * address. Otherwise, a negated errno value is returned. See
  383. * getpeername() for the list of appropriate error numbers.
  384. *
  385. ****************************************************************************/
  386. static int local_getpeername(FAR struct socket *psock,
  387. FAR struct sockaddr *addr,
  388. FAR socklen_t *addrlen)
  389. {
  390. return local_getsockname(psock, addr, addrlen);
  391. }
  392. /****************************************************************************
  393. * Name: local_listen
  394. *
  395. * Description:
  396. * To accept connections, a socket is first created with psock_socket(), a
  397. * willingness to accept incoming connections and a queue limit for
  398. * incoming connections are specified with psock_listen(), and then the
  399. * connections are accepted with psock_accept(). For the case of local
  400. * unix sockets, psock_listen() calls this function. The psock_listen()
  401. * call applies only to sockets of type SOCK_STREAM or SOCK_SEQPACKET.
  402. *
  403. * Input Parameters:
  404. * psock Reference to an internal, boound socket structure.
  405. * backlog The maximum length the queue of pending connections may grow.
  406. * If a connection request arrives with the queue full, the client
  407. * may receive an error with an indication of ECONNREFUSED or,
  408. * if the underlying protocol supports retransmission, the request
  409. * may be ignored so that retries succeed.
  410. *
  411. * Returned Value:
  412. * On success, zero is returned. On error, a negated errno value is
  413. * returned. See list() for the set of appropriate error values.
  414. *
  415. ****************************************************************************/
  416. #ifndef CONFIG_NET_LOCAL_STREAM
  417. int local_listen(FAR struct socket *psock, int backlog)
  418. {
  419. return -EOPNOTSUPP;
  420. }
  421. #endif
  422. /****************************************************************************
  423. * Name: local_connect
  424. *
  425. * Description:
  426. * local_connect() connects the local socket referred to by the structure
  427. * 'psock' to the address specified by 'addr'. The addrlen argument
  428. * specifies the size of 'addr'. The format of the address in 'addr' is
  429. * determined by the address space of the socket 'psock'.
  430. *
  431. * If the socket 'psock' is of type SOCK_DGRAM then 'addr' is the address
  432. * to which datagrams are sent by default, and the only address from which
  433. * datagrams are received. If the socket is of type SOCK_STREAM or
  434. * SOCK_SEQPACKET, this call attempts to make a connection to the socket
  435. * that is bound to the address specified by 'addr'.
  436. *
  437. * Generally, connection-based protocol sockets may successfully
  438. * local_connect() only once; connectionless protocol sockets may use
  439. * local_connect() multiple times to change their association.
  440. * Connectionless sockets may dissolve the association by connecting to
  441. * an address with the sa_family member of sockaddr set to AF_UNSPEC.
  442. *
  443. * Input Parameters:
  444. * psock Pointer to a socket structure initialized by psock_socket()
  445. * addr Server address (form depends on type of socket)
  446. * addrlen Length of actual 'addr'
  447. *
  448. * Returned Value:
  449. * 0 on success; a negated errno value on failue. See connect() for the
  450. * list of appropriate errno values to be returned.
  451. *
  452. ****************************************************************************/
  453. static int local_connect(FAR struct socket *psock,
  454. FAR const struct sockaddr *addr, socklen_t addrlen)
  455. {
  456. /* Verify that a valid address has been provided */
  457. if (addr->sa_family != AF_LOCAL || addrlen < sizeof(sa_family_t))
  458. {
  459. return -EBADF;
  460. }
  461. /* Perform the connection depending on the protocol type */
  462. switch (psock->s_type)
  463. {
  464. #ifdef CONFIG_NET_LOCAL_STREAM
  465. case SOCK_STREAM:
  466. {
  467. /* Verify that the socket is not already connected */
  468. if (_SS_ISCONNECTED(psock->s_flags))
  469. {
  470. return -EISCONN;
  471. }
  472. /* It's not... Connect to the local Unix domain server */
  473. return psock_local_connect(psock, addr);
  474. }
  475. break;
  476. #endif /* CONFIG_NET_LOCAL_STREAM */
  477. #ifdef CONFIG_NET_LOCAL_DGRAM
  478. case SOCK_DGRAM:
  479. {
  480. /* Perform the datagram connection logic */
  481. #warning Missing logic
  482. return -ENOSYS;
  483. }
  484. break;
  485. #endif /* CONFIG_NET_LOCAL_DGRAM */
  486. default:
  487. return -EBADF;
  488. }
  489. }
  490. /****************************************************************************
  491. * Name: local_accept
  492. *
  493. * Description:
  494. * The pkt_accept function is used with connection-based socket types
  495. * (SOCK_STREAM, SOCK_SEQPACKET and SOCK_RDM). It extracts the first
  496. * connection request on the queue of pending connections, creates a new
  497. * connected socket with mostly the same properties as 'sockfd', and
  498. * allocates a new socket descriptor for the socket, which is returned. The
  499. * newly created socket is no longer in the listening state. The original
  500. * socket 'sockfd' is unaffected by this call. Per file descriptor flags
  501. * are not inherited across an pkt_accept.
  502. *
  503. * The 'sockfd' argument is a socket descriptor that has been created with
  504. * socket(), bound to a local address with bind(), and is listening for
  505. * connections after a call to listen().
  506. *
  507. * On return, the 'addr' structure is filled in with the address of the
  508. * connecting entity. The 'addrlen' argument initially contains the size
  509. * of the structure pointed to by 'addr'; on return it will contain the
  510. * actual length of the address returned.
  511. *
  512. * If no pending connections are present on the queue, and the socket is
  513. * not marked as non-blocking, pkt_accept blocks the caller until a
  514. * connection is present. If the socket is marked non-blocking and no
  515. * pending connections are present on the queue, pkt_accept returns
  516. * EAGAIN.
  517. *
  518. * Input Parameters:
  519. * psock Reference to the listening socket structure
  520. * addr Receives the address of the connecting client
  521. * addrlen Input: allocated size of 'addr', Return: returned size of 'addr'
  522. * newsock Location to return the accepted socket information.
  523. *
  524. * Returned Value:
  525. * Returns 0 (OK) on success. On failure, it returns a negated errno
  526. * value. See accept() for a desrciption of the approriate error value.
  527. *
  528. * Assumptions:
  529. * The network is locked.
  530. *
  531. ****************************************************************************/
  532. #ifndef CONFIG_NET_LOCAL_STREAM
  533. static int local_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
  534. FAR socklen_t *addrlen, FAR struct socket *newsock)
  535. {
  536. return -EAFNOSUPPORT;
  537. }
  538. #endif
  539. /****************************************************************************
  540. * Name: local_poll
  541. *
  542. * Description:
  543. * The standard poll() operation redirects operations on socket descriptors
  544. * to local_poll which, indiectly, calls to function.
  545. *
  546. * Input Parameters:
  547. * psock - An instance of the internal socket structure.
  548. * fds - The structure describing the events to be monitored, OR NULL if
  549. * this is a request to stop monitoring events.
  550. * setup - true: Setup up the poll; false: Teardown the poll
  551. *
  552. * Returned Value:
  553. * 0: Success; Negated errno on failure
  554. *
  555. ****************************************************************************/
  556. #ifndef CONFIG_DISABLE_POLL
  557. static int local_poll(FAR struct socket *psock, FAR struct pollfd *fds,
  558. bool setup)
  559. {
  560. #ifndef HAVE_LOCAL_POLL
  561. return -ENOSYS;
  562. #else
  563. /* Check if we are setting up or tearing down the poll */
  564. if (setup)
  565. {
  566. /* Perform the TCP/IP poll() setup */
  567. return local_pollsetup(psock, fds);
  568. }
  569. else
  570. {
  571. /* Perform the TCP/IP poll() teardown */
  572. return local_pollteardown(psock, fds);
  573. }
  574. #endif /* HAVE_LOCAL_POLL */
  575. }
  576. #endif /* !CONFIG_DISABLE_POLL */
  577. /****************************************************************************
  578. * Name: local_send
  579. *
  580. * Description:
  581. * Implements the send() operation for the case of the local, Unix socket.
  582. *
  583. * Input Parameters:
  584. * psock An instance of the internal socket structure.
  585. * buf Data to send
  586. * len Length of data to send
  587. * flags Send flags
  588. *
  589. * Returned Value:
  590. * On success, returns the number of characters sent. On error, a negated
  591. * errno value is returned (see send() for the list of appropriate error
  592. * values.
  593. *
  594. ****************************************************************************/
  595. static ssize_t local_send(FAR struct socket *psock, FAR const void *buf,
  596. size_t len, int flags)
  597. {
  598. ssize_t ret;
  599. switch (psock->s_type)
  600. {
  601. #ifdef CONFIG_NET_LOCAL_STREAM
  602. case SOCK_STREAM:
  603. {
  604. /* Local TCP packet send */
  605. ret = psock_local_send(psock, buf, len, flags);
  606. }
  607. break;
  608. #endif /* CONFIG_NET_LOCAL_STREAM */
  609. #ifdef CONFIG_NET_LOCAL_DGRAM
  610. case SOCK_DGRAM:
  611. {
  612. /* Local UDP packet send */
  613. #warning Missing logic
  614. ret = -ENOSYS;
  615. }
  616. break;
  617. #endif /* CONFIG_NET_LOCAL_DGRAM */
  618. default:
  619. {
  620. /* EDESTADDRREQ. Signifies that the socket is not connection-mode
  621. * and no peer address is set.
  622. */
  623. ret = -EDESTADDRREQ;
  624. }
  625. break;
  626. }
  627. return ret;
  628. }
  629. /****************************************************************************
  630. * Name: local_sendto
  631. *
  632. * Description:
  633. * Implements the sendto() operation for the case of the local, Unix socket.
  634. *
  635. * Input Parameters:
  636. * psock A pointer to a NuttX-specific, internal socket structure
  637. * buf Data to send
  638. * len Length of data to send
  639. * flags Send flags
  640. * to Address of recipient
  641. * tolen The length of the address structure
  642. *
  643. * Returned Value:
  644. * On success, returns the number of characters sent. On error, a negated
  645. * errno value is returned (see send_to() for the list of appropriate error
  646. * values.
  647. *
  648. ****************************************************************************/
  649. ssize_t local_sendto(FAR struct socket *psock, FAR const void *buf,
  650. size_t len, int flags, FAR const struct sockaddr *to,
  651. socklen_t tolen)
  652. {
  653. ssize_t nsent;
  654. /* Verify that a valid address has been provided */
  655. if (to->sa_family != AF_LOCAL || tolen < sizeof(sa_family_t))
  656. {
  657. nerr("ERROR: Unrecognized address family: %d\n",
  658. to->sa_family);
  659. return -EAFNOSUPPORT;
  660. }
  661. #ifdef CONFIG_NET_LOCAL_DGRAM
  662. /* If this is a connected socket, then return EISCONN */
  663. if (psock->s_type != SOCK_DGRAM)
  664. {
  665. nerr("ERROR: Connected socket\n");
  666. return -EISCONN;
  667. }
  668. /* Now handle the local UDP sendto() operation */
  669. nsent = psock_local_sendto(psock, buf, len, flags, to, tolen);
  670. #else
  671. nsent = -EISCONN;
  672. #endif /* CONFIG_NET_LOCAL_DGRAM */
  673. return nsent;
  674. }
  675. /****************************************************************************
  676. * Name: local_close
  677. *
  678. * Description:
  679. * Performs the close operation on a local, Unix socket instance
  680. *
  681. * Input Parameters:
  682. * psock Socket instance
  683. *
  684. * Returned Value:
  685. * 0 on success; a negated errno value is returned on any failure.
  686. *
  687. * Assumptions:
  688. *
  689. ****************************************************************************/
  690. static int local_close(FAR struct socket *psock)
  691. {
  692. /* Perform some pre-close operations for the local address type */
  693. switch (psock->s_type)
  694. {
  695. #if defined(CONFIG_NET_LOCAL_STREAM) || defined(CONFIG_NET_LOCAL_DGRAM)
  696. #ifdef CONFIG_NET_LOCAL_STREAM
  697. case SOCK_STREAM:
  698. #endif
  699. #ifdef CONFIG_NET_LOCAL_DGRAM
  700. case SOCK_DGRAM:
  701. #endif
  702. {
  703. FAR struct local_conn_s *conn = psock->s_conn;
  704. /* Is this the last reference to the connection structure (there
  705. * could be more if the socket was dup'ed).
  706. */
  707. if (conn->lc_crefs <= 1)
  708. {
  709. conn->lc_crefs = 0;
  710. local_release(conn);
  711. }
  712. else
  713. {
  714. /* No.. Just decrement the reference count */
  715. conn->lc_crefs--;
  716. }
  717. return OK;
  718. }
  719. #endif /* CONFIG_NET_LOCAL_STREAM || CONFIG_NET_LOCAL_DGRAM */
  720. default:
  721. return -EBADF;
  722. }
  723. }
  724. /****************************************************************************
  725. * Public Functions
  726. ****************************************************************************/
  727. #endif /* CONFIG_NET_LOCAL */