本文整理汇总了C++中CMSG_LEN函数的典型用法代码示例。如果您正苦于以下问题:C++ CMSG_LEN函数的具体用法?C++ CMSG_LEN怎么用?C++ CMSG_LEN使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了CMSG_LEN函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: malloc
struct command *read_command( int cmd_fd ) {
struct command *cmd = malloc(sizeof(struct command));
if (! cmd) {
fprintf(stderr, "Unable to allocate memory for command!\n");
return NULL;
}
int fd[1] = {-1};
char buffer[CMSG_SPACE(sizeof fd)];
struct iovec v = {
.iov_base = cmd,
.iov_len = sizeof(*cmd)
};
struct msghdr msg = {
.msg_iov = &v,
.msg_iovlen = 1,
.msg_control = buffer,
.msg_controllen = sizeof(buffer)
};
int done = recvmsg( cmd_fd, &msg, 0 );
if (done == -1) {
fprintf(stderr, "Error reading command.");
free(cmd);
return NULL;
}
struct cmsghdr *cmessage = CMSG_FIRSTHDR(&msg);
if (cmessage) {
memcpy(fd, CMSG_DATA(cmessage), sizeof fd);
/* place FD back in the command message */
cmd->fd = (int) fd[0];
}
return cmd;
}
int send_command( int cmd_fd, enum command_type type, char *param, int passfd, int exclusive, char *tag ) {
if (type == CMD_ADD && passfd == 1) {
type = CMD_PASSFD;
}
struct command cmd = {
.fd = -1,
.exclusive = exclusive,
.type = type,
.param = {0},
.tag = {0}
};
if (param != NULL) {
strncpy(cmd.param, param, TH_COMMAND_PARAM_LENGTH);
cmd.param[TH_COMMAND_PARAM_LENGTH-1] = '\0';
}
if (tag != NULL) {
strncpy(cmd.tag, tag, TH_DEVICE_TAG_LENGTH);
cmd.tag[TH_DEVICE_TAG_LENGTH-1] = '\0';
}
struct iovec v = {
.iov_base = &cmd,
.iov_len = sizeof(cmd)
};
struct msghdr m = {
.msg_iov = &v,
.msg_iovlen = 1
};
/* add FD */
int dev_fd[1] = { -1 };
char buffer[CMSG_SPACE(sizeof(dev_fd))];
if (passfd) {
int fd = open( param, O_RDONLY );
if (fd < 0) {
perror("open");
return 1;
}
dev_fd[0] = fd ;
m.msg_control = buffer;
m.msg_controllen = sizeof(buffer);
struct cmsghdr *cmessage = CMSG_FIRSTHDR(&m);
cmessage->cmsg_level = SOL_SOCKET;
cmessage->cmsg_type = SCM_RIGHTS;
cmessage->cmsg_len = CMSG_LEN(sizeof(dev_fd));
m.msg_controllen = cmessage->cmsg_len;
memcpy(CMSG_DATA(cmessage), dev_fd, sizeof dev_fd);
}
int done = sendmsg( cmd_fd, &m, 0 );
return (done == -1);
}
开发者ID:dreiss,项目名称:triggerhappy,代码行数:90,代码来源:cmdsocket.c
示例2: lttcomm_recv_creds_unix_sock
/*
* Recv a message accompanied with credentials from a unix socket.
*
* Returns the size of received data, or negative error value.
*/
LTTNG_HIDDEN
ssize_t lttcomm_recv_creds_unix_sock(int sock, void *buf, size_t len,
lttng_sock_cred *creds)
{
struct msghdr msg;
struct iovec iov[1];
ssize_t ret;
size_t len_last;
#ifdef __linux__
struct cmsghdr *cmptr;
size_t sizeof_cred = sizeof(lttng_sock_cred);
char anc_buf[CMSG_SPACE(sizeof_cred)];
#endif /* __linux__ */
memset(&msg, 0, sizeof(msg));
/* Not allowed */
if (creds == NULL) {
ret = -1;
goto end;
}
/* Prepare to receive the structures */
iov[0].iov_base = buf;
iov[0].iov_len = len;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
#ifdef __linux__
msg.msg_control = anc_buf;
msg.msg_controllen = sizeof(anc_buf);
#endif /* __linux__ */
do {
len_last = iov[0].iov_len;
ret = recvmsg(sock, &msg, 0);
if (ret > 0) {
iov[0].iov_base += ret;
iov[0].iov_len -= ret;
assert(ret <= len_last);
}
} while ((ret > 0 && ret < len_last) || (ret < 0 && errno == EINTR));
if (ret < 0) {
PERROR("recvmsg fds");
goto end;
} else if (ret > 0) {
ret = len;
}
/* Else ret = 0 meaning an orderly shutdown. */
#ifdef __linux__
if (msg.msg_flags & MSG_CTRUNC) {
fprintf(stderr, "Error: Control message truncated.\n");
ret = -1;
goto end;
}
cmptr = CMSG_FIRSTHDR(&msg);
if (cmptr == NULL) {
fprintf(stderr, "Error: Invalid control message header\n");
ret = -1;
goto end;
}
if (cmptr->cmsg_level != SOL_SOCKET ||
cmptr->cmsg_type != LTTNG_SOCK_CREDS) {
fprintf(stderr, "Didn't received any credentials\n");
ret = -1;
goto end;
}
if (cmptr->cmsg_len != CMSG_LEN(sizeof_cred)) {
fprintf(stderr, "Error: Received %zu bytes of ancillary data, expected %zu\n",
(size_t) cmptr->cmsg_len, (size_t) CMSG_LEN(sizeof_cred));
ret = -1;
goto end;
}
memcpy(creds, CMSG_DATA(cmptr), sizeof_cred);
#elif (defined(__FreeBSD__) || defined(__CYGWIN__) || defined(__sun__) || defined(__APPLE__))
{
int peer_ret;
peer_ret = getpeereid(sock, &creds->uid, &creds->gid);
if (peer_ret != 0) {
return peer_ret;
}
}
#else
#error "Please implement credential support for your OS."
#endif /* __linux__ */
end:
return ret;
}
开发者ID:mjeanson,项目名称:lttng-tools,代码行数:100,代码来源:unix.c
示例3: scm_detach_fds
void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)
{
struct cmsghdr __user *cm
= (__force struct cmsghdr __user*)msg->msg_control;
int fdmax = 0;
int fdnum = scm->fp->count;
struct file **fp = scm->fp->fp;
int __user *cmfptr;
int err = 0, i;
if (MSG_CMSG_COMPAT & msg->msg_flags) {
scm_detach_fds_compat(msg, scm);
return;
}
if (msg->msg_controllen > sizeof(struct cmsghdr))
fdmax = ((msg->msg_controllen - sizeof(struct cmsghdr))
/ sizeof(int));
if (fdnum < fdmax)
fdmax = fdnum;
for (i=0, cmfptr=(__force int __user *)CMSG_DATA(cm); i<fdmax;
i++, cmfptr++)
{
int new_fd;
err = security_file_receive(fp[i]);
if (err)
break;
err = get_unused_fd_flags(MSG_CMSG_CLOEXEC & msg->msg_flags
? O_CLOEXEC : 0);
if (err < 0)
break;
new_fd = err;
err = put_user(new_fd, cmfptr);
if (err) {
put_unused_fd(new_fd);
break;
}
/* Bump the usage count and install the file. */
get_file(fp[i]);
fd_install(new_fd, fp[i]);
}
if (i > 0)
{
int cmlen = CMSG_LEN(i*sizeof(int));
err = put_user(SOL_SOCKET, &cm->cmsg_level);
if (!err)
err = put_user(SCM_RIGHTS, &cm->cmsg_type);
if (!err)
err = put_user(cmlen, &cm->cmsg_len);
if (!err) {
cmlen = CMSG_SPACE(i*sizeof(int));
msg->msg_control += cmlen;
msg->msg_controllen -= cmlen;
}
}
if (i < fdnum || (fdnum && fdmax <= 0))
msg->msg_flags |= MSG_CTRUNC;
/*
* All of the files that fit in the message have had their
* usage counts incremented, so we just free the list.
*/
__scm_destroy(scm);
}
开发者ID:12rafael,项目名称:jellytimekernel,代码行数:68,代码来源:scm.c
示例4: dgram_sctp_write
static int
dgram_sctp_write(BIO *b, const char *in, int inl)
{
int ret;
bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr;
struct bio_dgram_sctp_sndinfo *sinfo = &(data->sndinfo);
struct bio_dgram_sctp_prinfo *pinfo = &(data->prinfo);
struct bio_dgram_sctp_sndinfo handshake_sinfo;
struct iovec iov[1];
struct msghdr msg;
struct cmsghdr *cmsg;
#if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo)) + CMSG_SPACE(sizeof(struct sctp_prinfo))];
struct sctp_sndinfo *sndinfo;
struct sctp_prinfo *prinfo;
#else
char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
struct sctp_sndrcvinfo *sndrcvinfo;
#endif
errno = 0;
/* If we're send anything else than application data,
* disable all user parameters and flags.
*/
if (in[0] != 23) {
memset(&handshake_sinfo, 0x00, sizeof(struct bio_dgram_sctp_sndinfo));
#ifdef SCTP_SACK_IMMEDIATELY
handshake_sinfo.snd_flags = SCTP_SACK_IMMEDIATELY;
#endif
sinfo = &handshake_sinfo;
}
/* If we have to send a shutdown alert message and the
* socket is not dry yet, we have to save it and send it
* as soon as the socket gets dry.
*/
if (data->save_shutdown && !BIO_dgram_sctp_wait_for_dry(b)) {
data->saved_message.bio = b;
data->saved_message.length = inl;
data->saved_message.data = malloc(inl);
memcpy(data->saved_message.data, in, inl);
return inl;
}
iov[0].iov_base = (char *)in;
iov[0].iov_len = inl;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_control = (caddr_t)cmsgbuf;
msg.msg_controllen = 0;
msg.msg_flags = 0;
#if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
cmsg = (struct cmsghdr *)cmsgbuf;
cmsg->cmsg_level = IPPROTO_SCTP;
cmsg->cmsg_type = SCTP_SNDINFO;
cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndinfo));
sndinfo = (struct sctp_sndinfo *)CMSG_DATA(cmsg);
memset(sndinfo, 0, sizeof(struct sctp_sndinfo));
sndinfo->snd_sid = sinfo->snd_sid;
sndinfo->snd_flags = sinfo->snd_flags;
sndinfo->snd_ppid = sinfo->snd_ppid;
sndinfo->snd_context = sinfo->snd_context;
msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo));
cmsg = (struct cmsghdr *)&cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo))];
cmsg->cmsg_level = IPPROTO_SCTP;
cmsg->cmsg_type = SCTP_PRINFO;
cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_prinfo));
prinfo = (struct sctp_prinfo *)CMSG_DATA(cmsg);
memset(prinfo, 0, sizeof(struct sctp_prinfo));
prinfo->pr_policy = pinfo->pr_policy;
prinfo->pr_value = pinfo->pr_value;
msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_prinfo));
#else
cmsg = (struct cmsghdr *)cmsgbuf;
cmsg->cmsg_level = IPPROTO_SCTP;
cmsg->cmsg_type = SCTP_SNDRCV;
cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
memset(sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo));
sndrcvinfo->sinfo_stream = sinfo->snd_sid;
sndrcvinfo->sinfo_flags = sinfo->snd_flags;
#ifdef __FreeBSD__
sndrcvinfo->sinfo_flags |= pinfo->pr_policy;
#endif
sndrcvinfo->sinfo_ppid = sinfo->snd_ppid;
sndrcvinfo->sinfo_context = sinfo->snd_context;
sndrcvinfo->sinfo_timetolive = pinfo->pr_value;
msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndrcvinfo));
#endif
ret = sendmsg(b->num, &msg, 0);
BIO_clear_retry_flags(b);
if (ret <= 0) {
if (BIO_dgram_should_retry(ret)) {
BIO_set_retry_write(b);
//.........这里部分代码省略.........
开发者ID:hotelzululima,项目名称:libopenssl,代码行数:101,代码来源:bss_dgram.c
示例5: get_creds
int get_creds(int sd, char *username, char *hostname)
{
int nb/*, sync*/;
char ctrl[CMSG_SPACE(sizeof(struct ucred))];
size_t size;
struct iovec iov[1];
struct msghdr msg;
struct cmsghdr *cmptr;
ucreds *credentials;
struct passwd *cpwd;
char dummy;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_control = ctrl;
msg.msg_controllen = sizeof(ctrl);
msg.msg_flags = 0;
#ifdef LOCAL_CREDS
nb = 1;
if (setsockopt(sd, 0, LOCAL_CREDS, &nb, sizeof(nb)) == -1) return 0;
#else
#ifdef SO_PASSCRED
nb = 1;
if (setsockopt(sd, SOL_SOCKET, SO_PASSCRED, &nb, sizeof(nb)) == -1)
return 0;
#endif
#endif
dummy = '\0';
do
{
msg.msg_iov->iov_base = (void *) & dummy;
msg.msg_iov->iov_len = sizeof(dummy);
nb = recvmsg(sd, &msg, 0);
}
while (nb == -1 && (errno == EINTR || errno == EAGAIN));
if (nb == -1) return 0;
if ((unsigned)msg.msg_controllen < sizeof(struct cmsghdr)) return 0;
cmptr = CMSG_FIRSTHDR(&msg);
#ifndef __NetBSD__
size = sizeof(ucreds);
#else
if (cmptr->cmsg_len < SOCKCREDSIZE(0)) return 0;
size = SOCKCREDSIZE(((cred *)CMSG_DATA(cmptr))->sc_ngroups);
#endif
if ((unsigned)cmptr->cmsg_len != CMSG_LEN(size)) return 0;
if (cmptr->cmsg_level != SOL_SOCKET) return 0;
if (cmptr->cmsg_type != SCM_CREDS) return 0;
if (!(credentials = (ucreds *)malloc(size))) return 0;
memcpy(credentials, CMSG_DATA(cmptr), size);
cpwd = getpwuid(SPC_PEER_UID(credentials));
if (cpwd)
strcpy(username, cpwd->pw_name);
strcpy(hostname, server_name);
free(credentials);
return 0;
}
开发者ID:Johnlihj,项目名称:torque,代码行数:85,代码来源:process_request.c
示例6: ngx_read_channel
ngx_int_t
ngx_read_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size, ngx_log_t *log)
{
ssize_t n;
ngx_err_t err;
struct iovec iov[1];
struct msghdr msg;
#if (NGX_HAVE_MSGHDR_MSG_CONTROL)
union {
struct cmsghdr cm;
char space[CMSG_SPACE(sizeof(int))];
} cmsg;
#else
int fd;
#endif
iov[0].iov_base = (char *) ch;
iov[0].iov_len = size;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
#if (NGX_HAVE_MSGHDR_MSG_CONTROL)
msg.msg_control = (caddr_t) &cmsg;
msg.msg_controllen = sizeof(cmsg);
#else
msg.msg_accrights = (caddr_t) &fd;
msg.msg_accrightslen = sizeof(int);
#endif
n = recvmsg(s, &msg, 0);
if (n == -1) {
err = ngx_errno;
if (err == NGX_EAGAIN) {
return NGX_AGAIN;
}
ngx_log_error(NGX_LOG_ALERT, log, err, "recvmsg() failed");
return NGX_ERROR;
}
if (n == 0) {
ngx_log_debug0(NGX_LOG_DEBUG_CORE, log, 0, "recvmsg() returned zero");
return NGX_ERROR;
}
if ((size_t) n < sizeof(ngx_channel_t)) {
ngx_log_error(NGX_LOG_ALERT, log, 0,
"recvmsg() returned not enough data: %uz", n);
return NGX_ERROR;
}
#if (NGX_HAVE_MSGHDR_MSG_CONTROL)
if (ch->command == NGX_CMD_OPEN_CHANNEL) {
if (cmsg.cm.cmsg_len < (socklen_t) CMSG_LEN(sizeof(int))) {
ngx_log_error(NGX_LOG_ALERT, log, 0,
"recvmsg() returned too small ancillary data");
return NGX_ERROR;
}
if (cmsg.cm.cmsg_level != SOL_SOCKET || cmsg.cm.cmsg_type != SCM_RIGHTS)
{
ngx_log_error(NGX_LOG_ALERT, log, 0,
"recvmsg() returned invalid ancillary data "
"level %d or type %d",
cmsg.cm.cmsg_level, cmsg.cm.cmsg_type);
return NGX_ERROR;
}
ch->fd = *(int *) CMSG_DATA(&cmsg.cm);
}
if (msg.msg_flags & (MSG_TRUNC|MSG_CTRUNC)) {
ngx_log_error(NGX_LOG_ALERT, log, 0,
"recvmsg() truncated data");
}
#else
if (ch->command == NGX_CMD_OPEN_CHANNEL) {
if (msg.msg_accrightslen != sizeof(int)) {
ngx_log_error(NGX_LOG_ALERT, log, 0,
"recvmsg() returned no ancillary data");
return NGX_ERROR;
}
ch->fd = fd;
}
#endif
return n;
}
开发者ID:10389030,项目名称:nginx,代码行数:99,代码来源:ngx_channel.c
示例7: control_message_from_parent
/*
* This function runs in the context of the background proxy process.
* Receive a control message from the parent (sent by the port_share_sendmsg
* function above) and act on it. Return false if the proxy process should
* exit, true otherwise.
*/
static bool
control_message_from_parent (const socket_descriptor_t sd_control,
struct proxy_connection **list,
struct event_set *es,
const in_addr_t server_addr,
const int server_port)
{
struct buffer buf = alloc_buf (PROXY_CONNECTION_BUFFER_SIZE);
struct msghdr mesg;
struct cmsghdr* h;
struct iovec iov[2];
char command = 0;
ssize_t status;
int ret = true;
CLEAR (mesg);
iov[0].iov_base = &command;
iov[0].iov_len = sizeof (command);
iov[1].iov_base = BPTR (&buf);
iov[1].iov_len = BCAP (&buf);
mesg.msg_iov = iov;
mesg.msg_iovlen = 2;
mesg.msg_controllen = cmsg_size ();
mesg.msg_control = (char *) malloc (mesg.msg_controllen);
check_malloc_return (mesg.msg_control);
mesg.msg_flags = 0;
h = CMSG_FIRSTHDR(&mesg);
h->cmsg_len = CMSG_LEN(sizeof(socket_descriptor_t));
h->cmsg_level = SOL_SOCKET;
h->cmsg_type = SCM_RIGHTS;
*((socket_descriptor_t*)CMSG_DATA(h)) = SOCKET_UNDEFINED;
status = recvmsg (sd_control, &mesg, MSG_NOSIGNAL);
if (status != -1)
{
if ( h == NULL
|| h->cmsg_len != CMSG_LEN(sizeof(socket_descriptor_t))
|| h->cmsg_level != SOL_SOCKET
|| h->cmsg_type != SCM_RIGHTS )
{
ret = false;
}
else
{
const socket_descriptor_t received_fd = *((socket_descriptor_t*)CMSG_DATA(h));
dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: RECEIVED sd=%d", (int)received_fd);
if (status >= 2 && command == COMMAND_REDIRECT)
{
buf.len = status - 1;
if (proxy_entry_new (list,
es,
server_addr,
server_port,
received_fd,
&buf))
{
CLEAR (buf); /* we gave the buffer to proxy_entry_new */
}
else
{
openvpn_close_socket (received_fd);
}
}
else if (status >= 1 && command == COMMAND_EXIT)
{
dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: RECEIVED COMMAND_EXIT");
openvpn_close_socket (received_fd); /* null socket */
ret = false;
}
}
}
free (mesg.msg_control);
free_buf (&buf);
return ret;
}
开发者ID:OPSF,项目名称:uClinux,代码行数:85,代码来源:ps.c
示例8: recvfd
/*
* Receives a file descriptor from the sockfd provided. Returns the file
* descriptor as sent from sendfd(). It will return the file descriptor
* or die (literally) trying. Any synchronisation and preparation of
* state should be done external to this (we expect the other side to be
* in sendfd() in the code).
*/
struct file_t recvfd(int sockfd)
{
struct msghdr msg = {0};
struct iovec iov[1] = {0};
struct cmsghdr *cmsg;
struct file_t file = {0};
int *fdptr;
int olderrno;
union {
char buf[CMSG_SPACE(sizeof(file.fd))];
struct cmsghdr align;
} u;
/* Allocate a buffer. */
/* TODO: Make this dynamic with MSG_PEEK. */
file.name = malloc(TAG_BUFFER);
if (!file.name)
error("recvfd: failed to allocate file.tag buffer\n");
/*
* We need to "recieve" the non-ancillary data even though we don't
* plan to use it at all. Otherwise, things won't work as expected.
* See unix(7) and other well-hidden documentation.
*/
iov[0].iov_base = file.name;
iov[0].iov_len = TAG_BUFFER;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_control = u.buf;
msg.msg_controllen = sizeof(u.buf);
ssize_t ret = recvmsg(sockfd, &msg, 0);
if (ret < 0)
goto err;
cmsg = CMSG_FIRSTHDR(&msg);
if (!cmsg)
error("recvfd: got NULL from CMSG_FIRSTHDR");
if (cmsg->cmsg_level != SOL_SOCKET)
error("recvfd: expected SOL_SOCKET in cmsg: %d", cmsg->cmsg_level);
if (cmsg->cmsg_type != SCM_RIGHTS)
error("recvfd: expected SCM_RIGHTS in cmsg: %d", cmsg->cmsg_type);
if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)))
error("recvfd: expected correct CMSG_LEN in cmsg: %lu", cmsg->cmsg_len);
fdptr = (int *) CMSG_DATA(cmsg);
if (!fdptr || *fdptr < 0)
error("recvfd: recieved invalid pointer");
file.fd = *fdptr;
return file;
err:
olderrno = errno;
free(file.name);
errno = olderrno;
return (struct file_t){0};
}
开发者ID:caniszczyk,项目名称:runc,代码行数:69,代码来源:cmsg.c
示例9: lutil_getpeereid
int lutil_getpeereid( int s, uid_t *euid, gid_t *egid
#ifdef LDAP_PF_LOCAL_SENDMSG
, struct berval *peerbv
#endif
)
{
#ifdef LDAP_PF_LOCAL
#if defined( HAVE_GETPEERUCRED )
ucred_t *uc = NULL;
if( getpeerucred( s, &uc ) == 0 ) {
*euid = ucred_geteuid( uc );
*egid = ucred_getegid( uc );
ucred_free( uc );
return 0;
}
#elif defined( SO_PEERCRED )
struct ucred peercred;
ber_socklen_t peercredlen = sizeof peercred;
if(( getsockopt( s, SOL_SOCKET, SO_PEERCRED,
(void *)&peercred, &peercredlen ) == 0 )
&& ( peercredlen == sizeof peercred ))
{
*euid = peercred.uid;
*egid = peercred.gid;
return 0;
}
#elif defined( LOCAL_PEERCRED )
struct xucred peercred;
ber_socklen_t peercredlen = sizeof peercred;
if(( getsockopt( s, LOCAL_PEERCRED, 1,
(void *)&peercred, &peercredlen ) == 0 )
&& ( peercred.cr_version == XUCRED_VERSION ))
{
*euid = peercred.cr_uid;
*egid = peercred.cr_gid;
return 0;
}
#elif defined( LDAP_PF_LOCAL_SENDMSG ) && defined( MSG_WAITALL )
int err, fd;
struct iovec iov;
struct msghdr msg = {0};
# ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
# ifndef CMSG_SPACE
# define CMSG_SPACE(len) (_CMSG_ALIGN(sizeof(struct cmsghdr)) + _CMSG_ALIGN(len))
# endif
# ifndef CMSG_LEN
# define CMSG_LEN(len) (_CMSG_ALIGN(sizeof(struct cmsghdr)) + (len))
# endif
struct {
struct cmsghdr cm;
int fd;
} control_st;
struct cmsghdr *cmsg;
# endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
struct stat st;
struct sockaddr_un lname, rname;
ber_socklen_t llen, rlen;
rlen = sizeof(rname);
llen = sizeof(lname);
memset( &lname, 0, sizeof( lname ));
getsockname(s, (struct sockaddr *)&lname, &llen);
iov.iov_base = peerbv->bv_val;
iov.iov_len = peerbv->bv_len;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
peerbv->bv_len = 0;
# ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
msg.msg_control = &control_st;
msg.msg_controllen = sizeof( struct cmsghdr ) + sizeof( int ); /* no padding! */
cmsg = CMSG_FIRSTHDR( &msg );
# else
msg.msg_accrights = (char *)&fd;
msg.msg_accrightslen = sizeof(fd);
# endif
/*
* AIX returns a bogus file descriptor if recvmsg() is
* called with MSG_PEEK (is this a bug?). Hence we need
* to receive the Abandon PDU.
*/
err = recvmsg( s, &msg, MSG_WAITALL );
if( err >= 0 &&
# ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
cmsg->cmsg_len == CMSG_LEN( sizeof(int) ) &&
cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_RIGHTS
# else
msg.msg_accrightslen == sizeof(int)
# endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL*/
) {
int mode = S_IFIFO|S_ISUID|S_IRWXU;
//.........这里部分代码省略.........
开发者ID:dago,项目名称:openldap,代码行数:101,代码来源:getpeereid.c
示例10: port_share_sendmsg
/*
* Send a command (char), data (head), and a file descriptor (sd_send) to a local process
* over unix socket sd. Unfortunately, there's no portable way to send file descriptors
* to other processes, so this code, as well as its analog (control_message_from_parent below),
* is Linux-specific. This function runs in the context of the main process and is used to
* send commands, data, and file descriptors to the background process.
*/
static void
port_share_sendmsg (const socket_descriptor_t sd,
const char command,
const struct buffer *head,
const socket_descriptor_t sd_send)
{
if (socket_defined (sd))
{
struct msghdr mesg;
struct cmsghdr* h;
struct iovec iov[2];
socket_descriptor_t sd_null[2] = { SOCKET_UNDEFINED, SOCKET_UNDEFINED };
char cmd;
ssize_t status;
dmsg (D_PS_PROXY_DEBUG, "PORT SHARE: sendmsg sd=%d len=%d",
(int)sd_send,
head ? BLEN(head) : -1);
CLEAR (mesg);
cmd = command;
iov[0].iov_base = &cmd;
iov[0].iov_len = sizeof (cmd);
mesg.msg_iovlen = 1;
if (head)
{
iov[1].iov_base = BPTR (head);
iov[1].iov_len = BLEN (head);
mesg.msg_iovlen = 2;
}
mesg.msg_iov = iov;
mesg.msg_controllen = cmsg_size ();
mesg.msg_control = (char *) malloc (mesg.msg_controllen);
check_malloc_return (mesg.msg_control);
mesg.msg_flags = 0;
h = CMSG_FIRSTHDR(&mesg);
h->cmsg_level = SOL_SOCKET;
h->cmsg_type = SCM_RIGHTS;
h->cmsg_len = CMSG_LEN(sizeof(socket_descriptor_t));
if (socket_defined (sd_send))
{
*((socket_descriptor_t*)CMSG_DATA(h)) = sd_send;
}
else
{
socketpair (PF_UNIX, SOCK_DGRAM, 0, sd_null);
*((socket_descriptor_t*)CMSG_DATA(h)) = sd_null[0];
}
status = sendmsg (sd, &mesg, MSG_NOSIGNAL);
if (status == -1)
msg (M_WARN, "PORT SHARE: sendmsg failed (unable to communicate with background process)");
close_socket_if_defined (sd_null[0]);
close_socket_if_defined (sd_null[1]);
free (mesg.msg_control);
}
}
开发者ID:OPSF,项目名称:uClinux,代码行数:72,代码来源:ps.c
示例11: uv__write
/* On success returns NULL. On error returns a pointer to the write request
* which had the error.
*/
static void uv__write(uv_stream_t* stream) {
uv_write_t* req;
struct iovec* iov;
int iovcnt;
ssize_t n;
start:
assert(stream->fd >= 0);
/* Get the request at the head of the queue. */
req = uv_write_queue_head(stream);
if (!req) {
assert(stream->write_queue_size == 0);
return;
}
assert(req->handle == stream);
/*
* Cast to iovec. We had to have our own uv_buf_t instead of iovec
* because Windows's WSABUF is not an iovec.
*/
assert(sizeof(uv_buf_t) == sizeof(struct iovec));
iov = (struct iovec*) &(req->bufs[req->write_index]);
iovcnt = req->bufcnt - req->write_index;
/*
* Now do the actual writev. Note that we've been updating the pointers
* inside the iov each time we write. So there is no need to offset it.
*/
if (req->send_handle) {
struct msghdr msg;
char scratch[64];
struct cmsghdr *cmsg;
int fd_to_send = req->send_handle->fd;
assert(fd_to_send >= 0);
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = iov;
msg.msg_iovlen = iovcnt;
msg.msg_flags = 0;
msg.msg_control = (void*) scratch;
msg.msg_controllen = CMSG_LEN(sizeof(fd_to_send));
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = msg.msg_controllen;
*(int*) CMSG_DATA(cmsg) = fd_to_send;
do {
n = sendmsg(stream->fd, &msg, 0);
}
while (n == -1 && errno == EINTR);
} else {
do {
if (iovcnt == 1) {
n = write(stream->fd, iov[0].iov_base, iov[0].iov_len);
} else {
n = writev(stream->fd, iov, iovcnt);
}
}
while (n == -1 && errno == EINTR);
}
if (n < 0) {
if (errno != EAGAIN) {
/* Error */
req->error = errno;
stream->write_queue_size -= uv__write_req_size(req);
uv__write_req_finish(req);
return;
} else if (stream->blocking) {
/* If this is a blocking stream, try again. */
goto start;
}
} else {
/* Successful write */
/* Update the counters. */
while (n >= 0) {
uv_buf_t* buf = &(req->bufs[req->write_index]);
size_t len = buf->len;
assert(req->write_index < req->bufcnt);
if ((size_t)n < len) {
buf->base += n;
buf->len -= n;
stream->write_queue_size -= n;
n = 0;
//.........这里部分代码省略.........
开发者ID:HenryRawas,项目名称:libuv,代码行数:101,代码来源:stream.c
示例12: main
int
main(int argc, char *argv[])
{
struct msghdr msgh;
struct iovec iov;
struct ucred *ucredp, ucred;
int data, lfd, sfd, optval, opt;
ssize_t nr;
Boolean useDatagramSocket;
union {
struct cmsghdr cmh;
char control[CMSG_SPACE(sizeof(struct ucred))];
/* Space large enough to hold a ucred structure */
} control_un;
struct cmsghdr *cmhp;
socklen_t len;
/* Parse command-line arguments */
useDatagramSocket = FALSE;
while ((opt = getopt(argc, argv, "d")) != -1) {
switch (opt) {
case 'd':
useDatagramSocket = TRUE;
break;
default:
usageErr("%s [-d]\n"
" -d use datagram socket\n", argv[0]);
}
}
/* Create socket bound to well-known address */
if (remove(SOCK_PATH) == -1 && errno != ENOENT)
errExit("remove-%s", SOCK_PATH);
if (useDatagramSocket) {
printf("Receiving via datagram socket\n");
sfd = unixBind(SOCK_PATH, SOCK_DGRAM);
if (sfd == -1)
errExit("unixBind");
} else {
printf("Receiving via stream socket\n");
lfd = unixListen(SOCK_PATH, 5);
if (lfd == -1)
errExit("unixListen");
sfd = accept(lfd, NULL, NULL);
if (sfd == -1)
errExit("accept");
}
/* We must set the SO_PASSCRED socket option in order to receive
credentials */
optval = 1;
if (setsockopt(sfd, SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval)) == -1)
errExit("setsockopt");
/* Set 'control_un' to describe ancillary data that we want to receive */
control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred));
control_un.cmh.cmsg_level = SOL_SOCKET;
control_un.cmh.cmsg_type = SCM_CREDENTIALS;
/* Set 'msgh' fields to describe 'control_un' */
msgh.msg_control = control_un.control;
msgh.msg_controllen = sizeof(control_un.control);
/* Set fields of 'msgh' to point to buffer used to receive (real)
data read by recvmsg() */
msgh.msg_iov = &iov;
msgh.msg_iovlen = 1;
iov.iov_base = &data;
iov.iov_len = sizeof(int);
msgh.msg_name = NULL; /* We don't need address of peer */
msgh.msg_namelen = 0;
/* Receive real plus ancillary data */
nr = recvmsg(sfd, &msgh, 0);
if (nr == -1)
errExit("recvmsg");
printf("recvmsg() returned %ld\n", (long) nr);
if (nr > 0)
printf("Received data = %d\n", data);
/* Extract credentials information from received ancillary data */
cmhp = CMSG_FIRSTHDR(&msgh);
if (cmhp == NULL || cmhp->cmsg_len != CMSG_LEN(sizeof(struct ucred)))
fatal("bad cmsg header / message length");
if (cmhp->cmsg_level != SOL_SOCKET)
//.........这里部分代码省略.........
开发者ID:MarkTseng,项目名称:mySampleCode,代码行数:101,代码来源:scm_cred_recv.c
示例13: main
int
main(int argc, char *argv[])
{
struct msghdr msgh;
struct iovec iov;
int data, lfd, sfd, fd, opt;
ssize_t nr;
Boolean useDatagramSocket;
union {
struct cmsghdr cmh;
char control[CMSG_SPACE(sizeof(int))];
/* Space large enough to hold an 'int' */
} control_un;
struct cmsghdr *cmhp;
/* Parse command-line arguments */
useDatagramSocket = FALSE;
while ((opt = getopt(argc, argv, "d")) != -1) {
switch (opt) {
case 'd':
useDatagramSocket = TRUE;
break;
default:
usageErr("%s [-d]\n"
" -d use datagram socket\n", argv[0]);
}
}
/* Create socket bound to well-known address */
if (remove(SOCK_PATH) == -1 && errno != ENOENT)
errExit("remove-%s", SOCK_PATH);
if (useDatagramSocket) {
fprintf(stderr, "Receiving via datagram socket\n");
sfd = unixBind(SOCK_PATH, SOCK_DGRAM);
if (sfd == -1)
errExit("unixBind");
} else {
fprintf(stderr, "Receiving via stream socket\n");
lfd = unixListen(SOCK_PATH, 5);
if (lfd == -1)
errExit("unixListen");
sfd = accept(lfd, NULL, 0);
if (sfd == -1)
errExit("accept");
}
/* Set 'control_un' to describe ancillary data that we want to receive */
control_un.cmh.cmsg_len = CMSG_LEN(sizeof(int));
control_un.cmh.cmsg_level = SOL_SOCKET;
control_un.cmh.cmsg_type = SCM_RIGHTS;
/* Set 'msgh' fields to describe 'control_un' */
msgh.msg_control = control_un.control;
msgh.msg_controllen = sizeof(control_un.control);
/* Set fields of 'msgh' to point to buffer used to receive (real)
data read by recvmsg() */
msgh.msg_iov = &iov;
msgh.msg_iovlen = 1;
iov.iov_base = &data;
iov.iov_len = sizeof(int);
msgh.msg_name = NULL; /* We don't need address of peer */
msgh.msg_namelen = 0;
/* Receive real plus ancillary data */
nr = recvmsg(sfd, &msgh, 0);
if (nr == -1)
errExit("recvmsg");
fprintf(stderr, "recvmsg() returned %ld\n", (long) nr);
if (nr > 0)
fprintf(stderr, "Received data = %d\n", data);
/* Get the received file descriptor (which is typically a different
file descriptor number than was used in the sending process) */
cmhp = CMSG_FIRSTHDR(&msgh);
if (cmhp == NULL || cmhp->cmsg_len != CMSG_LEN(sizeof(int)))
fatal("bad cmsg header / message length");
if (cmhp->cmsg_level != SOL_SOCKET)
fatal("cmsg_level != SOL_SOCKET");
if (cmhp->cmsg_type != SCM_RIGHTS)
fatal("cmsg_type != SCM_RIGHTS");
fd = *((int *) CMSG_DATA(cmhp));
fprintf(stderr, "Received fd=%d\n", fd);
/* Having obtained the file descriptor, read the file's contents and
//.........这里部分代码省略.........
开发者ID:XHelloWorldX,项目名称:LinuxSyetemProg,代码行数:101,代码来源:scm_rights_recv.c
示例14: send_to_from
ssize_t FAST_FUNC
send_to_from(int fd, void *buf, size_t len, int flags,
const struct sockaddr *to,
const struct sockaddr *from,
socklen_t tolen)
{
#ifndef IP_PKTINFO
(void)from; /* suppress "unused from" warning */
return sendto(fd, buf, len, flags, to, tolen);
#else
struct iovec iov[1];
struct msghdr msg;
union {
char cmsg[CMSG_SPACE(sizeof(struct in_pktinfo))];
# if ENABLE_FEATURE_IPV6 && defined(IPV6_PKTINFO)
char cmsg6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
# endif
} u;
struct cmsghdr* cmsgptr;
if (from->sa_family != AF_INET
# if ENABLE_FEATURE_IPV6
&& from->sa_family != AF_INET6
# endif
) {
/* ANY local address */
return sendto(fd, buf, len, flags, to, tolen);
}
/* man recvmsg and man cmsg is needed to make sense of code below */
iov[0].iov_base = buf;
iov[0].iov_len = len;
memset(&u, 0, sizeof(u));
memset(&msg, 0, sizeof(msg));
msg.msg_name = (void *)(struct sockaddr *)to; /* or compiler will annoy us */
msg.msg_namelen = tolen;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_control = &u;
msg.msg_controllen = sizeof(u);
msg.msg_flags = flags;
cmsgptr = CMSG_FIRSTHDR(&msg);
if (to->sa_family == AF_INET && from->sa_family == AF_INET) {
struct in_pktinfo *pktptr;
cmsgptr->cmsg_level = IPPROTO_IP;
cmsgptr->cmsg_type = IP_PKTINFO;
cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
pktptr = (struct in_pktinfo *)(CMSG_DATA(cmsgptr));
/*pktptr->ipi_ifindex = 0; -- already done by memset(u...) */
/* In general, CMSG_DATA() can be unaligned, but in this case
* we know for sure it is sufficiently aligned:
* CMSG_FIRSTHDR simply returns &u above,
* and CMSG_DATA returns &u + size_t + int + int.
* Thus direct assignment is ok:
*/
pktptr->ipi_spec_dst = ((struct sockaddr_in*)from)->sin_addr;
}
# if ENABLE_FEATURE_IPV6 && defined(IPV6_PKTINFO)
else if (to->sa_family == AF_INET6 && from->sa_family == AF_INET6) {
struct in6_pktinfo *pktptr;
cmsgptr->cmsg_level = IPPROTO_IPV6;
cmsgptr->cmsg_type = IPV6_PKTINFO;
cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
pktptr = (struct in6_pktinfo *)(CMSG_DATA(cmsgptr));
/* pktptr->ipi6_ifindex = 0; -- already done by memset(u...) */
pktptr->ipi6_addr = ((struct sockaddr_in6*)from)->sin6_addr;
}
# endif
msg.msg_controllen = cmsgptr->cmsg_len;
return sendmsg(fd, &msg, flags);
#endif
}
开发者ID:jameshilliard,项目名称:WECB-BH-GPL,代码行数:77,代码来源:udp_io.c
示例15: do_recvmsg
int do_recvmsg(message *dev_m_in, message *dev_m_out)
{
int minor;
int rc;
struct msg_control msg_ctrl;
socklen_t controllen_avail = 0;
socklen_t controllen_needed = 0;
socklen_t controllen_desired = 0;
#if DEBUG == 1
static int call_count = 0;
printf("(uds) [%d] do_sendmsg() call_count=%d\n",
uds_minor(dev_m_in), ++call_count);
#endif
minor = uds_minor(dev_m_in);
#if DEBUG == 1
printf("(uds) [%d] CREDENTIALS {pid:%d,uid:%d,gid:%d}\n", minor,
uds_fd_table[minor].ancillary_data.cred.pid,
uds_fd_table[minor].ancillary_data.cred.uid,
uds_fd_table[minor].ancillary_data.cred.gid);
#endif
memset(&msg_ctrl, '\0', sizeof(struct msg_control));
/* get the msg_control from the user, it will include the
* amount of space the user has allocated for control data.
*/
rc = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT,
(vir_bytes) 0, (vir_bytes) &msg_ctrl,
sizeof(struct msg_control));
if (rc != OK) {
return EIO;
}
controllen_avail = MIN(msg_ctrl.msg_controllen, MSG_CONTROL_MAX);
if (uds_fd_table[minor].ancillary_data.nfiledes > 0) {
controllen_needed = CMSG_LEN(sizeof(int) *
(uds_fd_table[minor].ancillary_data.nfiledes));
}
/* if there is room we also include credentials */
controllen_desired = controllen_needed +
CMSG_LEN(sizeof(struct ucred));
if (controllen_needed > controllen_avail) {
return EOVERFLOW;
}
rc = recv_fds(minor, &uds_fd_table[minor].ancillary_data, &msg_ctrl);
if (rc != OK) {
return rc;
}
if (controllen_desired <= controllen_avail) {
rc = recv_cred(minor, &uds_fd_table[minor].ancillary_data,
&msg_ctrl);
if (rc != OK) {
return rc;
}
}
/* send the user the control data */
rc = sys_safecopyto(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT,
(vir_bytes) 0, (vir_bytes) &msg_ctrl,
sizeof(struct msg_control));
return rc ? EIO : OK;
}
开发者ID:AjeyBohare,项目名称:minix,代码行数:73,代码来源:uds.c
示例16: g_unix_credentials_message_deserialize
static GSocketControlMessage *
g_unix_credentials_message_deserialize (gint level,
gint type,
gsize size,
gpointer data)
{
GSocketControlMessage *message;
message = NULL;
#ifdef __linux__
{
GCredentials *credentials;
struct ucred *ucred;
if (level != SOL_SOCKET || type != SCM_CREDENTIALS)
goto out;
if (size != sizeof (struct ucred))
{
g_warning ("Expected a struct ucred (%" G_GSIZE_FORMAT " bytes) but "
"got %" G_GSIZE_FORMAT " bytes of data",
sizeof (struct ucred),
size);
goto out;
}
ucred = data;
if (ucred->uid == (uid_t)-1 &&
ucred->gid == (gid_t)-1)
{
/* This happens if the remote side didn't pass the credentials */
goto out;
}
credentials = g_credentials_new ();
g_credentials_set_native (credentials, G_CREDENTIALS_TYPE_LINUX_UCRED, ucred);
message = g_unix_credentials_message_new_with_credentials (credentials);
g_object_unref (credentials);
out:
;
}
#elif defined(__FreeBSD__)
{
GCredentials *credentials;
struct cmsgcred *cred;
if (level != SOL_SOCKET || type != SCM_CREDS)
{
goto out;
}
if (size < sizeof *cred)
{
g_warning ("Expected a struct cmsgcred (%" G_GSIZE_FORMAT " bytes) but "
"got %" G_GSIZE_FORMAT " bytes of data",
CMSG_LEN (sizeof *cred),
size);
goto out;
}
cred = data;
credentials = g_credentials_new ();
g_credentials_set_native (credentials, G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED, cred);
message = g_unix_credentials_message_new_with_credentials (credentials);
g_object_unref (credentials);
out:
;
}
#endif
return message;
}
开发者ID:01org,项目名称:android-bluez-glib,代码行数:74,代码来源:gunixcredentialsmessage.c
示例17: send_r
int send_r(int sk, int stream, int order, int send_size, int assoc_i)
{
int error = 0;
struct msghdr outmsg;
struct iovec iov;
char *message = NULL;
int msglen = 0;
char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
struct cmsghdr *cmsg;
struct sctp_sndrcvinfo *sinfo;
if (send_size > 0) {
message = build_msg(send_size);
msglen = strlen(message) + 1;
iov.iov_base = message;
iov.iov_len = msglen;
}
else {
if (do_exit) {
exit(1);
} else {
goto error_out;
}
}
outmsg.msg_name = &s_rem;
outmsg.msg_namelen = sizeof(struct sockaddr_storage);
outmsg.msg_iov = &iov;
outmsg.msg_iovlen = 1;
outmsg.msg_control = outcmsg;
outmsg.msg_controllen = sizeof(outcmsg);
outmsg.msg_flags = 0;
cmsg = CMSG_FIRSTHDR(&outmsg);
cmsg->cmsg_level = IPPROTO_SCTP;
cmsg->cmsg_type = SCTP_SNDRCV;
cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
outmsg.msg_controllen = cmsg->cmsg_len;
sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
memset(sinfo, 0, sizeof(struct sctp_sndrcvinfo));
sinfo->sinfo_ppid = rand();
sinfo->sinfo_stream = stream;
sinfo->sinfo_flags = 0;
if (!order)
sinfo->sinfo_flags = SCTP_UNORDERED;
DEBUG_PRINT(DEBUG_MIN, "\tsendmsg(sk=%d, assoc=%d) %4d bytes.\n",
sk, assoc_i, send_size);
DEBUG_PRINT(DEBUG_MAX, "\t SNDRCV");
if (DEBUG_MAX == debug_level) {
printf("(stream=%u ", sinfo->sinfo_stream);
printf("flags=0x%x ", sinfo->sinfo_flags);
printf("ppid=%u\n", sinfo->sinfo_ppid);
}
/* Send to our neighbor. */
error = sendmsg(sk, &outmsg, MSG_WAITALL);
if (error != msglen) {
fprintf(stderr, "\n\t\t*** sendmsg: %s ***\n\n",
strerror(errno));
fflush(stdout);
if (do_exit) {
exit(1);
} else {
if (!drain)
goto error_out;
}
}
if (send_size > 0) free(message);
return 0;
error_out:
if (send_size > 0) free(message);
return -1;
} /* send_r() */
< |
请发表评论