92 * Kernel component of socket creation.
93 *
94 * The socket library determines which version number to use.
95 * First the library calls this with a NULL devpath. If this fails
96 * to find a transport (using solookup) the library will look in /etc/netconfig
97 * for the appropriate transport. If one is found it will pass in the
98 * devpath for the kernel to use.
99 */
100 int
101 so_socket(int family, int type_w_flags, int protocol, char *devpath,
102 int version)
103 {
104 struct sonode *so;
105 vnode_t *vp;
106 struct file *fp;
107 int fd;
108 int error;
109 int type;
110
111 type = type_w_flags & SOCK_TYPE_MASK;
112 if (devpath != NULL) {
113 char *buf;
114 size_t kdevpathlen = 0;
115
116 buf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
117 if ((error = copyinstr(devpath, buf,
118 MAXPATHLEN, &kdevpathlen)) != 0) {
119 kmem_free(buf, MAXPATHLEN);
120 return (set_errno(error));
121 }
122 so = socket_create(family, type, protocol, buf, NULL,
123 SOCKET_SLEEP, version, CRED(), &error);
124 kmem_free(buf, MAXPATHLEN);
125 } else {
126 so = socket_create(family, type, protocol, NULL, NULL,
127 SOCKET_SLEEP, version, CRED(), &error);
128 }
129 if (so == NULL)
130 return (set_errno(error));
131
132 /* Allocate a file descriptor for the socket */
133 vp = SOTOV(so);
134 if (error = falloc(vp, FWRITE|FREAD, &fp, &fd)) {
135 (void) socket_close(so, 0, CRED());
136 socket_destroy(so);
137 return (set_errno(error));
138 }
139
140 /*
141 * Now fill in the entries that falloc reserved
142 */
143 mutex_exit(&fp->f_tlock);
144 setf(fd, fp);
145 if ((type_w_flags & SOCK_CLOEXEC) != 0) {
146 f_setfd(fd, FD_CLOEXEC);
147 }
148
149 return (fd);
150 }
151
152 /*
153 * Map from a file descriptor to a socket node.
154 * Returns with the file descriptor held i.e. the caller has to
155 * use releasef when done with the file descriptor.
156 */
157 struct sonode *
158 getsonode(int sock, int *errorp, file_t **fpp)
159 {
160 file_t *fp;
161 vnode_t *vp;
162 struct sonode *so;
471
472 /* wait for so2 being SS_CONNECTED ignoring signals */
473 mutex_enter(&so2->so_lock);
474 error = sowaitconnected(so2, 0, 1);
475 mutex_exit(&so2->so_lock);
476 if (error != 0) {
477 (void) socket_close(nso, 0, CRED());
478 socket_destroy(nso);
479 eprintsoline(so2, error);
480 goto done;
481 }
482
483 nvp = SOTOV(nso);
484 if (error = falloc(nvp, FWRITE|FREAD, &nfp, &nfd)) {
485 (void) socket_close(nso, 0, CRED());
486 socket_destroy(nso);
487 eprintsoline(nso, error);
488 goto done;
489 }
490 /*
491 * fill in the entries that falloc reserved
492 */
493 mutex_exit(&nfp->f_tlock);
494 setf(nfd, nfp);
495
496 releasef(svs[0]);
497 releasef(svs[1]);
498
499 /*
500 * If FD_CLOEXEC was set on the filedescriptor we're
501 * swapping out, we should set it on the new one too.
502 */
503 VERIFY(f_getfd_error(svs[0], &orig_flags) == 0);
504 if (orig_flags & FD_CLOEXEC) {
505 f_setfd(nfd, FD_CLOEXEC);
506 }
507
508 /*
509 * The socketpair library routine will close the original
510 * svs[0] when this code passes out a different file
511 * descriptor.
512 */
513 svs[0] = nfd;
514
515 if (copyout(svs, sv, sizeof (svs))) {
516 (void) closeandsetf(nfd, NULL);
517 eprintline(EFAULT);
518 return (set_errno(EFAULT));
519 }
520 }
521 return (0);
522
523 done:
|
92 * Kernel component of socket creation.
93 *
94 * The socket library determines which version number to use.
95 * First the library calls this with a NULL devpath. If this fails
96 * to find a transport (using solookup) the library will look in /etc/netconfig
97 * for the appropriate transport. If one is found it will pass in the
98 * devpath for the kernel to use.
99 */
100 int
101 so_socket(int family, int type_w_flags, int protocol, char *devpath,
102 int version)
103 {
104 struct sonode *so;
105 vnode_t *vp;
106 struct file *fp;
107 int fd;
108 int error;
109 int type;
110
111 type = type_w_flags & SOCK_TYPE_MASK;
112 type_w_flags &= ~SOCK_TYPE_MASK;
113 if (type_w_flags & ~(SOCK_CLOEXEC|SOCK_NDELAY|SOCK_NONBLOCK))
114 return (set_errno(EINVAL));
115
116 if (devpath != NULL) {
117 char *buf;
118 size_t kdevpathlen = 0;
119
120 buf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
121 if ((error = copyinstr(devpath, buf,
122 MAXPATHLEN, &kdevpathlen)) != 0) {
123 kmem_free(buf, MAXPATHLEN);
124 return (set_errno(error));
125 }
126 so = socket_create(family, type, protocol, buf, NULL,
127 SOCKET_SLEEP, version, CRED(), &error);
128 kmem_free(buf, MAXPATHLEN);
129 } else {
130 so = socket_create(family, type, protocol, NULL, NULL,
131 SOCKET_SLEEP, version, CRED(), &error);
132 }
133 if (so == NULL)
134 return (set_errno(error));
135
136 /* Allocate a file descriptor for the socket */
137 vp = SOTOV(so);
138 if (error = falloc(vp, FWRITE|FREAD, &fp, &fd)) {
139 (void) socket_close(so, 0, CRED());
140 socket_destroy(so);
141 return (set_errno(error));
142 }
143
144 /*
145 * Now fill in the entries that falloc reserved
146 */
147 if (type_w_flags & SOCK_NDELAY) {
148 so->so_state |= SS_NDELAY;
149 fp->f_flag |= FNDELAY;
150 }
151 if (type_w_flags & SOCK_NONBLOCK) {
152 so->so_state |= SS_NONBLOCK;
153 fp->f_flag |= FNONBLOCK;
154 }
155 mutex_exit(&fp->f_tlock);
156 setf(fd, fp);
157 if ((type_w_flags & SOCK_CLOEXEC) != 0) {
158 f_setfd(fd, FD_CLOEXEC);
159 }
160
161 return (fd);
162 }
163
164 /*
165 * Map from a file descriptor to a socket node.
166 * Returns with the file descriptor held i.e. the caller has to
167 * use releasef when done with the file descriptor.
168 */
169 struct sonode *
170 getsonode(int sock, int *errorp, file_t **fpp)
171 {
172 file_t *fp;
173 vnode_t *vp;
174 struct sonode *so;
483
484 /* wait for so2 being SS_CONNECTED ignoring signals */
485 mutex_enter(&so2->so_lock);
486 error = sowaitconnected(so2, 0, 1);
487 mutex_exit(&so2->so_lock);
488 if (error != 0) {
489 (void) socket_close(nso, 0, CRED());
490 socket_destroy(nso);
491 eprintsoline(so2, error);
492 goto done;
493 }
494
495 nvp = SOTOV(nso);
496 if (error = falloc(nvp, FWRITE|FREAD, &nfp, &nfd)) {
497 (void) socket_close(nso, 0, CRED());
498 socket_destroy(nso);
499 eprintsoline(nso, error);
500 goto done;
501 }
502 /*
503 * copy over FNONBLOCK and FNDELAY flags should they exist
504 */
505 if (so1->so_state & SS_NONBLOCK)
506 nfp->f_flag |= FNONBLOCK;
507 if (so1->so_state & SS_NDELAY)
508 nfp->f_flag |= FNDELAY;
509
510 /*
511 * fill in the entries that falloc reserved
512 */
513 mutex_exit(&nfp->f_tlock);
514 setf(nfd, nfp);
515
516 /*
517 * get the original flags before we release
518 */
519 VERIFY(f_getfd_error(svs[0], &orig_flags) == 0);
520
521 releasef(svs[0]);
522 releasef(svs[1]);
523
524 /*
525 * If FD_CLOEXEC was set on the filedescriptor we're
526 * swapping out, we should set it on the new one too.
527 */
528 if (orig_flags & FD_CLOEXEC) {
529 f_setfd(nfd, FD_CLOEXEC);
530 }
531
532 /*
533 * The socketpair library routine will close the original
534 * svs[0] when this code passes out a different file
535 * descriptor.
536 */
537 svs[0] = nfd;
538
539 if (copyout(svs, sv, sizeof (svs))) {
540 (void) closeandsetf(nfd, NULL);
541 eprintline(EFAULT);
542 return (set_errno(EFAULT));
543 }
544 }
545 return (0);
546
547 done:
|