我有以下代码:
#include <netinet/in.h>
#include <fcntl.h>
#include <stdio.h>
int main (void) {
int fd_s=socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
struct sockaddr_in info_s = {.sin_family=AF_INET,.sin_port=htons(1024),.sin_zero={0,0,0,0,0,0,0},.sin_addr.s_addr=0};
bind(fd_s,&info_s,sizeof(info_s));
listen(fd_s,1);
int info_s_len=sizeof(struct sockaddr_in);
int fd_c;
struct sockaddr_in info_c;
while((fd_c=accept(fd_s, &info_c,&info_s_len))){
printf("client connected.\n");
if(!fork()){
int fd=open("log", O_RDWR|O_CREAT|O_APPEND|O_SYNC);
int p0[2],p1[2],p2[2];pipe2(p0, O_NONBLOCK);pipe2(p1, O_NONBLOCK);pipe2(p2, O_NONBLOCK);
dup2(p0[0], 0);
dup2(p1[1], 1);
dup2(p2[1], 2);
if(!fork()){
system("/bin/sh");
close(p0[0]);close(p0[1]);close(p1[0]);close(p1[1]);close(p2[0]);close(p2[1]);
close(fd_c);
close(fd);
printf("client disconnected.");
exit(0);
}else{
fd_set rd,wr;int on=1;//fcntl(fd_c, O_NONBLOCK, &on);
//char b[50];fwrite("ls;",3,1,fp_);fgets(b,50,fp_);printf(b);
FD_ZERO(&rd);FD_ZERO(&wr);
FD_SET(p1[0], &rd);FD_SET(p2[1],&rd);FD_SET(p0[1],&wr);FD_SET(fd_c, &rd);FD_SET(fd_c,&wr);
char *b=0; int bl,i;
while(select(p2[1]+1,&rd,&wr,0,0)){
char c;
if(FD_ISSET(fd_c,&rd)) {
b=realloc(b, 1*sizeof(char));
for(i=0,bl=1*sizeof(char);recv(fd_c,b+i,1,0)==1;i++,bl+=sizeof(char)){b=realloc(b, bl);}
write(p0[1],b,bl);
write(fd,b,bl);
free(b);
b=0;
}else if(FD_ISSET(p1[0],&rd)){
b=realloc(b, 1*sizeof(char));
for(i=0,bl=0;read(p0[0],b+i,1)>0;i++,bl+=sizeof(char)){b=realloc(b, bl);}
send(fd_c,b,bl,0);
write(fd,b,bl);
free(b);b=0;
}else if(FD_ISSET(p2[0],&rd)){
for(i=0,bl=0;read(p2[0],b+i,1)>0;i++,bl+=sizeof(char)){b=realloc(b, bl);}
send(fd_c,b,bl,0);
write(fd,b,bl);
free(b);b=0;
}
FD_ZERO(&rd);FD_ZERO(&wr);
FD_SET(p1[0], &rd);FD_SET(p2[1],&rd);FD_SET(p0[1],&wr);FD_SET(fd_c, &rd);FD_SET(fd_c,&wr);
}
}
}
}
return 0;
}
我做的时候
telnet localhost 1024
我的守护进程产生/bin/sh
,所有发送的命令都保存到文件log
。
但是,当我写(例如)时:id;
我的守护进程没有回到客户端,也没有进入log
文件。
我错过了什么?
P.D:当客户端断开关闭功能时,代码需要一些,我将在找到倾倒姿势时添加。
感谢。
答案 0 :(得分:0)
execve()
不会返回。
因此,此次通话下方的所有行都没有到达。
使用system()
以便在孩子退出后继续:
The value returned is -1 on error (e.g. fork(2) failed), and the
return status of the command otherwise. This latter return status is
in the format specified in wait(2). Thus, the exit code of the command
will be WEXITSTATUS(status). In case /bin/sh could not be executed,
the exit status will be that of a command that does exit(127).
If the value of command is NULL, system() returns nonzero if the shell
is available, and zero if not.
system() does not affect the wait status of any other children.
答案 1 :(得分:0)
以下是我的解决方案。
#include <netinet/in.h>
#include <fcntl.h>
#include <stdio.h>
int
main (void)
{
int fd_s = socket (AF_INET, SOCK_STREAM, IPPROTO_IP);
struct sockaddr_in info_s = {.sin_family = AF_INET,.sin_port =
htons (1024),.sin_zero = {0, 0, 0, 0, 0, 0, 0},.sin_addr.s_addr = 0
};
bind (fd_s, &info_s, sizeof (info_s));
listen (fd_s, 1);
int info_s_len = sizeof (struct sockaddr_in);
int fd_c;
struct sockaddr_in info_c;
while ((fd_c = accept (fd_s, &info_c, &info_s_len)))
{
printf ("client connected.\n");
if (!fork ())
{
int fd = open ("log", O_WRONLY | O_CREAT | O_APPEND);
int pty, tty;
char *name;
openpty (&pty, &tty, NULL, NULL, NULL);
name = ttyname (tty);
int p0[2], p1[2], p2[2];
pipe (p0);
pipe2 (p1, O_NONBLOCK);
pipe2 (p2, O_NONBLOCK);
dup2 (tty, 0);
dup2 (tty, 1);
dup2 (tty, 2);
dup2 (p0[0], 0);
dup2 (p1[1], 1);
dup2 (p2[1], 2);
if (!fork ())
{
system ("/bin/sh");
close (p0[0]);
close (p0[1]);
close (p1[0]);
close (p1[1]);
close (p2[0]);
close (p2[1]);
close (fd_c);
close (fd);
// some log
exit (0);
}
else
{
fd_set rd, wr;
fcntl (fd_c, F_SETFL, O_NONBLOCK);
FD_ZERO (&rd);
FD_ZERO (&wr);
FD_SET (p1[0], &rd);
FD_SET (p2[0], &rd);
FD_SET (fd_c, &rd);
char *b = 0;
int bl, i;
while (select (p2[1] + 1, &rd, &wr, 0, 0))
{
char c;
if (FD_ISSET (fd_c, &rd))
{
for (i = bl = b = 0; 1; i++)
{
char c;
int ret = recv (fd_c, &c, sizeof (c), 0);
if (ret == sizeof (c))
{
bl += sizeof (char);
b = realloc (b, bl);
b[i] = c;
}
else if (ret == 0)
{
close (fd_c);
free (b);
exit (0);
}
else if (ret == -1)
{
write (p0[1], b, bl);
write (fd, b, bl);
free (b);
break;
}
}
}
else if (FD_ISSET (p1[0], &rd))
{
for (i = bl = b = 0; 1; i++)
{
char c;
int ret = read (p1[0], &c, sizeof (c));
if (ret == sizeof (c))
{
bl += sizeof (c);
b = realloc (b, bl);
b[i] = c;
}
else if (ret == -1)
{
send (fd_c, b, bl, 0);
write (fd, b, bl);
free (b);
break;
}
else
{
}
}
}
else if (FD_ISSET (p2[0], &rd))
{
for (i = bl = b = 0; 1; i++)
{
char c;
int ret = read (p2[0], &c, sizeof (c));
if (ret == sizeof (c))
{
bl += sizeof (c);
b = realloc (b, bl);
b[i] = c;
}
else if (ret == -1)
{
send (fd_c, b, bl, 0);
write (fd, b, bl);
free (b);
break;
}
}
}
FD_ZERO (&rd);
FD_ZERO (&wr);
FD_SET (p1[0], &rd);
FD_SET (p2[0], &rd);
FD_SET (fd_c, &rd);
}
}
}
}
return 0;
}
非常感谢...