全部博文(41)
分类: LINUX
2009-08-25 17:17:56
tcp.c文件的tcp_ioctl函数
978计划工作组
int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
{
int err;
switch(cmd)
{
case TIOCINQ:
#ifdef FIXME /* FIXME: */
case FIONREAD:
#endif {
unsigned long amount;
if (sk->state == TCP_LISTEN)
return(-EINVAL);
sk->inuse = 1;
amount = tcp_readable(sk);
release_sock(sk);
err=verify_area(VERIFY_WRITE,(void *)arg,
sizeof(unsigned long));
if(err)
return err;
put_fs_long(amount,(unsigned long *)arg);
return(0);
}
case SIOCATMARK:
{
int answ = sk->urg_data && sk->urg_seq == sk->copied_seq;
err = verify_area(VERIFY_WRITE,(void *) arg,
sizeof(unsigned long));
if (err)
return err;
put_fs_long(answ,(int *) arg);
return(0);
}
case TIOCOUTQ:
{
unsigned long amount;
if (sk->state == TCP_LISTEN) return(-EINVAL);
amount = sk->prot->wspace(sk);
err=verify_area(VERIFY_WRITE,(void *)arg,
sizeof(unsigned long));
if(err)
return err;
put_fs_long(amount,(unsigned long *)arg);
return(0);
}
default:
return(-EINVAL);
}
}
查询相关信息。
TIOCINQ/ FIONREAD:宏值为0x541B,用于查询下一个可读取数据包中数据长度。
SIOCATMARK:宏值为0x8905,用于判断下一个将要读取得数据是否为urgent 数据。。
TIOCOUTQ:宏值为0x5411,用于检测当前发送缓冲区中空闲空间大小。
VERIFY_WRITE:宏值为1,访问类型是写类型。
arg:用于返回函数的执行结果。
verify_area:验证参数地址空间是否存在,根据参数验证是否可读(VERIFY_READ)或可写(VERIFY_WRITE)。
put_fs_long:将第一个参数的值赋给第二个参数。
amount:可读取的数据字节数。
answ:为1表示接收到了紧急数据且下一个要读取的就是紧急数据。
sk->urg_seq:值为紧急数据的序列号,而非紧急标志的序列号。