#include <stdio.h>
#include <sys/types.h>
#include <stropts.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "common.h"
#define FIFO_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
int
my_recv_fd(
int
servfd) {
int
newfd, nread, flag, status;
char
*ptr, buf[MAXLINE];
struct
strbuf dat;
struct
strrecvfd recvfd;
status = -1;
dat.buf = buf;
dat.maxlen = MAXLINE;
flag = 0;
if
(getmsg(servfd, NULL, &dat, &flag) < 0) {
fprintf
(stderr,
"getmsg error\n"
);
return
(-1); }
nread = dat.len;
if
(nread == 0) {
fprintf
(stderr,
"connection closed by server"
);
return
(-1);
}
for
(ptr = buf; ptr < &buf[nread]; ) {
if
(*ptr++ == 0) {
if
(ptr != &buf[nread-1]) {
fprintf
(stderr,
"message format error"
);
return
(-1); }
status = *ptr & 255;
if
(status == 0) {
if
(ioctl(servfd, I_RECVFD, &recvfd) < 0)
return
(-1);
newfd = recvfd.fd;
}
else
newfd = -status;
nread -= 2;
}
}
if
(nread > 0)
if
(write(STDERR_FILENO, buf, nread) != nread)
return
(-1);
if
(status >= 0)
return
(newfd);
}
int
my_send_fd(
int
clifd,
int
fd) {
char
buf[2];
buf[0] = 0;
if
(fd < 0) {
buf[1] = -fd;
if
(buf[1] == 0) buf[1] = 1;
}
else
{
buf[1] = 0;
}
if
(write(clifd, buf, 2) != 2)
return
(-1);
if
(fd >= 0)
if
(ioctl(clifd, I_SENDFD, fd) < 0)
return
(-1);
return
(0);
}
int
cli_conn(
const
char
*name) {
int
fd;
if
( (fd = open(name, O_RDWR)) < 0)
return
(-1);
if
(isastream(fd) == 0)
return
(-2);
return
(fd);
}
int
my_serv_accept(
int
listenfd) {
struct
strrecvfd recvfd;
if
(ioctl(listenfd, I_RECVFD, &recvfd) < 0)
return
(-1);
return
(recvfd.fd);
}
int
bind_to_fs(
int
fd,
const
char
*name) {
int
tempfd;
if
( (tempfd = creat(name, FIFO_MODE)) < 0)
return
0;
if
(close(tempfd) < 0)
return
0;
if
(ioctl(fd, I_PUSH,
"connld"
) < 0)
return
0;
if
(fattach(fd, name) < 0)
return
0;
return
1;
}
int
my_isastream(
int
fd) {
return
isastream(fd); }
int
my_getfl(
int
fd) {
return
fcntl(fd,F_GETFL); }