This source file includes following definitions.
- dprintf
- min
- sockaddr_un_printk
- unix_lock
- unix_unlock
- unix_proto_listen
- unix_proto_setsockopt
- unix_proto_getsockopt
- unix_proto_sendto
- unix_proto_recvfrom
- unix_proto_shutdown
- unix_proto_send
- unix_proto_recv
- unix_data_lookup
- unix_data_alloc
- unix_data_ref
- unix_data_deref
- unix_proto_create
- unix_proto_dup
- unix_proto_release
- unix_proto_bind
- unix_proto_connect
- unix_proto_socketpair
- unix_proto_accept
- unix_proto_getname
- unix_proto_read
- unix_proto_write
- unix_proto_select
- unix_proto_ioctl
- unix_open
- unix_close
- unix_ioctl
- unix_proto_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 #include <linux/config.h>
31 #include <linux/kernel.h>
32 #include <linux/major.h>
33 #include <linux/signal.h>
34 #include <linux/sched.h>
35 #include <linux/errno.h>
36 #include <linux/string.h>
37 #include <linux/stat.h>
38 #include <linux/socket.h>
39 #include <linux/un.h>
40 #include <linux/fcntl.h>
41 #include <linux/termios.h>
42 #include <linux/sockios.h>
43 #include <linux/net.h>
44 #include <linux/fs.h>
45 #include <linux/ddi.h>
46 #include <linux/malloc.h>
47
48 #include <asm/system.h>
49 #include <asm/segment.h>
50
51 #include <stdarg.h>
52
53 #include "unix.h"
54
55 struct unix_proto_data unix_datas[NSOCKETS];
56 static int unix_debug = 0;
57
58
59 static int unix_proto_create(struct socket *sock, int protocol);
60 static int unix_proto_dup(struct socket *newsock, struct socket *oldsock);
61 static int unix_proto_release(struct socket *sock, struct socket *peer);
62 static int unix_proto_bind(struct socket *sock, struct sockaddr *umyaddr,
63 int sockaddr_len);
64 static int unix_proto_connect(struct socket *sock, struct sockaddr *uservaddr,
65 int sockaddr_len, int flags);
66 static int unix_proto_socketpair(struct socket *sock1, struct socket *sock2);
67 static int unix_proto_accept(struct socket *sock, struct socket *newsock,
68 int flags);
69 static int unix_proto_getname(struct socket *sock, struct sockaddr *usockaddr,
70 int *usockaddr_len, int peer);
71 static int unix_proto_read(struct socket *sock, char *ubuf, int size,
72 int nonblock);
73 static int unix_proto_write(struct socket *sock, char *ubuf, int size,
74 int nonblock);
75 static int unix_proto_select(struct socket *sock, int sel_type, select_table * wait);
76 static int unix_proto_ioctl(struct socket *sock, unsigned int cmd,
77 unsigned long arg);
78 static int unix_proto_listen(struct socket *sock, int backlog);
79 static int unix_proto_send(struct socket *sock, void *buff, int len,
80 int nonblock, unsigned flags);
81 static int unix_proto_recv(struct socket *sock, void *buff, int len,
82 int nonblock, unsigned flags);
83 static int unix_proto_sendto(struct socket *sock, void *buff, int len,
84 int nonblock, unsigned flags,
85 struct sockaddr *addr, int addr_len);
86 static int unix_proto_recvfrom(struct socket *sock, void *buff, int len,
87 int nonblock, unsigned flags,
88 struct sockaddr *addr, int *addr_len);
89
90 static int unix_proto_shutdown(struct socket *sock, int how);
91
92 static int unix_proto_setsockopt(struct socket *sock, int level, int optname,
93 char *optval, int optlen);
94 static int unix_proto_getsockopt(struct socket *sock, int level, int optname,
95 char *optval, int *optlen);
96
97
98 static void
99 dprintf(int level, char *fmt, ...)
100 {
101 va_list args;
102 char *buff;
103 extern int vsprintf(char * buf, const char * fmt, va_list args);
104
105 if (level != unix_debug) return;
106
107 buff = (char *) kmalloc(256, GFP_KERNEL);
108 if (buff != NULL) {
109 va_start(args, fmt);
110 vsprintf(buff, fmt, args);
111 va_end(args);
112 printk(buff);
113 kfree(buff);
114 }
115 }
116
117
118 static inline int
119 min(int a, int b)
120 {
121 if (a < b) return(a);
122 return(b);
123 }
124
125
126 void
127 sockaddr_un_printk(struct sockaddr_un *sockun, int sockaddr_len)
128 {
129 char buf[sizeof(sockun->sun_path) + 1];
130
131 if (unix_debug == 0) return;
132
133 sockaddr_len -= UN_PATH_OFFSET;
134 if (sockun->sun_family != AF_UNIX)
135 printk("UNIX: Badd addr family %d>\n", sockun->sun_family);
136 else if (sockaddr_len <= 0 || sockaddr_len >= sizeof(buf))
137 printk("UNIX: Bad addr len %d>\n", sockaddr_len);
138 else {
139 memcpy(buf, sockun->sun_path, sockaddr_len);
140 buf[sockaddr_len] = '\0';
141 printk("\"%s\"[%lu]\n", buf, sockaddr_len + UN_PATH_OFFSET);
142 }
143 }
144
145
146
147
148
149
150
151
152
153
154
155 void unix_lock(struct unix_proto_data *upd)
156 {
157 while (upd->lock_flag)
158 sleep_on(&upd->wait);
159 upd->lock_flag = 1;
160 }
161
162
163 void unix_unlock(struct unix_proto_data *upd)
164 {
165 upd->lock_flag = 0;
166 wake_up(&upd->wait);
167 }
168
169
170 static int
171 unix_proto_listen(struct socket *sock, int backlog)
172 {
173 return(0);
174 }
175
176
177 static int
178 unix_proto_setsockopt(struct socket *sock, int level, int optname,
179 char *optval, int optlen)
180 {
181 return(-EOPNOTSUPP);
182 }
183
184
185 static int
186 unix_proto_getsockopt(struct socket *sock, int level, int optname,
187 char *optval, int *optlen)
188 {
189 return(-EOPNOTSUPP);
190 }
191
192 static int
193 unix_proto_sendto(struct socket *sock, void *buff, int len, int nonblock,
194 unsigned flags, struct sockaddr *addr, int addr_len)
195 {
196 return(-EOPNOTSUPP);
197 }
198
199 static int
200 unix_proto_recvfrom(struct socket *sock, void *buff, int len, int nonblock,
201 unsigned flags, struct sockaddr *addr, int *addr_len)
202 {
203 return(-EOPNOTSUPP);
204 }
205
206
207 static int
208 unix_proto_shutdown(struct socket *sock, int how)
209 {
210 return(-EOPNOTSUPP);
211 }
212
213
214
215 static int
216 unix_proto_send(struct socket *sock, void *buff, int len, int nonblock,
217 unsigned flags)
218 {
219 if (flags != 0) return(-EINVAL);
220 return(unix_proto_write(sock, (char *) buff, len, nonblock));
221 }
222
223
224
225 static int
226 unix_proto_recv(struct socket *sock, void *buff, int len, int nonblock,
227 unsigned flags)
228 {
229 if (flags != 0) return(-EINVAL);
230 return(unix_proto_read(sock, (char *) buff, len, nonblock));
231 }
232
233
234 static struct unix_proto_data *
235 unix_data_lookup(struct sockaddr_un *sockun, int sockaddr_len,
236 struct inode *inode)
237 {
238 struct unix_proto_data *upd;
239
240 for(upd = unix_datas; upd <= last_unix_data; ++upd) {
241 if (upd->refcnt > 0 && upd->socket &&
242 upd->socket->state == SS_UNCONNECTED &&
243 upd->sockaddr_un.sun_family == sockun->sun_family &&
244 upd->inode == inode) return(upd);
245 }
246 return(NULL);
247 }
248
249
250 static struct unix_proto_data *
251 unix_data_alloc(void)
252 {
253 struct unix_proto_data *upd;
254
255 cli();
256 for(upd = unix_datas; upd <= last_unix_data; ++upd) {
257 if (!upd->refcnt) {
258 upd->refcnt = -1;
259 sti();
260 upd->socket = NULL;
261 upd->sockaddr_len = 0;
262 upd->sockaddr_un.sun_family = 0;
263 upd->buf = NULL;
264 upd->bp_head = upd->bp_tail = 0;
265 upd->inode = NULL;
266 upd->peerupd = NULL;
267 return(upd);
268 }
269 }
270 sti();
271 return(NULL);
272 }
273
274
275 static inline void
276 unix_data_ref(struct unix_proto_data *upd)
277 {
278 if (!upd) {
279 dprintf(1, "UNIX: data_ref: upd = NULL\n");
280 return;
281 }
282 ++upd->refcnt;
283 dprintf(1, "UNIX: data_ref: refing data 0x%x(%d)\n", upd, upd->refcnt);
284 }
285
286
287 static void
288 unix_data_deref(struct unix_proto_data *upd)
289 {
290 if (!upd) {
291 dprintf(1, "UNIX: data_deref: upd = NULL\n");
292 return;
293 }
294 if (upd->refcnt == 1) {
295 dprintf(1, "UNIX: data_deref: releasing data 0x%x\n", upd);
296 if (upd->buf) {
297 free_page((unsigned long)upd->buf);
298 upd->buf = NULL;
299 upd->bp_head = upd->bp_tail = 0;
300 }
301 }
302 --upd->refcnt;
303 }
304
305
306
307
308
309
310 static int
311 unix_proto_create(struct socket *sock, int protocol)
312 {
313 struct unix_proto_data *upd;
314
315 dprintf(1, "UNIX: create: socket 0x%x, proto %d\n", sock, protocol);
316 if (protocol != 0) {
317 dprintf(1, "UNIX: create: protocol != 0\n");
318 return(-EINVAL);
319 }
320 if (!(upd = unix_data_alloc())) {
321 printk("UNIX: create: can't allocate buffer\n");
322 return(-ENOMEM);
323 }
324 if (!(upd->buf = (char*) get_free_page(GFP_USER))) {
325 printk("UNIX: create: can't get page!\n");
326 unix_data_deref(upd);
327 return(-ENOMEM);
328 }
329 upd->protocol = protocol;
330 upd->socket = sock;
331 UN_DATA(sock) = upd;
332 upd->refcnt = 1;
333 dprintf(1, "UNIX: create: allocated data 0x%x\n", upd);
334 return(0);
335 }
336
337
338 static int
339 unix_proto_dup(struct socket *newsock, struct socket *oldsock)
340 {
341 struct unix_proto_data *upd = UN_DATA(oldsock);
342
343 return(unix_proto_create(newsock, upd->protocol));
344 }
345
346
347 static int
348 unix_proto_release(struct socket *sock, struct socket *peer)
349 {
350 struct unix_proto_data *upd = UN_DATA(sock);
351
352 dprintf(1, "UNIX: release: socket 0x%x, unix_data 0x%x\n", sock, upd);
353 if (!upd) return(0);
354 if (upd->socket != sock) {
355 printk("UNIX: release: socket link mismatch!\n");
356 return(-EINVAL);
357 }
358 if (upd->inode) {
359 dprintf(1, "UNIX: release: releasing inode 0x%x\n", upd->inode);
360 iput(upd->inode);
361 upd->inode = NULL;
362 }
363 UN_DATA(sock) = NULL;
364 upd->socket = NULL;
365 if (upd->peerupd) unix_data_deref(upd->peerupd);
366 unix_data_deref(upd);
367 return(0);
368 }
369
370
371
372
373
374
375
376
377
378
379
380 static int
381 unix_proto_bind(struct socket *sock, struct sockaddr *umyaddr,
382 int sockaddr_len)
383 {
384 char fname[sizeof(((struct sockaddr_un *)0)->sun_path) + 1];
385 struct unix_proto_data *upd = UN_DATA(sock);
386 unsigned long old_fs;
387 int i;
388 int er;
389
390 dprintf(1, "UNIX: bind: socket 0x%x, len=%d\n", sock, sockaddr_len);
391 if (sockaddr_len <= UN_PATH_OFFSET ||
392 sockaddr_len > sizeof(struct sockaddr_un)) {
393 dprintf(1, "UNIX: bind: bad length %d\n", sockaddr_len);
394 return(-EINVAL);
395 }
396 if (upd->sockaddr_len || upd->inode) {
397 printk("UNIX: bind: already bound!\n");
398 return(-EINVAL);
399 }
400 er=verify_area(VERIFY_WRITE, umyaddr, sockaddr_len);
401 if(er)
402 return er;
403 memcpy_fromfs(&upd->sockaddr_un, umyaddr, sockaddr_len);
404 upd->sockaddr_un.sun_path[sockaddr_len-UN_PATH_OFFSET] = '\0';
405 if (upd->sockaddr_un.sun_family != AF_UNIX) {
406 dprintf(1, "UNIX: bind: family is %d, not AF_UNIX(%d)\n",
407 upd->sockaddr_un.sun_family, AF_UNIX);
408 return(-EINVAL);
409 }
410
411 memcpy(fname, upd->sockaddr_un.sun_path, sockaddr_len-UN_PATH_OFFSET);
412 fname[sockaddr_len-UN_PATH_OFFSET] = '\0';
413 old_fs = get_fs();
414 set_fs(get_ds());
415 i = do_mknod(fname, S_IFSOCK | S_IRWXUGO, 0);
416 if (i == -EEXIST)
417 i = -EADDRINUSE;
418 if (i == 0)
419 i = open_namei(fname, 0, S_IFSOCK, &upd->inode, NULL);
420 set_fs(old_fs);
421 if (i < 0) {
422 dprintf(1, "UNIX: bind: can't open socket %s\n", fname);
423 return(i);
424 }
425 upd->sockaddr_len = sockaddr_len;
426
427 dprintf(1, "UNIX: bind: bound socket address: ");
428 sockaddr_un_printk(&upd->sockaddr_un, upd->sockaddr_len);
429 dprintf(1, "to inode 0x%x\n", upd->inode);
430 return(0);
431 }
432
433
434
435
436
437
438
439 static int
440 unix_proto_connect(struct socket *sock, struct sockaddr *uservaddr,
441 int sockaddr_len, int flags)
442 {
443 char fname[sizeof(((struct sockaddr_un *)0)->sun_path) + 1];
444 struct sockaddr_un sockun;
445 struct unix_proto_data *serv_upd;
446 struct inode *inode;
447 unsigned long old_fs;
448 int i;
449 int er;
450
451 dprintf(1, "UNIX: connect: socket 0x%x, servlen=%d\n", sock, sockaddr_len);
452
453 if (sockaddr_len <= UN_PATH_OFFSET ||
454 sockaddr_len > sizeof(struct sockaddr_un)) {
455 dprintf(1, "UNIX: connect: bad length %d\n", sockaddr_len);
456 return(-EINVAL);
457 }
458 if (sock->state == SS_CONNECTING) return(-EINPROGRESS);
459 if (sock->state == SS_CONNECTED) return(-EISCONN);
460
461 er=verify_area(VERIFY_READ, uservaddr, sockaddr_len);
462 if(er)
463 return er;
464 memcpy_fromfs(&sockun, uservaddr, sockaddr_len);
465 sockun.sun_path[sockaddr_len-UN_PATH_OFFSET] = '\0';
466 if (sockun.sun_family != AF_UNIX) {
467 dprintf(1, "UNIX: connect: family is %d, not AF_UNIX(%d)\n",
468 sockun.sun_family, AF_UNIX);
469 return(-EINVAL);
470 }
471
472
473
474
475
476
477
478 memcpy(fname, sockun.sun_path, sockaddr_len-UN_PATH_OFFSET);
479 fname[sockaddr_len-UN_PATH_OFFSET] = '\0';
480 old_fs = get_fs();
481 set_fs(get_ds());
482 i = open_namei(fname, 0, S_IFSOCK, &inode, NULL);
483 set_fs(old_fs);
484 if (i < 0) {
485 dprintf(1, "UNIX: connect: can't open socket %s\n", fname);
486 return(i);
487 }
488 serv_upd = unix_data_lookup(&sockun, sockaddr_len, inode);
489 iput(inode);
490 if (!serv_upd) {
491 dprintf(1, "UNIX: connect: can't locate peer %s at inode 0x%x\n",
492 fname, inode);
493 return(-EINVAL);
494 }
495 if ((i = sock_awaitconn(sock, serv_upd->socket)) < 0) {
496 dprintf(1, "UNIX: connect: can't await connection\n");
497 return(i);
498 }
499 if (sock->conn) {
500 unix_data_ref(UN_DATA(sock->conn));
501 UN_DATA(sock)->peerupd = UN_DATA(sock->conn);
502 }
503 return(0);
504 }
505
506
507
508
509
510
511
512
513 static int
514 unix_proto_socketpair(struct socket *sock1, struct socket *sock2)
515 {
516 struct unix_proto_data *upd1 = UN_DATA(sock1), *upd2 = UN_DATA(sock2);
517
518 unix_data_ref(upd1);
519 unix_data_ref(upd2);
520 upd1->peerupd = upd2;
521 upd2->peerupd = upd1;
522 return(0);
523 }
524
525
526
527 static int
528 unix_proto_accept(struct socket *sock, struct socket *newsock, int flags)
529 {
530 struct socket *clientsock;
531
532 dprintf(1, "UNIX: accept: socket 0x%x accepted via socket 0x%x\n",
533 sock, newsock);
534
535
536
537
538
539 while(!(clientsock = sock->iconn)) {
540 if (flags & O_NONBLOCK) return(-EAGAIN);
541 interruptible_sleep_on(sock->wait);
542 if (current->signal & ~current->blocked) {
543 dprintf(1, "UNIX: accept: sleep was interrupted\n");
544 return(-ERESTARTSYS);
545 }
546 }
547
548
549
550
551
552 sock->iconn = clientsock->next;
553 clientsock->next = NULL;
554 newsock->conn = clientsock;
555 clientsock->conn = newsock;
556 clientsock->state = SS_CONNECTED;
557 newsock->state = SS_CONNECTED;
558 unix_data_ref(UN_DATA(clientsock));
559 UN_DATA(newsock)->peerupd = UN_DATA(clientsock);
560 UN_DATA(newsock)->sockaddr_un = UN_DATA(sock)->sockaddr_un;
561 UN_DATA(newsock)->sockaddr_len = UN_DATA(sock)->sockaddr_len;
562 wake_up_interruptible(clientsock->wait);
563 return(0);
564 }
565
566
567
568 static int
569 unix_proto_getname(struct socket *sock, struct sockaddr *usockaddr,
570 int *usockaddr_len, int peer)
571 {
572 struct unix_proto_data *upd;
573 int len;
574 int er;
575
576 dprintf(1, "UNIX: getname: socket 0x%x for %s\n", sock, peer?"peer":"self");
577 if (peer) {
578 if (sock->state != SS_CONNECTED) {
579 dprintf(1, "UNIX: getname: socket not connected\n");
580 return(-EINVAL);
581 }
582 upd = UN_DATA(sock->conn);
583 } else
584 upd = UN_DATA(sock);
585
586 er=verify_area(VERIFY_WRITE, usockaddr_len, sizeof(*usockaddr_len));
587 if(er)
588 return er;
589 if ((len = get_fs_long(usockaddr_len)) <= 0) return(-EINVAL);
590 if (len > upd->sockaddr_len) len = upd->sockaddr_len;
591 if (len) {
592 er=verify_area(VERIFY_WRITE, usockaddr, len);
593 if(er)
594 return er;
595 memcpy_tofs(usockaddr, &upd->sockaddr_un, len);
596 }
597 put_fs_long(len, usockaddr_len);
598 return(0);
599 }
600
601
602
603 static int
604 unix_proto_read(struct socket *sock, char *ubuf, int size, int nonblock)
605 {
606 struct unix_proto_data *upd;
607 int todo, avail;
608 int er;
609
610 if ((todo = size) <= 0) return(0);
611 upd = UN_DATA(sock);
612 while(!(avail = UN_BUF_AVAIL(upd))) {
613 if (sock->state != SS_CONNECTED) {
614 dprintf(1, "UNIX: read: socket not connected\n");
615 return((sock->state == SS_DISCONNECTING) ? 0 : -EINVAL);
616 }
617 dprintf(1, "UNIX: read: no data available...\n");
618 if (nonblock) return(-EAGAIN);
619 interruptible_sleep_on(sock->wait);
620 if (current->signal & ~current->blocked) {
621 dprintf(1, "UNIX: read: interrupted\n");
622 return(-ERESTARTSYS);
623 }
624 }
625
626
627
628
629
630
631 unix_lock(upd);
632 do {
633 int part, cando;
634
635 if (avail <= 0) {
636 printk("UNIX: read: AVAIL IS NEGATIVE!!!\n");
637 send_sig(SIGKILL, current, 1);
638 return(-EPIPE);
639 }
640
641 if ((cando = todo) > avail) cando = avail;
642 if (cando >(part = BUF_SIZE - upd->bp_tail)) cando = part;
643 dprintf(1, "UNIX: read: avail=%d, todo=%d, cando=%d\n",
644 avail, todo, cando);
645 if((er=verify_area(VERIFY_WRITE,ubuf,cando))<0)
646 {
647 unix_unlock(upd);
648 return er;
649 }
650 memcpy_tofs(ubuf, upd->buf + upd->bp_tail, cando);
651 upd->bp_tail =(upd->bp_tail + cando) &(BUF_SIZE-1);
652 ubuf += cando;
653 todo -= cando;
654 if (sock->state == SS_CONNECTED)
655 wake_up_interruptible(sock->conn->wait);
656 avail = UN_BUF_AVAIL(upd);
657 } while(todo && avail);
658 unix_unlock(upd);
659 return(size - todo);
660 }
661
662
663
664
665
666
667
668 static int
669 unix_proto_write(struct socket *sock, char *ubuf, int size, int nonblock)
670 {
671 struct unix_proto_data *pupd;
672 int todo, space;
673 int er;
674
675 if ((todo = size) <= 0) return(0);
676 if (sock->state != SS_CONNECTED) {
677 dprintf(1, "UNIX: write: socket not connected\n");
678 if (sock->state == SS_DISCONNECTING) {
679 send_sig(SIGPIPE, current, 1);
680 return(-EPIPE);
681 }
682 return(-EINVAL);
683 }
684 pupd = UN_DATA(sock)->peerupd;
685
686 while(!(space = UN_BUF_SPACE(pupd))) {
687 dprintf(1, "UNIX: write: no space left...\n");
688 if (nonblock) return(-EAGAIN);
689 interruptible_sleep_on(sock->wait);
690 if (current->signal & ~current->blocked) {
691 dprintf(1, "UNIX: write: interrupted\n");
692 return(-ERESTARTSYS);
693 }
694 if (sock->state == SS_DISCONNECTING) {
695 dprintf(1, "UNIX: write: disconnected(SIGPIPE)\n");
696 send_sig(SIGPIPE, current, 1);
697 return(-EPIPE);
698 }
699 }
700
701
702
703
704
705
706 unix_lock(pupd);
707
708 do {
709 int part, cando;
710
711 if (space <= 0) {
712 printk("UNIX: write: SPACE IS NEGATIVE!!!\n");
713 send_sig(SIGKILL, current, 1);
714 return(-EPIPE);
715 }
716
717
718
719
720
721 if (sock->state == SS_DISCONNECTING) {
722 send_sig(SIGPIPE, current, 1);
723 unix_unlock(pupd);
724 return(-EPIPE);
725 }
726 if ((cando = todo) > space) cando = space;
727 if (cando >(part = BUF_SIZE - pupd->bp_head)) cando = part;
728 dprintf(1, "UNIX: write: space=%d, todo=%d, cando=%d\n",
729 space, todo, cando);
730 er=verify_area(VERIFY_READ, ubuf, cando);
731 if(er)
732 {
733 unix_unlock(pupd);
734 return er;
735 }
736 memcpy_fromfs(pupd->buf + pupd->bp_head, ubuf, cando);
737 pupd->bp_head =(pupd->bp_head + cando) &(BUF_SIZE-1);
738 ubuf += cando;
739 todo -= cando;
740 if (sock->state == SS_CONNECTED)
741 wake_up_interruptible(sock->conn->wait);
742 space = UN_BUF_SPACE(pupd);
743 } while(todo && space);
744 unix_unlock(pupd);
745 return(size - todo);
746 }
747
748
749 static int
750 unix_proto_select(struct socket *sock, int sel_type, select_table * wait)
751 {
752 struct unix_proto_data *upd, *peerupd;
753
754
755 if (sock->flags & SO_ACCEPTCON) {
756 if (sel_type == SEL_IN) {
757 dprintf(1, "UNIX: select: %sconnections pending\n",
758 sock->iconn ? "" : "no ");
759 if (sock->iconn) return(1);
760 select_wait(sock->wait, wait);
761 return(sock->iconn ? 1 : 0);
762 }
763 dprintf(1, "UNIX: select: nothing else for server socket\n");
764 select_wait(sock->wait, wait);
765 return(0);
766 }
767
768 if (sel_type == SEL_IN) {
769 upd = UN_DATA(sock);
770 dprintf(1, "UNIX: select: there is%s data available\n",
771 UN_BUF_AVAIL(upd) ? "" : " no");
772 if (UN_BUF_AVAIL(upd))
773 return(1);
774 else if (sock->state != SS_CONNECTED) {
775 dprintf(1, "UNIX: select: socket not connected(read EOF)\n");
776 return(1);
777 }
778 select_wait(sock->wait,wait);
779 return(0);
780 }
781 if (sel_type == SEL_OUT) {
782 if (sock->state != SS_CONNECTED) {
783 dprintf(1, "UNIX: select: socket not connected(write EOF)\n");
784 return(1);
785 }
786 peerupd = UN_DATA(sock->conn);
787 dprintf(1, "UNIX: select: there is%s space available\n",
788 UN_BUF_SPACE(peerupd) ? "" : " no");
789 if (UN_BUF_SPACE(peerupd) > 0) return(1);
790 select_wait(sock->wait,wait);
791 return(0);
792 }
793
794
795 dprintf(1, "UNIX: select: there are no exceptions here?!\n");
796 return(0);
797 }
798
799
800 static int
801 unix_proto_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
802 {
803 struct unix_proto_data *upd, *peerupd;
804 int er;
805
806 upd = UN_DATA(sock);
807 peerupd = (sock->state == SS_CONNECTED) ? UN_DATA(sock->conn) : NULL;
808
809 switch(cmd) {
810 case TIOCINQ:
811 if (sock->flags & SO_ACCEPTCON) return(-EINVAL);
812 er=verify_area(VERIFY_WRITE,(void *)arg, sizeof(unsigned long));
813 if(er)
814 return er;
815 if (UN_BUF_AVAIL(upd) || peerupd)
816 put_fs_long(UN_BUF_AVAIL(upd),(unsigned long *)arg);
817 else
818 put_fs_long(0,(unsigned long *)arg);
819 break;
820 case TIOCOUTQ:
821 if (sock->flags & SO_ACCEPTCON) return(-EINVAL);
822 er=verify_area(VERIFY_WRITE,(void *)arg, sizeof(unsigned long));
823 if(er)
824 return er;
825 if (peerupd) put_fs_long(UN_BUF_SPACE(peerupd),
826 (unsigned long *)arg);
827 else
828 put_fs_long(0,(unsigned long *)arg);
829 break;
830 default:
831 return(-EINVAL);
832 }
833 return(0);
834 }
835
836
837 static int
838 unix_open(struct inode * inode, struct file * file)
839 {
840 int minor;
841
842 dprintf(1, "UNIX: open\n");
843 minor = MINOR(inode->i_rdev);
844 if (minor != 0) return(-ENODEV);
845
846 return(0);
847 }
848
849
850 static void
851 unix_close(struct inode * inode, struct file * file)
852 {
853 dprintf(1, "UNIX: close\n");
854 }
855
856
857 static int
858 unix_ioctl(struct inode *inode, struct file *file,
859 unsigned int cmd, unsigned long arg)
860 {
861 int minor, ret;
862 int er;
863
864 dprintf(1, "UNIX: ioctl(0x%X, 0x%X)\n", cmd, arg);
865 minor = MINOR(inode->i_rdev);
866 if (minor != 0) return(-ENODEV);
867
868 ret = -EINVAL;
869 switch(cmd) {
870 case DDIOCSDBG:
871 er=verify_area(VERIFY_READ,(void *)arg, sizeof(int));
872 if(er)
873 return er;
874 unix_debug = get_fs_long((int *)arg);
875 if (unix_debug != 0 && unix_debug != 1) {
876 unix_debug = 0;
877 return(-EINVAL);
878 }
879 return(0);
880 case SIOCSIFLINK:
881 printk("UNIX: cannot link streams!\n");
882 break;
883 default:
884 break;
885 }
886 return(ret);
887 }
888
889
890
891
892 static struct file_operations unix_fops = {
893 NULL,
894 NULL,
895 NULL,
896 NULL,
897 NULL,
898 unix_ioctl,
899 NULL,
900 unix_open,
901 unix_close
902 };
903
904
905 static struct proto_ops unix_proto_ops = {
906 AF_UNIX,
907 unix_proto_create,
908 unix_proto_dup,
909 unix_proto_release,
910 unix_proto_bind,
911 unix_proto_connect,
912 unix_proto_socketpair,
913 unix_proto_accept,
914 unix_proto_getname,
915 unix_proto_read,
916 unix_proto_write,
917 unix_proto_select,
918 unix_proto_ioctl,
919 unix_proto_listen,
920 unix_proto_send,
921 unix_proto_recv,
922 unix_proto_sendto,
923 unix_proto_recvfrom,
924 unix_proto_shutdown,
925 unix_proto_setsockopt,
926 unix_proto_getsockopt,
927 NULL
928 };
929
930
931 void
932 unix_proto_init(struct ddi_proto *pro)
933 {
934 struct unix_proto_data *upd;
935
936 dprintf(1, "%s: init: initializing...\n", pro->name);
937 if (register_chrdev(AF_UNIX_MAJOR, "af_unix", &unix_fops) < 0) {
938 printk("%s: cannot register major device %d!\n",
939 pro->name, AF_UNIX_MAJOR);
940 return;
941 }
942
943
944 (void) sock_register(unix_proto_ops.family, &unix_proto_ops);
945
946 for(upd = unix_datas; upd <= last_unix_data; ++upd) {
947 upd->refcnt = 0;
948 }
949 }