| nde 回复于:2003-12-01 09:35:53
|
顶一下
|
| 蓝色键盘 回复于:2003-12-01 12:17:21
|
read和write对应管道的fd0和fd1。
|
| nde 回复于:2003-12-01 13:21:40
|
[quote:1d477501ee="蓝色键盘"]read和write对应管道的fd0和fd1。[/quote:1d477501ee]
命名的流管道以一个文件名的形式存在,用open打开这个文件名只能得到一个fd,何来fd[0]、fd[1]?
是不是要连续open两次?
|
| nde 回复于:2003-12-01 13:31:34
|
按照open两次的思路改了一下程序,结果还是同样的错误
进程1:
fd0=open("nspfile",O_RDONLY);
fd1=open("nspfile",O_WRONLY);
read( fd0, buf, 10 ); // fail,errno=5
进程2:
fd0=open("nspfile",O_RDONLY);
fd1=open("nspfile",O_WRONLY);
write( fd1, buf, 10 ); // success
运行结果是进程2的write正确,但是进程1的read出错,errno=5,I/O错误
|
| nde 回复于:2003-12-01 14:35:37
|
补充说明:
以上代码的目的是进程1和进程2通过命名流管道nspfile通讯,进程2发送数据给进程1。nspfile是事先创建好的并以一个文件形式存在的命名流管道。
|
| mmHunter 回复于:2003-12-01 23:16:08
|
建议参考一下postfix的源代码,stream部分写的挺好的...
|
| nde 回复于:2003-12-02 09:30:16
|
[quote:4c6ece04a7="mmHunter"]建议参考一下postfix的源代码,stream部分写的挺好的...[/quote:4c6ece04a7]
多谢你的建议。postfix我不太熟,是否使用到SVR3.2的流管道也不清楚,所以我不打算花时间去看源码了。
SCO OpenServer 5是SVR3.2的版本,支持的是/dev/spx流管道,与SVR4的pipe和BSD的socketpair不同。
我想试的是SCO OpenServer 5的/dev/spx流管道。根据man spx中提供的源码已经成功创建了命名流管道,但是如何open/read/write在man spx中没有提及,我试过各种方法都不成功,怀疑可能是BUG。
SVR3.2的流管道没什么人用,实在搞不定就算了,仅仅是研究探讨一下。
|
| mmHunter 回复于:2003-12-02 10:51:51
|
postfix就是用了流管道,不过如果不是很大量很大量的通讯,没有必要采用流管道,unix domain socket就行,移植性也好...
|
| nde 回复于:2003-12-02 13:08:08
|
[quote:d8f17ef08a="mmHunter"]postfix就是用了流管道,不过如果不是很大量很大量的通讯,没有必要采用流管道,unix domain socket就行,移植性也好...[/quote:d8f17ef08a]
我查了postfix源码,用的是命名管道FIFO,没有使用/dev/spx命名流管道,因为/dev/spx是SVR3.2特有的,一般代码考虑移植性是不会使用。
|
| mmHunter 回复于:2003-12-02 13:25:30
|
哦,我想当然了... postfix用的是I_SENDFD方式的流...
另外,精华区有相关的文章,挺详细的呀?http://chinaunix.net/jh/23/107530.html
|
| nde 回复于:2003-12-02 15:03:49
|
[quote:f6b9b3cf61="mmHunter"]哦,我想当然了... postfix用的是I_SENDFD方式的流...
另外,精华区有相关的文章,挺详细的呀?http://chinaunix.net/jh/23/107530.html[/quote:f6b9b3cf61]
你真是个热心人,多谢了。
那篇文章我看过,作者蓝色键盘,这个帖子题目就是想请教他的。那篇文章的主要内容就是man spx输出的结果。其中uname stream pipe“无名”流管道的部分我已试验过OK,进一步试验named stream pipe“有名”流管道时遇到问题-create/open/write OK,read errno=5。这是man spx以及那篇文章中都没有提到的。我用google搜索过/dev/spx都没有找到相关信息。
|
| gadfly 回复于:2003-12-04 15:28:51
|
可惜我没有sco的环境。
不过我看了一下说明,通过spx建立无名管道,需要打开这个设备两次,
并通过ioctl对这两个描述符建立对应的联系。之后就和通常的pipe操作一样了。希望以下的代码对你有所帮助,并且,也讲述到了如何通过spx建立有名管道,以及传递文件描述符。
http://osr5doc.ca.caldera.com:457/cgi-bin/man/man?spx+HW
[code:1:88fbac74fc]
Examples
A routine to create an unnamed bi-directional stream pipe in the manner of pipe(S):
#include <unistd.h>
#include <sys/types.h>
#include <sys/fcntl.h>
#include <sys/stream.h>
#include <sys/stropts.h>
#include <sys/stat.h>
#include <termio.h>
#include <signal.h>
#define SPX "/dev/spx"
int spipe(fd)
int *fd;
{
struct strfdinsert s;
long p;
if ( ( fd[0] = open(SPX, O_RDWR) ) < 0 )
return(-1);
if ( ( fd[1] = open(SPX, O_RDWR) ) < 0 ) /* open different minor */
return(-1);
s.ctlbuf.buf = (caddr_t) &p ;
s.ctlbuf.maxlen = s.ctlbuf.len = sizeof(long);
s.databuf.buf = (caddr_t) NULL;
s.databuf.maxlen = s.databuf.len = -1;
s.fildes = fd[1];
s.offset = s.flags = 0;
if ( ioctl(fd[0], I_FDINSERT, &s) < 0 ) /* join loop drivers */
return(-1);
return(0);
}
A routine to create a named stream pipe from a unnamed one (this requires root privilege):
int nspipe(fd, pipename)
int *fd;
char *pipename;
{
struct stat status;
int omask;
if ( spipe(fd) < 0 )
return(-1);
if ( fstat(fd[0],&status) < 0 )
return(-1);
unlink(pipename);
omask = umask(0);
if ( mknod(pipename, S_IFCHR|0666, status.st_rdev) < 0 ) /* create node */
return(-1);
umask(omask);
return(0);
}
A routine to pass a file descriptor to another process:
int passfd(fd, sendfd)
int fd, sendfd;
{
if ( ioctl(fd, I_SENDFD, sendfd) < 0 ) /* send descriptor sendfd */
return(-1);
}
A routine to receive a file descriptor from a process:
int recvfd(fd)
int fd;
{
struct strrecvfd s;
if ( ioctl(fd, I_RECVFD, (char *) &s) < 0 )
return(-1);
/* s.uid received effective user ID of sender
s.gid received effective group ID of sender */
return(s.fd); /* received file descriptor */
}
[/code:1:88fbac74fc]
|