|
|
1.1.1.4 ! root 1: #include <linux/signal.h> 1.1 root 2: #include <linux/sched.h> 3: #include <linux/kernel.h> 1.1.1.4 ! root 4: #include <linux/errno.h> ! 5: #include <linux/string.h> 1.1.1.2 root 6: #include <linux/stat.h> 1.1.1.4 ! root 7: #include <linux/socket.h> ! 8: #include <linux/un.h> ! 9: #include <linux/fcntl.h> ! 10: #include <linux/termios.h> ! 11: 1.1 root 12: #include <asm/system.h> 13: #include <asm/segment.h> 1.1.1.4 ! root 14: 1.1 root 15: #include "kern_sock.h" 16: 17: static struct unix_proto_data { 18: int refcnt; /* cnt of reference 0=free */ 19: struct socket *socket; /* socket we're bound to */ 20: int protocol; 21: struct sockaddr_un sockaddr_un; 22: short sockaddr_len; /* >0 if name bound */ 23: char *buf; 24: int bp_head, bp_tail; 25: struct inode *inode; 26: struct unix_proto_data *peerupd; 27: } unix_datas[NSOCKETS]; 28: #define last_unix_data (unix_datas + NSOCKETS - 1) 29: 30: #define UN_DATA(SOCK) ((struct unix_proto_data *)(SOCK)->data) 31: #define UN_PATH_OFFSET ((unsigned long)((struct sockaddr_un *)0)->sun_path) 32: 33: /* 34: * buffer size must be power of 2. buffer mgmt inspired by pipe code. 35: * note that buffer contents can wraparound, and we can write one byte less 36: * than full size to discern full vs empty. 37: */ 38: #define BUF_SIZE PAGE_SIZE 39: #define UN_BUF_AVAIL(UPD) (((UPD)->bp_head - (UPD)->bp_tail) & (BUF_SIZE-1)) 40: #define UN_BUF_SPACE(UPD) ((BUF_SIZE-1) - UN_BUF_AVAIL(UPD)) 41: 42: static int unix_proto_init(void); 43: static int unix_proto_create(struct socket *sock, int protocol); 44: static int unix_proto_dup(struct socket *newsock, struct socket *oldsock); 45: static int unix_proto_release(struct socket *sock, struct socket *peer); 46: static int unix_proto_bind(struct socket *sock, struct sockaddr *umyaddr, 47: int sockaddr_len); 48: static int unix_proto_connect(struct socket *sock, struct sockaddr *uservaddr, 49: int sockaddr_len); 50: static int unix_proto_socketpair(struct socket *sock1, struct socket *sock2); 51: static int unix_proto_accept(struct socket *sock, struct socket *newsock); 52: static int unix_proto_getname(struct socket *sock, struct sockaddr *usockaddr, 53: int *usockaddr_len, int peer); 54: static int unix_proto_read(struct socket *sock, char *ubuf, int size, 55: int nonblock); 56: static int unix_proto_write(struct socket *sock, char *ubuf, int size, 57: int nonblock); 1.1.1.4 ! root 58: static int unix_proto_select(struct socket *sock, int sel_type, select_table * wait); 1.1 root 59: static int unix_proto_ioctl(struct socket *sock, unsigned int cmd, 60: unsigned long arg); 61: 62: struct proto_ops unix_proto_ops = { 63: unix_proto_init, 64: unix_proto_create, 65: unix_proto_dup, 66: unix_proto_release, 67: unix_proto_bind, 68: unix_proto_connect, 69: unix_proto_socketpair, 70: unix_proto_accept, 71: unix_proto_getname, 72: unix_proto_read, 73: unix_proto_write, 74: unix_proto_select, 75: unix_proto_ioctl 76: }; 77: 78: #ifdef SOCK_DEBUG 79: void 80: sockaddr_un_printk(struct sockaddr_un *sockun, int sockaddr_len) 81: { 82: char buf[sizeof(sockun->sun_path) + 1]; 83: 84: sockaddr_len -= UN_PATH_OFFSET; 85: if (sockun->sun_family != AF_UNIX) 86: printk("sockaddr_un: <BAD FAMILY: %d>\n", sockun->sun_family); 87: else if (sockaddr_len <= 0 || sockaddr_len >= sizeof(buf)-1) 88: printk("sockaddr_un: <BAD LENGTH: %d>\n", sockaddr_len); 89: else { 90: memcpy(buf, sockun->sun_path, sockaddr_len); 91: buf[sockaddr_len] = '\0'; 92: printk("sockaddr_un: '%s'[%d]\n", buf, 93: sockaddr_len + UN_PATH_OFFSET); 94: } 95: } 96: #endif 97: 98: static struct unix_proto_data * 99: unix_data_lookup(struct sockaddr_un *sockun, int sockaddr_len) 100: { 101: struct unix_proto_data *upd; 102: 103: for (upd = unix_datas; upd <= last_unix_data; ++upd) { 104: if (upd->refcnt && upd->socket && 105: upd->sockaddr_len == sockaddr_len && 106: memcmp(&upd->sockaddr_un, sockun, sockaddr_len) == 0) 107: return upd; 108: } 109: return NULL; 110: } 111: 112: static struct unix_proto_data * 113: unix_data_alloc(void) 114: { 115: struct unix_proto_data *upd; 116: 117: cli(); 118: for (upd = unix_datas; upd <= last_unix_data; ++upd) { 119: if (!upd->refcnt) { 120: upd->refcnt = 1; 121: sti(); 122: upd->socket = NULL; 123: upd->sockaddr_len = 0; 124: upd->buf = NULL; 125: upd->bp_head = upd->bp_tail = 0; 126: upd->inode = NULL; 127: upd->peerupd = NULL; 128: return upd; 129: } 130: } 131: sti(); 132: return NULL; 133: } 134: 135: static inline void 136: unix_data_ref(struct unix_proto_data *upd) 137: { 138: ++upd->refcnt; 139: PRINTK("unix_data_ref: refing data 0x%x (%d)\n", upd, upd->refcnt); 140: } 141: 142: static void 143: unix_data_deref(struct unix_proto_data *upd) 144: { 145: if (upd->refcnt == 1) { 146: PRINTK("unix_data_deref: releasing data 0x%x\n", upd); 147: if (upd->buf) { 148: free_page((unsigned long)upd->buf); 149: upd->buf = NULL; 150: upd->bp_head = upd->bp_tail = 0; 151: } 152: } 153: --upd->refcnt; 154: } 155: 156: /* 157: * upon a create, we allocate an empty protocol data, and grab a page to 158: * buffer writes 159: */ 160: static int 161: unix_proto_create(struct socket *sock, int protocol) 162: { 163: struct unix_proto_data *upd; 164: 165: PRINTK("unix_proto_create: socket 0x%x, proto %d\n", sock, protocol); 166: if (protocol != 0) { 167: PRINTK("unix_proto_create: protocol != 0\n"); 168: return -EINVAL; 169: } 170: if (!(upd = unix_data_alloc())) { 171: printk("unix_proto_create: can't allocate buffer\n"); 172: return -ENOMEM; 173: } 1.1.1.4 ! root 174: if (!(upd->buf = (char *)get_free_page(GFP_USER))) { 1.1 root 175: printk("unix_proto_create: can't get page!\n"); 176: unix_data_deref(upd); 177: return -ENOMEM; 178: } 179: upd->protocol = protocol; 180: upd->socket = sock; 181: UN_DATA(sock) = upd; 182: PRINTK("unix_proto_create: allocated data 0x%x\n", upd); 183: return 0; 184: } 185: 186: static int 187: unix_proto_dup(struct socket *newsock, struct socket *oldsock) 188: { 189: struct unix_proto_data *upd = UN_DATA(oldsock); 190: 191: return unix_proto_create(newsock, upd->protocol); 192: } 193: 194: static int 195: unix_proto_release(struct socket *sock, struct socket *peer) 196: { 197: struct unix_proto_data *upd = UN_DATA(sock); 198: 199: PRINTK("unix_proto_release: socket 0x%x, unix_data 0x%x\n", 200: sock, upd); 201: if (!upd) 202: return 0; 203: if (upd->socket != sock) { 204: printk("unix_proto_release: socket link mismatch!\n"); 205: return -EINVAL; 206: } 207: if (upd->inode) { 208: PRINTK("unix_proto_release: releasing inode 0x%x\n", 209: upd->inode); 210: iput(upd->inode); 211: upd->inode = NULL; 212: } 213: UN_DATA(sock) = NULL; 214: upd->socket = NULL; 215: if (upd->peerupd) 216: unix_data_deref(upd->peerupd); 217: unix_data_deref(upd); 218: return 0; 219: } 220: 221: /* 222: * bind a name to a socket. this is where much of the work is done. we 223: * allocate a fresh page for the buffer, grab the appropriate inode and 224: * set things up. 225: * 226: * XXX what should we do if an address is already bound? here we return 227: * EINVAL, but it may be necessary to re-bind. i think thats what bsd does 228: * in the case of datagram sockets 229: */ 230: static int 231: unix_proto_bind(struct socket *sock, struct sockaddr *umyaddr, 232: int sockaddr_len) 233: { 234: struct unix_proto_data *upd = UN_DATA(sock); 235: char fname[sizeof(((struct sockaddr_un *)0)->sun_path) + 1]; 236: int i; 237: unsigned long old_fs; 238: 239: PRINTK("unix_proto_bind: socket 0x%x, len=%d\n", sock, 240: sockaddr_len); 241: if (sockaddr_len <= UN_PATH_OFFSET || 242: sockaddr_len >= sizeof(struct sockaddr_un)) { 243: PRINTK("unix_proto_bind: bad length %d\n", sockaddr_len); 244: return -EINVAL; 245: } 246: if (upd->sockaddr_len || upd->inode) { 247: printk("unix_proto_bind: already bound!\n"); 248: return -EINVAL; 249: } 250: verify_area(umyaddr, sockaddr_len); 251: memcpy_fromfs(&upd->sockaddr_un, umyaddr, sockaddr_len); 252: if (upd->sockaddr_un.sun_family != AF_UNIX) { 253: PRINTK("unix_proto_bind: family is %d, not AF_UNIX (%d)\n", 254: upd->sockaddr_un.sun_family, AF_UNIX); 255: return -EINVAL; 256: } 257: 258: memcpy(fname, upd->sockaddr_un.sun_path, sockaddr_len-UN_PATH_OFFSET); 259: fname[sockaddr_len-UN_PATH_OFFSET] = '\0'; 260: old_fs = get_fs(); 261: set_fs(get_ds()); 1.1.1.2 root 262: i = do_mknod(fname, S_IFSOCK | 0777, 0); 1.1 root 263: if (i == 0) 264: i = open_namei(fname, 0, S_IFSOCK, &upd->inode); 265: set_fs(old_fs); 266: if (i < 0) { 267: printk("unix_proto_bind: can't open socket %s\n", fname); 268: return i; 269: } 270: 271: upd->sockaddr_len = sockaddr_len; /* now its legal */ 272: PRINTK("unix_proto_bind: bound socket address: "); 273: #ifdef SOCK_DEBUG 274: sockaddr_un_printk(&upd->sockaddr_un, upd->sockaddr_len); 275: #endif 276: return 0; 277: } 278: 279: /* 280: * perform a connection. we can only connect to unix sockets (i can't for 281: * the life of me find an application where that wouldn't be the case!) 282: */ 283: static int 284: unix_proto_connect(struct socket *sock, struct sockaddr *uservaddr, 285: int sockaddr_len) 286: { 287: int i; 288: struct unix_proto_data *serv_upd; 289: struct sockaddr_un sockun; 290: 291: PRINTK("unix_proto_connect: socket 0x%x, servlen=%d\n", sock, 292: sockaddr_len); 293: if (sockaddr_len <= UN_PATH_OFFSET || 294: sockaddr_len >= sizeof(struct sockaddr_un)) { 295: PRINTK("unix_proto_connect: bad length %d\n", sockaddr_len); 296: return -EINVAL; 297: } 298: verify_area(uservaddr, sockaddr_len); 299: memcpy_fromfs(&sockun, uservaddr, sockaddr_len); 300: if (sockun.sun_family != AF_UNIX) { 301: PRINTK("unix_proto_connect: family is %d, not AF_UNIX (%d)\n", 302: sockun.sun_family, AF_UNIX); 303: return -EINVAL; 304: } 305: if (!(serv_upd = unix_data_lookup(&sockun, sockaddr_len))) { 306: PRINTK("unix_proto_connect: can't locate peer\n"); 307: return -EINVAL; 308: } 309: if ((i = sock_awaitconn(sock, serv_upd->socket)) < 0) { 310: PRINTK("unix_proto_connect: can't await connection\n"); 311: return i; 312: } 313: unix_data_ref(UN_DATA(sock->conn)); 314: UN_DATA(sock)->peerupd = UN_DATA(sock->conn); /* ref server */ 315: return 0; 316: } 317: 318: /* 319: * to do a socketpair, we make just connect the two datas, easy! since we 320: * always wait on the socket inode, they're no contention for a wait area, 321: * and deadlock prevention in the case of a process writing to itself is, 322: * ignored, in true unix fashion! 323: */ 324: static int 325: unix_proto_socketpair(struct socket *sock1, struct socket *sock2) 326: { 327: struct unix_proto_data *upd1 = UN_DATA(sock1), *upd2 = UN_DATA(sock2); 328: 329: unix_data_ref(upd1); 330: unix_data_ref(upd2); 331: upd1->peerupd = upd2; 332: upd2->peerupd = upd1; 333: return 0; 334: } 335: 336: /* 337: * on accept, we ref the peer's data for safe writes 338: */ 339: static int 340: unix_proto_accept(struct socket *sock, struct socket *newsock) 341: { 342: PRINTK("unix_proto_accept: socket 0x%x accepted via socket 0x%x\n", 343: sock, newsock); 344: unix_data_ref(UN_DATA(newsock->conn)); 345: UN_DATA(newsock)->peerupd = UN_DATA(newsock->conn); 346: return 0; 347: } 348: 349: /* 350: * gets the current name or the name of the connected socket. 351: */ 352: static int 353: unix_proto_getname(struct socket *sock, struct sockaddr *usockaddr, 354: int *usockaddr_len, int peer) 355: { 356: struct unix_proto_data *upd; 357: int len; 358: 359: PRINTK("unix_proto_getname: socket 0x%x for %s\n", sock, 360: peer ? "peer" : "self"); 361: if (peer) { 362: if (sock->state != SS_CONNECTED) { 363: PRINTK("unix_proto_getname: socket not connected\n"); 364: return -EINVAL; 365: } 366: upd = UN_DATA(sock->conn); 367: } 368: else 369: upd = UN_DATA(sock); 370: verify_area(usockaddr_len, sizeof(*usockaddr_len)); 371: if ((len = get_fs_long(usockaddr_len)) <= 0) 372: return -EINVAL; 373: if (len > upd->sockaddr_len) 374: len = upd->sockaddr_len; 375: if (len) { 376: verify_area(usockaddr, len); 377: memcpy_tofs(usockaddr, &upd->sockaddr_un, len); 378: } 379: put_fs_long(len, usockaddr_len); 380: return 0; 381: } 382: 383: /* 384: * we read from our own buf. 385: */ 386: static int 387: unix_proto_read(struct socket *sock, char *ubuf, int size, int nonblock) 388: { 389: struct unix_proto_data *upd; 390: int todo, avail; 391: 392: if ((todo = size) <= 0) 393: return 0; 394: upd = UN_DATA(sock); 395: while (!(avail = UN_BUF_AVAIL(upd))) { 396: if (sock->state != SS_CONNECTED) { 397: PRINTK("unix_proto_read: socket not connected\n"); 398: return (sock->state == SS_DISCONNECTING) ? 0 : -EINVAL; 399: } 400: PRINTK("unix_proto_read: no data available...\n"); 401: if (nonblock) 402: return -EAGAIN; 403: interruptible_sleep_on(sock->wait); 404: if (current->signal & ~current->blocked) { 405: PRINTK("unix_proto_read: interrupted\n"); 406: return -ERESTARTSYS; 407: } 408: if (sock->state == SS_DISCONNECTING) { 409: PRINTK("unix_proto_read: disconnected\n"); 410: return 0; 411: } 412: } 413: 414: /* 415: * copy from the read buffer into the user's buffer, watching for 416: * wraparound. then we wake up the writer 417: */ 418: do { 419: int part, cando; 420: 421: if (avail <= 0) { 422: PRINTK("unix_proto_read: AVAIL IS NEGATIVE!!!\n"); 1.1.1.3 root 423: send_sig(SIGKILL,current,1); 1.1 root 424: return -EINTR; 425: } 426: 427: if ((cando = todo) > avail) 428: cando = avail; 429: if (cando > (part = BUF_SIZE - upd->bp_tail)) 430: cando = part; 431: PRINTK("unix_proto_read: avail=%d, todo=%d, cando=%d\n", 432: avail, todo, cando); 433: verify_area(ubuf, cando); 434: memcpy_tofs(ubuf, upd->buf + upd->bp_tail, cando); 435: upd->bp_tail = (upd->bp_tail + cando) & (BUF_SIZE-1); 436: ubuf += cando; 437: todo -= cando; 438: if (sock->state == SS_CONNECTED) 439: wake_up(sock->conn->wait); 440: avail = UN_BUF_AVAIL(upd); 441: } while (todo && avail); 442: return size - todo; 443: } 444: 445: /* 446: * we write to our peer's buf. when we connected we ref'd this peer so we 447: * are safe that the buffer remains, even after the peer has disconnected, 448: * which we check other ways. 449: */ 450: static int 451: unix_proto_write(struct socket *sock, char *ubuf, int size, int nonblock) 452: { 453: struct unix_proto_data *pupd; 454: int todo, space; 455: 456: if ((todo = size) <= 0) 457: return 0; 458: if (sock->state != SS_CONNECTED) { 459: PRINTK("unix_proto_write: socket not connected\n"); 460: if (sock->state == SS_DISCONNECTING) { 1.1.1.3 root 461: send_sig(SIGPIPE,current,1); 1.1 root 462: return -EINTR; 463: } 464: return -EINVAL; 465: } 466: pupd = UN_DATA(sock)->peerupd; /* safer than sock->conn */ 467: 468: while (!(space = UN_BUF_SPACE(pupd))) { 469: PRINTK("unix_proto_write: no space left...\n"); 470: if (nonblock) 1.1.1.3 root 471: return -EAGAIN; 1.1 root 472: interruptible_sleep_on(sock->wait); 473: if (current->signal & ~current->blocked) { 474: PRINTK("unix_proto_write: interrupted\n"); 1.1.1.3 root 475: return -ERESTARTSYS; 1.1 root 476: } 477: if (sock->state == SS_DISCONNECTING) { 478: PRINTK("unix_proto_write: disconnected (SIGPIPE)\n"); 1.1.1.3 root 479: send_sig(SIGPIPE,current,1); 1.1 root 480: return -EINTR; 481: } 482: } 483: 484: /* 485: * copy from the user's buffer to the write buffer, watching for 486: * wraparound. then we wake up the reader 487: */ 488: do { 489: int part, cando; 490: 491: if (space <= 0) { 492: PRINTK("unix_proto_write: SPACE IS NEGATIVE!!!\n"); 1.1.1.3 root 493: send_sig(SIGKILL,current,1); 1.1 root 494: return -EINTR; 495: } 496: 497: /* 498: * we may become disconnected inside this loop, so watch 499: * for it (peerupd is safe until we close) 500: */ 501: if (sock->state == SS_DISCONNECTING) { 1.1.1.3 root 502: send_sig(SIGPIPE,current,1); 1.1 root 503: return -EINTR; 504: } 505: if ((cando = todo) > space) 506: cando = space; 507: if (cando > (part = BUF_SIZE - pupd->bp_head)) 508: cando = part; 509: PRINTK("unix_proto_write: space=%d, todo=%d, cando=%d\n", 510: space, todo, cando); 511: verify_area(ubuf, cando); 512: memcpy_fromfs(pupd->buf + pupd->bp_head, ubuf, cando); 513: pupd->bp_head = (pupd->bp_head + cando) & (BUF_SIZE-1); 514: ubuf += cando; 515: todo -= cando; 516: if (sock->state == SS_CONNECTED) 517: wake_up(sock->conn->wait); 518: space = UN_BUF_SPACE(pupd); 519: } while (todo && space); 520: return size - todo; 521: } 522: 523: static int 1.1.1.4 ! root 524: unix_proto_select(struct socket *sock, int sel_type, select_table * wait) 1.1 root 525: { 526: struct unix_proto_data *upd, *peerupd; 527: 1.1.1.4 ! root 528: if (sel_type == SEL_IN) { 1.1 root 529: upd = UN_DATA(sock); 530: PRINTK("unix_proto_select: there is%s data available\n", 531: UN_BUF_AVAIL(upd) ? "" : " no"); 532: if (UN_BUF_AVAIL(upd)) /* even if disconnected */ 533: return 1; 534: else if (sock->state != SS_CONNECTED) { 535: PRINTK("unix_proto_select: socket not connected (read EOF)\n"); 536: return 1; 537: } 1.1.1.4 ! root 538: select_wait(sock->wait,wait); ! 539: return 0; 1.1 root 540: } 1.1.1.4 ! root 541: if (sel_type == SEL_OUT) { 1.1 root 542: if (sock->state != SS_CONNECTED) { 543: PRINTK("unix_proto_select: socket not connected (write EOF)\n"); 544: return 1; 545: } 546: peerupd = UN_DATA(sock->conn); 547: PRINTK("unix_proto_select: there is%s space available\n", 548: UN_BUF_SPACE(peerupd) ? "" : " no"); 1.1.1.4 ! root 549: if (UN_BUF_SPACE(peerupd) > 0) ! 550: return 1; ! 551: select_wait(sock->wait,wait); ! 552: return 0; 1.1 root 553: } 554: /* SEL_EX */ 555: PRINTK("unix_proto_select: there are no exceptions here?!\n"); 556: return 0; 557: } 558: 559: static int 560: unix_proto_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 561: { 562: struct unix_proto_data *upd, *peerupd; 563: 564: upd = UN_DATA(sock); 565: peerupd = (sock->state == SS_CONNECTED) ? UN_DATA(sock->conn) : NULL; 566: 567: switch (cmd) { 568: case TIOCINQ: 569: verify_area((void *)arg, sizeof(unsigned long)); 570: if (UN_BUF_AVAIL(upd) || peerupd) 571: put_fs_long(UN_BUF_AVAIL(upd), (unsigned long *)arg); 572: else 573: put_fs_long(1, (unsigned long *)arg); /* read EOF */ 574: break; 575: 576: case TIOCOUTQ: 577: verify_area((void *)arg, sizeof(unsigned long)); 578: if (peerupd) 579: put_fs_long(UN_BUF_SPACE(peerupd), 580: (unsigned long *)arg); 581: else 582: put_fs_long(0, (unsigned long *)arg); 583: break; 584: 585: default: 586: return -EINVAL; 587: } 588: return 0; 589: } 590: 591: static int 592: unix_proto_init(void) 593: { 594: struct unix_proto_data *upd; 595: 596: PRINTK("unix_proto_init: initializing...\n"); 597: for (upd = unix_datas; upd <= last_unix_data; ++upd) 598: upd->refcnt = 0; 599: return 0; 600: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.