Annotation of embedaddon/nginx/src/os/unix/ngx_channel.c, revision 1.1

1.1     ! misho       1: 
        !             2: /*
        !             3:  * Copyright (C) Igor Sysoev
        !             4:  * Copyright (C) Nginx, Inc.
        !             5:  */
        !             6: 
        !             7: 
        !             8: #include <ngx_config.h>
        !             9: #include <ngx_core.h>
        !            10: #include <ngx_channel.h>
        !            11: 
        !            12: 
        !            13: ngx_int_t
        !            14: ngx_write_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size,
        !            15:     ngx_log_t *log)
        !            16: {
        !            17:     ssize_t             n;
        !            18:     ngx_err_t           err;
        !            19:     struct iovec        iov[1];
        !            20:     struct msghdr       msg;
        !            21: 
        !            22: #if (NGX_HAVE_MSGHDR_MSG_CONTROL)
        !            23: 
        !            24:     union {
        !            25:         struct cmsghdr  cm;
        !            26:         char            space[CMSG_SPACE(sizeof(int))];
        !            27:     } cmsg;
        !            28: 
        !            29:     if (ch->fd == -1) {
        !            30:         msg.msg_control = NULL;
        !            31:         msg.msg_controllen = 0;
        !            32: 
        !            33:     } else {
        !            34:         msg.msg_control = (caddr_t) &cmsg;
        !            35:         msg.msg_controllen = sizeof(cmsg);
        !            36: 
        !            37:         cmsg.cm.cmsg_len = CMSG_LEN(sizeof(int));
        !            38:         cmsg.cm.cmsg_level = SOL_SOCKET;
        !            39:         cmsg.cm.cmsg_type = SCM_RIGHTS;
        !            40: 
        !            41:         /*
        !            42:          * We have to use ngx_memcpy() instead of simple
        !            43:          *   *(int *) CMSG_DATA(&cmsg.cm) = ch->fd;
        !            44:          * because some gcc 4.4 with -O2/3/s optimization issues the warning:
        !            45:          *   dereferencing type-punned pointer will break strict-aliasing rules
        !            46:          *
        !            47:          * Fortunately, gcc with -O1 compiles this ngx_memcpy()
        !            48:          * in the same simple assignment as in the code above
        !            49:          */
        !            50: 
        !            51:         ngx_memcpy(CMSG_DATA(&cmsg.cm), &ch->fd, sizeof(int));
        !            52:     }
        !            53: 
        !            54:     msg.msg_flags = 0;
        !            55: 
        !            56: #else
        !            57: 
        !            58:     if (ch->fd == -1) {
        !            59:         msg.msg_accrights = NULL;
        !            60:         msg.msg_accrightslen = 0;
        !            61: 
        !            62:     } else {
        !            63:         msg.msg_accrights = (caddr_t) &ch->fd;
        !            64:         msg.msg_accrightslen = sizeof(int);
        !            65:     }
        !            66: 
        !            67: #endif
        !            68: 
        !            69:     iov[0].iov_base = (char *) ch;
        !            70:     iov[0].iov_len = size;
        !            71: 
        !            72:     msg.msg_name = NULL;
        !            73:     msg.msg_namelen = 0;
        !            74:     msg.msg_iov = iov;
        !            75:     msg.msg_iovlen = 1;
        !            76: 
        !            77:     n = sendmsg(s, &msg, 0);
        !            78: 
        !            79:     if (n == -1) {
        !            80:         err = ngx_errno;
        !            81:         if (err == NGX_EAGAIN) {
        !            82:             return NGX_AGAIN;
        !            83:         }
        !            84: 
        !            85:         ngx_log_error(NGX_LOG_ALERT, log, err, "sendmsg() failed");
        !            86:         return NGX_ERROR;
        !            87:     }
        !            88: 
        !            89:     return NGX_OK;
        !            90: }
        !            91: 
        !            92: 
        !            93: ngx_int_t
        !            94: ngx_read_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size, ngx_log_t *log)
        !            95: {
        !            96:     ssize_t             n;
        !            97:     ngx_err_t           err;
        !            98:     struct iovec        iov[1];
        !            99:     struct msghdr       msg;
        !           100: 
        !           101: #if (NGX_HAVE_MSGHDR_MSG_CONTROL)
        !           102:     union {
        !           103:         struct cmsghdr  cm;
        !           104:         char            space[CMSG_SPACE(sizeof(int))];
        !           105:     } cmsg;
        !           106: #else
        !           107:     int                 fd;
        !           108: #endif
        !           109: 
        !           110:     iov[0].iov_base = (char *) ch;
        !           111:     iov[0].iov_len = size;
        !           112: 
        !           113:     msg.msg_name = NULL;
        !           114:     msg.msg_namelen = 0;
        !           115:     msg.msg_iov = iov;
        !           116:     msg.msg_iovlen = 1;
        !           117: 
        !           118: #if (NGX_HAVE_MSGHDR_MSG_CONTROL)
        !           119:     msg.msg_control = (caddr_t) &cmsg;
        !           120:     msg.msg_controllen = sizeof(cmsg);
        !           121: #else
        !           122:     msg.msg_accrights = (caddr_t) &fd;
        !           123:     msg.msg_accrightslen = sizeof(int);
        !           124: #endif
        !           125: 
        !           126:     n = recvmsg(s, &msg, 0);
        !           127: 
        !           128:     if (n == -1) {
        !           129:         err = ngx_errno;
        !           130:         if (err == NGX_EAGAIN) {
        !           131:             return NGX_AGAIN;
        !           132:         }
        !           133: 
        !           134:         ngx_log_error(NGX_LOG_ALERT, log, err, "recvmsg() failed");
        !           135:         return NGX_ERROR;
        !           136:     }
        !           137: 
        !           138:     if (n == 0) {
        !           139:         ngx_log_debug0(NGX_LOG_DEBUG_CORE, log, 0, "recvmsg() returned zero");
        !           140:         return NGX_ERROR;
        !           141:     }
        !           142: 
        !           143:     if ((size_t) n < sizeof(ngx_channel_t)) {
        !           144:         ngx_log_error(NGX_LOG_ALERT, log, 0,
        !           145:                       "recvmsg() returned not enough data: %uz", n);
        !           146:         return NGX_ERROR;
        !           147:     }
        !           148: 
        !           149: #if (NGX_HAVE_MSGHDR_MSG_CONTROL)
        !           150: 
        !           151:     if (ch->command == NGX_CMD_OPEN_CHANNEL) {
        !           152: 
        !           153:         if (cmsg.cm.cmsg_len < (socklen_t) CMSG_LEN(sizeof(int))) {
        !           154:             ngx_log_error(NGX_LOG_ALERT, log, 0,
        !           155:                           "recvmsg() returned too small ancillary data");
        !           156:             return NGX_ERROR;
        !           157:         }
        !           158: 
        !           159:         if (cmsg.cm.cmsg_level != SOL_SOCKET || cmsg.cm.cmsg_type != SCM_RIGHTS)
        !           160:         {
        !           161:             ngx_log_error(NGX_LOG_ALERT, log, 0,
        !           162:                           "recvmsg() returned invalid ancillary data "
        !           163:                           "level %d or type %d",
        !           164:                           cmsg.cm.cmsg_level, cmsg.cm.cmsg_type);
        !           165:             return NGX_ERROR;
        !           166:         }
        !           167: 
        !           168:         /* ch->fd = *(int *) CMSG_DATA(&cmsg.cm); */
        !           169: 
        !           170:         ngx_memcpy(&ch->fd, CMSG_DATA(&cmsg.cm), sizeof(int));
        !           171:     }
        !           172: 
        !           173:     if (msg.msg_flags & (MSG_TRUNC|MSG_CTRUNC)) {
        !           174:         ngx_log_error(NGX_LOG_ALERT, log, 0,
        !           175:                       "recvmsg() truncated data");
        !           176:     }
        !           177: 
        !           178: #else
        !           179: 
        !           180:     if (ch->command == NGX_CMD_OPEN_CHANNEL) {
        !           181:         if (msg.msg_accrightslen != sizeof(int)) {
        !           182:             ngx_log_error(NGX_LOG_ALERT, log, 0,
        !           183:                           "recvmsg() returned no ancillary data");
        !           184:             return NGX_ERROR;
        !           185:         }
        !           186: 
        !           187:         ch->fd = fd;
        !           188:     }
        !           189: 
        !           190: #endif
        !           191: 
        !           192:     return n;
        !           193: }
        !           194: 
        !           195: 
        !           196: ngx_int_t
        !           197: ngx_add_channel_event(ngx_cycle_t *cycle, ngx_fd_t fd, ngx_int_t event,
        !           198:     ngx_event_handler_pt handler)
        !           199: {
        !           200:     ngx_event_t       *ev, *rev, *wev;
        !           201:     ngx_connection_t  *c;
        !           202: 
        !           203:     c = ngx_get_connection(fd, cycle->log);
        !           204: 
        !           205:     if (c == NULL) {
        !           206:         return NGX_ERROR;
        !           207:     }
        !           208: 
        !           209:     c->pool = cycle->pool;
        !           210: 
        !           211:     rev = c->read;
        !           212:     wev = c->write;
        !           213: 
        !           214:     rev->log = cycle->log;
        !           215:     wev->log = cycle->log;
        !           216: 
        !           217: #if (NGX_THREADS)
        !           218:     rev->lock = &c->lock;
        !           219:     wev->lock = &c->lock;
        !           220:     rev->own_lock = &c->lock;
        !           221:     wev->own_lock = &c->lock;
        !           222: #endif
        !           223: 
        !           224:     rev->channel = 1;
        !           225:     wev->channel = 1;
        !           226: 
        !           227:     ev = (event == NGX_READ_EVENT) ? rev : wev;
        !           228: 
        !           229:     ev->handler = handler;
        !           230: 
        !           231:     if (ngx_add_conn && (ngx_event_flags & NGX_USE_EPOLL_EVENT) == 0) {
        !           232:         if (ngx_add_conn(c) == NGX_ERROR) {
        !           233:             ngx_free_connection(c);
        !           234:             return NGX_ERROR;
        !           235:         }
        !           236: 
        !           237:     } else {
        !           238:         if (ngx_add_event(ev, event, 0) == NGX_ERROR) {
        !           239:             ngx_free_connection(c);
        !           240:             return NGX_ERROR;
        !           241:         }
        !           242:     }
        !           243: 
        !           244:     return NGX_OK;
        !           245: }
        !           246: 
        !           247: 
        !           248: void
        !           249: ngx_close_channel(ngx_fd_t *fd, ngx_log_t *log)
        !           250: {
        !           251:     if (close(fd[0]) == -1) {
        !           252:         ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "close() channel failed");
        !           253:     }
        !           254: 
        !           255:     if (close(fd[1]) == -1) {
        !           256:         ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "close() channel failed");
        !           257:     }
        !           258: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>