1 /* $Id: timod.c,v 1.19 2002/02/08 03:57:14 davem Exp $
2 * timod.c: timod emulation.
4 * Copyright (C) 1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)
6 * Streams & timod emulation based on code
7 * Copyright (C) 1995, 1996 Mike Jagdis (jaggy@purplet.demon.co.uk)
11 #include <linux/types.h>
12 #include <linux/kernel.h>
13 #include <linux/sched.h>
14 #include <linux/smp.h>
15 #include <linux/smp_lock.h>
16 #include <linux/ioctl.h>
18 #include <linux/file.h>
19 #include <linux/netdevice.h>
20 #include <linux/poll.h>
24 #include <asm/uaccess.h>
25 #include <asm/termios.h>
30 asmlinkage
int solaris_ioctl(unsigned int fd
, unsigned int cmd
, u32 arg
);
32 static DEFINE_SPINLOCK(timod_pagelock
);
33 static char * page
= NULL
;
35 #ifndef DEBUG_SOLARIS_KMALLOC
37 #define mykmalloc kmalloc
42 void * mykmalloc(size_t s
, int gfp
)
49 SOLD("too big size, calling real kmalloc");
50 return kmalloc(s
, gfp
);
53 /* we are wasting memory, but we don't care */
54 page
= (char *)__get_free_page(gfp
);
71 #define BUF_SIZE PAGE_SIZE
72 #define PUT_MAGIC(a,m)
73 #define SCHECK_MAGIC(a,m)
75 #define MKCTL_TRAILER 0
79 #define BUF_SIZE (PAGE_SIZE-2*sizeof(u64))
80 #define BUFPAGE_MAGIC 0xBADC0DEDDEADBABEL
81 #define MKCTL_MAGIC 0xDEADBABEBADC0DEDL
82 #define PUT_MAGIC(a,m) do{(*(u64*)(a))=(m);}while(0)
83 #define SCHECK_MAGIC(a,m) do{if((*(u64*)(a))!=(m))printk("%s,%u,%s(): magic %08x at %p corrupted!\n",\
84 __FILE__,__LINE__,__FUNCTION__,(m),(a));}while(0)
85 #define BUF_OFFSET sizeof(u64)
86 #define MKCTL_TRAILER sizeof(u64)
90 static char *getpage( void )
94 spin_lock(&timod_pagelock
);
98 spin_unlock(&timod_pagelock
);
100 return r
+ BUF_OFFSET
;
102 spin_unlock(&timod_pagelock
);
104 r
= (char *)__get_free_page(GFP_KERNEL
);
105 PUT_MAGIC(r
,BUFPAGE_MAGIC
);
106 PUT_MAGIC(r
+PAGE_SIZE
-sizeof(u64
),BUFPAGE_MAGIC
);
107 return r
+ BUF_OFFSET
;
110 static void putpage(char *p
)
112 SOLD("putting page");
114 SCHECK_MAGIC(p
,BUFPAGE_MAGIC
);
115 SCHECK_MAGIC(p
+PAGE_SIZE
-sizeof(u64
),BUFPAGE_MAGIC
);
116 spin_lock(&timod_pagelock
);
118 spin_unlock(&timod_pagelock
);
119 free_page((unsigned long)p
);
123 spin_unlock(&timod_pagelock
);
128 static struct T_primsg
*timod_mkctl(int size
)
132 SOLD("creating primsg");
133 it
= (struct T_primsg
*)mykmalloc(size
+sizeof(*it
)-sizeof(s32
)+2*MKCTL_TRAILER
, GFP_KERNEL
);
138 PUT_MAGIC((char*)((u64
)(((char *)&it
->type
)+size
+7)&~7),MKCTL_MAGIC
);
143 static void timod_wake_socket(unsigned int fd
)
147 SOLD("wakeing socket");
148 sock
= SOCKET_I(current
->files
->fd
[fd
]->f_dentry
->d_inode
);
149 wake_up_interruptible(&sock
->wait
);
150 read_lock(&sock
->sk
->sk_callback_lock
);
151 if (sock
->fasync_list
&& !test_bit(SOCK_ASYNC_WAITDATA
, &sock
->flags
))
152 __kill_fasync(sock
->fasync_list
, SIGIO
, POLL_IN
);
153 read_unlock(&sock
->sk
->sk_callback_lock
);
157 static void timod_queue(unsigned int fd
, struct T_primsg
*it
)
159 struct sol_socket_struct
*sock
;
161 SOLD("queuing primsg");
162 sock
= (struct sol_socket_struct
*)current
->files
->fd
[fd
]->private_data
;
163 it
->next
= sock
->pfirst
;
167 timod_wake_socket(fd
);
171 static void timod_queue_end(unsigned int fd
, struct T_primsg
*it
)
173 struct sol_socket_struct
*sock
;
175 SOLD("queuing primsg at end");
176 sock
= (struct sol_socket_struct
*)current
->files
->fd
[fd
]->private_data
;
179 sock
->plast
->next
= it
;
186 static void timod_error(unsigned int fd
, int prim
, int terr
, int uerr
)
190 SOLD("making error");
191 it
= timod_mkctl(sizeof(struct T_error_ack
));
193 struct T_error_ack
*err
= (struct T_error_ack
*)&it
->type
;
196 err
->PRIM_type
= T_ERROR_ACK
;
197 err
->ERROR_prim
= prim
;
198 err
->TLI_error
= terr
;
199 err
->UNIX_error
= uerr
; /* FIXME: convert this */
205 static void timod_ok(unsigned int fd
, int prim
)
210 SOLD("creating ok ack");
211 it
= timod_mkctl(sizeof(*ok
));
214 ok
= (struct T_ok_ack
*)&it
->type
;
215 ok
->PRIM_type
= T_OK_ACK
;
216 ok
->CORRECT_prim
= prim
;
222 static int timod_optmgmt(unsigned int fd
, int flag
, char __user
*opt_buf
, int opt_len
, int do_ret
)
225 int ret_space
, ret_len
;
227 char *ret_pos
,*ret_buf
;
228 int (*sys_socketcall
)(int, unsigned long *) =
229 (int (*)(int, unsigned long *))SYS(socketcall
);
230 mm_segment_t old_fs
= get_fs();
233 SOLDD(("fd %u flg %u buf %p len %u doret %u",fd
,flag
,opt_buf
,opt_len
,do_ret
));
234 if (!do_ret
&& (!opt_buf
|| opt_len
<= 0))
236 SOLD("getting page");
237 ret_pos
= ret_buf
= getpage();
238 ret_space
= BUF_SIZE
;
243 while(opt_len
>= sizeof(struct opthdr
)) {
247 opt
= (struct opthdr
*)ret_pos
;
248 if (ret_space
< sizeof(struct opthdr
)) {
252 SOLD("getting opthdr");
253 if (copy_from_user(opt
, opt_buf
, sizeof(struct opthdr
)) ||
254 opt
->len
> opt_len
) {
259 if (flag
== T_NEGOTIATE
) {
262 SOLD("handling T_NEGOTIATE");
263 buf
= ret_pos
+ sizeof(struct opthdr
);
264 if (ret_space
< opt
->len
+ sizeof(struct opthdr
) ||
265 copy_from_user(buf
, opt_buf
+sizeof(struct opthdr
), opt
->len
)) {
271 args
[1] = opt
->level
;
275 SOLD("calling SETSOCKOPT");
277 error
= sys_socketcall(SYS_SETSOCKOPT
, args
);
283 SOLD("SETSOCKOPT ok");
285 orig_opt_len
= opt
->len
;
286 opt
->len
= ret_space
- sizeof(struct opthdr
);
292 args
[1] = opt
->level
;
294 args
[3] = (long)(ret_pos
+sizeof(struct opthdr
));
295 args
[4] = (long)&opt
->len
;
296 SOLD("calling GETSOCKOPT");
298 error
= sys_socketcall(SYS_GETSOCKOPT
, args
);
304 SOLD("GETSOCKOPT ok");
305 ret_space
-= sizeof(struct opthdr
) + opt
->len
;
306 ret_len
+= sizeof(struct opthdr
) + opt
->len
;
307 ret_pos
+= sizeof(struct opthdr
) + opt
->len
;
308 opt_len
-= sizeof(struct opthdr
) + orig_opt_len
;
309 opt_buf
+= sizeof(struct opthdr
) + orig_opt_len
;
314 SOLD("generating ret msg");
316 timod_error(fd
, T_OPTMGMT_REQ
, failed
, -error
);
319 it
= timod_mkctl(sizeof(struct T_optmgmt_ack
) + ret_len
);
321 struct T_optmgmt_ack
*ack
=
322 (struct T_optmgmt_ack
*)&it
->type
;
324 ack
->PRIM_type
= T_OPTMGMT_ACK
;
325 ack
->OPT_length
= ret_len
;
326 ack
->OPT_offset
= sizeof(struct T_optmgmt_ack
);
327 ack
->MGMT_flags
= (failed
? T_FAILURE
: flag
);
328 memcpy(((char*)ack
)+sizeof(struct T_optmgmt_ack
),
334 SOLDD(("put_page %p\n", ret_buf
));
340 int timod_putmsg(unsigned int fd
, char __user
*ctl_buf
, int ctl_len
,
341 char __user
*data_buf
, int data_len
, int flags
)
343 int ret
, error
, terror
;
347 struct sol_socket_struct
*sock
;
348 mm_segment_t old_fs
= get_fs();
350 int (*sys_socketcall
)(int, unsigned long __user
*) =
351 (int (*)(int, unsigned long __user
*))SYS(socketcall
);
352 int (*sys_sendto
)(int, void __user
*, size_t, unsigned, struct sockaddr __user
*, int) =
353 (int (*)(int, void __user
*, size_t, unsigned, struct sockaddr __user
*, int))SYS(sendto
);
354 filp
= current
->files
->fd
[fd
];
355 ino
= filp
->f_dentry
->d_inode
;
356 sock
= (struct sol_socket_struct
*)filp
->private_data
;
358 if (get_user(ret
, (int __user
*)A(ctl_buf
)))
363 struct T_bind_req req
;
365 SOLDD(("bind %016lx(%016lx)\n", sock
, filp
));
367 if (sock
->state
!= TS_UNBND
) {
368 timod_error(fd
, T_BIND_REQ
, TOUTSTATE
, 0);
372 if (copy_from_user(&req
, ctl_buf
, sizeof(req
))) {
373 timod_error(fd
, T_BIND_REQ
, TSYSERR
, EFAULT
);
377 if (req
.ADDR_offset
&& req
.ADDR_length
) {
378 if (req
.ADDR_length
> BUF_SIZE
) {
379 timod_error(fd
, T_BIND_REQ
, TSYSERR
, EFAULT
);
384 if (copy_from_user(buf
, ctl_buf
+ req
.ADDR_offset
, req
.ADDR_length
)) {
385 timod_error(fd
, T_BIND_REQ
, TSYSERR
, EFAULT
);
389 SOLD("got ctl data");
392 args
[2] = req
.ADDR_length
;
393 SOLD("calling BIND");
395 error
= sys_socketcall(SYS_BIND
, args
);
398 SOLD("BIND returned");
403 if (req
.CONIND_number
) {
405 args
[1] = req
.CONIND_number
;
406 SOLD("calling LISTEN");
408 error
= sys_socketcall(SYS_LISTEN
, args
);
412 it
= timod_mkctl(sizeof(struct T_bind_ack
)+sizeof(struct sockaddr
));
414 struct T_bind_ack
*ack
;
416 ack
= (struct T_bind_ack
*)&it
->type
;
417 ack
->PRIM_type
= T_BIND_ACK
;
418 ack
->ADDR_offset
= sizeof(*ack
);
419 ack
->ADDR_length
= sizeof(struct sockaddr
);
420 ack
->CONIND_number
= req
.CONIND_number
;
422 args
[1] = (long)(ack
+sizeof(*ack
));
423 args
[2] = (long)&ack
->ADDR_length
;
425 sys_socketcall(SYS_GETSOCKNAME
,args
);
427 sock
->state
= TS_IDLE
;
428 timod_ok(fd
, T_BIND_REQ
);
429 timod_queue_end(fd
, it
);
453 timod_error(fd
, T_BIND_REQ
, terror
, -error
);
459 struct T_conn_req req
;
460 unsigned short oldflags
;
463 if (sock
->state
!= TS_UNBND
&& sock
->state
!= TS_IDLE
) {
464 timod_error(fd
, T_CONN_REQ
, TOUTSTATE
, 0);
468 if (copy_from_user(&req
, ctl_buf
, sizeof(req
))) {
469 timod_error(fd
, T_CONN_REQ
, TSYSERR
, EFAULT
);
473 if (ctl_len
> BUF_SIZE
) {
474 timod_error(fd
, T_CONN_REQ
, TSYSERR
, EFAULT
);
479 if (copy_from_user(buf
, ctl_buf
, ctl_len
)) {
480 timod_error(fd
, T_CONN_REQ
, TSYSERR
, EFAULT
);
488 printk("returned data (%d bytes): ",len
);
492 printk("%02x",(unsigned char)*ptr
++);
497 SOLD("got ctl data");
499 args
[1] = (long)buf
+req
.DEST_offset
;
500 args
[2] = req
.DEST_length
;
501 oldflags
= filp
->f_flags
;
502 filp
->f_flags
&= ~O_NONBLOCK
;
503 SOLD("calling CONNECT");
505 error
= sys_socketcall(SYS_CONNECT
, args
);
507 filp
->f_flags
= oldflags
;
508 SOLD("CONNECT done");
510 struct T_conn_con
*con
;
512 it
= timod_mkctl(ctl_len
);
517 con
= (struct T_conn_con
*)&it
->type
;
522 printk("returned data (%d bytes): ",len
);
526 printk("%02x",(unsigned char)*ptr
++);
531 memcpy(con
, buf
, ctl_len
);
532 SOLD("copied ctl_buf");
533 con
->PRIM_type
= T_CONN_CON
;
534 sock
->state
= TS_DATA_XFER
;
536 struct T_discon_ind
*dis
;
538 it
= timod_mkctl(sizeof(*dis
));
544 dis
= (struct T_discon_ind
*)&it
->type
;
545 dis
->PRIM_type
= T_DISCON_IND
;
546 dis
->DISCON_reason
= -error
; /* FIXME: convert this as in iABI_errors() */
550 timod_ok(fd
, T_CONN_REQ
);
552 timod_queue_end(fd
, it
);
553 SOLD("CONNECT done");
558 struct T_optmgmt_req req
;
560 if (copy_from_user(&req
, ctl_buf
, sizeof(req
)))
563 return timod_optmgmt(fd
, req
.MGMT_flags
,
564 req
.OPT_offset
> 0 ? ctl_buf
+ req
.OPT_offset
: NULL
,
569 struct T_unitdata_req req
;
572 SOLD("T_UNITDATA_REQ");
573 if (sock
->state
!= TS_IDLE
&& sock
->state
!= TS_DATA_XFER
) {
574 timod_error(fd
, T_CONN_REQ
, TOUTSTATE
, 0);
578 if (copy_from_user(&req
, ctl_buf
, sizeof(req
))) {
579 timod_error(fd
, T_CONN_REQ
, TSYSERR
, EFAULT
);
585 char * ptr
= ctl_buf
+req
.DEST_offset
;
586 int len
= req
.DEST_length
;
587 printk("socket address (%d bytes): ",len
);
593 printk("%02x",(unsigned char)c
);
599 err
= sys_sendto(fd
, data_buf
, data_len
, 0, req
.DEST_length
> 0 ? (struct sockaddr __user
*)(ctl_buf
+req
.DEST_offset
) : NULL
, req
.DEST_length
);
603 printk("timod: sendto failed to send all the data\n");
606 timod_error(fd
, T_CONN_REQ
, TSYSERR
, -err
);
610 printk(KERN_INFO
"timod_putmsg: unsupported command %u.\n", ret
);
616 int timod_getmsg(unsigned int fd
, char __user
*ctl_buf
, int ctl_maxlen
, s32 __user
*ctl_len
,
617 char __user
*data_buf
, int data_maxlen
, s32 __user
*data_len
, int *flags_p
)
623 struct sol_socket_struct
*sock
;
624 struct T_unitdata_ind udi
;
625 mm_segment_t old_fs
= get_fs();
629 int (*sys_socketcall
)(int, unsigned long __user
*) =
630 (int (*)(int, unsigned long __user
*))SYS(socketcall
);
631 int (*sys_recvfrom
)(int, void __user
*, size_t, unsigned, struct sockaddr __user
*, int __user
*);
634 SOLDD(("%u %p %d %p %p %d %p %d\n", fd
, ctl_buf
, ctl_maxlen
, ctl_len
, data_buf
, data_maxlen
, data_len
, *flags_p
));
635 filp
= current
->files
->fd
[fd
];
636 ino
= filp
->f_dentry
->d_inode
;
637 sock
= (struct sol_socket_struct
*)filp
->private_data
;
638 SOLDD(("%p %p\n", sock
->pfirst
, sock
->pfirst
? sock
->pfirst
->next
: NULL
));
639 if ( ctl_maxlen
> 0 && !sock
->pfirst
&& SOCKET_I(ino
)->type
== SOCK_STREAM
640 && sock
->state
== TS_IDLE
) {
641 SOLD("calling LISTEN");
645 sys_socketcall(SYS_LISTEN
, args
);
649 if (!(filp
->f_flags
& O_NONBLOCK
)) {
650 struct poll_wqueues wait_table
;
653 poll_initwait(&wait_table
);
654 wait
= &wait_table
.pt
;
657 set_current_state(TASK_INTERRUPTIBLE
);
658 /* ! ( l<0 || ( l>=0 && ( ! pfirst || (flags == HIPRI && pri != HIPRI) ) ) ) */
659 /* ( ! l<0 && ! ( l>=0 && ( ! pfirst || (flags == HIPRI && pri != HIPRI) ) ) ) */
660 /* ( l>=0 && ( ! l>=0 || ! ( ! pfirst || (flags == HIPRI && pri != HIPRI) ) ) ) */
661 /* ( l>=0 && ( l<0 || ( pfirst && ! (flags == HIPRI && pri != HIPRI) ) ) ) */
662 /* ( l>=0 && ( l<0 || ( pfirst && (flags != HIPRI || pri == HIPRI) ) ) ) */
663 /* ( l>=0 && ( pfirst && (flags != HIPRI || pri == HIPRI) ) ) */
664 if (ctl_maxlen
>= 0 && sock
->pfirst
&& (*flags_p
!= MSG_HIPRI
|| sock
->pfirst
->pri
== MSG_HIPRI
))
666 SOLD("cond 1 passed");
669 *flags_p
!= MSG_HIPRI
&&
671 ((filp
->f_op
->poll(filp
, wait
) & POLLIN
) ||
672 (filp
->f_op
->poll(filp
, NULL
) & POLLIN
) ||
673 signal_pending(current
))
677 if( *flags_p
== MSG_HIPRI
) {
678 SOLD("avoiding lockup");
681 if(wait_table
.error
) {
682 SOLD("wait-table error");
683 poll_freewait(&wait_table
);
684 return wait_table
.error
;
690 current
->state
= TASK_RUNNING
;
691 poll_freewait(&wait_table
);
692 if (signal_pending(current
)) {
693 SOLD("signal pending");
697 if (ctl_maxlen
>= 0 && sock
->pfirst
) {
698 struct T_primsg
*it
= sock
->pfirst
;
699 int l
= min_t(int, ctl_maxlen
, it
->length
);
700 SCHECK_MAGIC((char*)((u64
)(((char *)&it
->type
)+sock
->offset
+it
->length
+7)&~7),MKCTL_MAGIC
);
701 SOLD("purting ctl data");
702 if(copy_to_user(ctl_buf
,
703 (char*)&it
->type
+ sock
->offset
, l
))
706 if(put_user(l
, ctl_len
))
716 SOLD("removing message");
717 sock
->pfirst
= it
->next
;
720 SOLDD(("getmsg kfree %016lx->%016lx\n", it
, sock
->pfirst
));
728 if (ctl_maxlen
>= 0) {
729 SOLD("ACCEPT perhaps?");
730 if (SOCKET_I(ino
)->type
== SOCK_STREAM
&& sock
->state
== TS_IDLE
) {
731 struct T_conn_ind ind
;
732 char *buf
= getpage();
735 SOLD("trying ACCEPT");
736 if (put_user(ctl_maxlen
- sizeof(ind
), ctl_len
))
740 args
[2] = (long)&len
;
741 oldflags
= filp
->f_flags
;
742 filp
->f_flags
|= O_NONBLOCK
;
743 SOLD("calling ACCEPT");
745 error
= sys_socketcall(SYS_ACCEPT
, args
);
747 filp
->f_flags
= oldflags
;
756 if (sizeof(ind
) > ctl_maxlen
) {
757 SOLD("generating CONN_IND");
758 ind
.PRIM_type
= T_CONN_IND
;
759 ind
.SRC_length
= len
;
760 ind
.SRC_offset
= sizeof(ind
);
761 ind
.OPT_length
= ind
.OPT_offset
= 0;
762 ind
.SEQ_number
= error
;
763 if(copy_to_user(ctl_buf
, &ind
, sizeof(ind
))||
764 put_user(sizeof(ind
)+ind
.SRC_length
,ctl_len
))
766 SOLD("CONN_IND created");
768 if (data_maxlen
>= 0)
769 put_user(0, data_len
);
770 SOLD("CONN_IND done");
773 if (len
>ctl_maxlen
) {
774 SOLD("data don't fit");
776 return -EFAULT
; /* XXX - is this ok ? */
778 if(copy_to_user(ctl_buf
,buf
,len
) || put_user(len
,ctl_len
)){
779 SOLD("can't copy data");
787 SOLD("checking data req");
788 if (data_maxlen
<= 0) {
789 if (data_maxlen
== 0)
790 put_user(0, data_len
);
792 put_user(0, ctl_len
);
796 if (ctl_maxlen
> sizeof(udi
) && sock
->state
== TS_IDLE
) {
798 tmpbuf
= ctl_buf
+ sizeof(udi
);
799 tmplen
= ctl_maxlen
- sizeof(udi
);
801 SOLD("udi does not fit");
805 if (put_user(tmplen
, ctl_len
))
808 oldflags
= filp
->f_flags
;
809 filp
->f_flags
|= O_NONBLOCK
;
810 SOLD("calling recvfrom");
811 sys_recvfrom
= (int (*)(int, void __user
*, size_t, unsigned, struct sockaddr __user
*, int __user
*))SYS(recvfrom
);
812 error
= sys_recvfrom(fd
, data_buf
, data_maxlen
, 0, (struct sockaddr __user
*)tmpbuf
, ctl_len
);
813 filp
->f_flags
= oldflags
;
816 SOLD("error >= 0" ) ;
817 if (error
&& ctl_maxlen
> sizeof(udi
) && sock
->state
== TS_IDLE
) {
818 SOLD("generating udi");
819 udi
.PRIM_type
= T_UNITDATA_IND
;
820 if (get_user(udi
.SRC_length
, ctl_len
))
822 udi
.SRC_offset
= sizeof(udi
);
823 udi
.OPT_length
= udi
.OPT_offset
= 0;
824 if (copy_to_user(ctl_buf
, &udi
, sizeof(udi
)) ||
825 put_user(sizeof(udi
)+udi
.SRC_length
, ctl_len
))
829 if (put_user(0, ctl_len
))
832 put_user(error
, data_len
);
837 asmlinkage
int solaris_getmsg(unsigned int fd
, u32 arg1
, u32 arg2
, u32 arg3
)
841 struct strbuf __user
*ctlptr
;
842 struct strbuf __user
*datptr
;
843 struct strbuf ctl
, dat
;
850 if(fd
>= NR_OPEN
) goto out
;
852 filp
= current
->files
->fd
[fd
];
855 ino
= filp
->f_dentry
->d_inode
;
856 if (!ino
|| !S_ISSOCK(ino
->i_mode
))
859 ctlptr
= (struct strbuf __user
*)A(arg1
);
860 datptr
= (struct strbuf __user
*)A(arg2
);
861 flgptr
= (int __user
*)A(arg3
);
866 if (copy_from_user(&ctl
,ctlptr
,sizeof(struct strbuf
)) ||
867 put_user(-1,&ctlptr
->len
))
873 if (copy_from_user(&dat
,datptr
,sizeof(struct strbuf
)) ||
874 put_user(-1,&datptr
->len
))
879 if (get_user(flags
,flgptr
))
893 error
= timod_getmsg(fd
,A(ctl
.buf
),ctl
.maxlen
,&ctlptr
->len
,
894 A(dat
.buf
),dat
.maxlen
,&datptr
->len
,&flags
);
896 if (!error
&& put_user(flags
,flgptr
))
904 asmlinkage
int solaris_putmsg(unsigned int fd
, u32 arg1
, u32 arg2
, u32 arg3
)
908 struct strbuf __user
*ctlptr
;
909 struct strbuf __user
*datptr
;
910 struct strbuf ctl
, dat
;
911 int flags
= (int) arg3
;
916 if(fd
>= NR_OPEN
) goto out
;
918 filp
= current
->files
->fd
[fd
];
921 ino
= filp
->f_dentry
->d_inode
;
924 if (!S_ISSOCK(ino
->i_mode
) &&
925 (imajor(ino
) != 30 || iminor(ino
) != 1))
934 if (copy_from_user(&ctl
,ctlptr
,sizeof(ctl
)))
936 if (ctl
.len
< 0 && flags
) {
946 if (copy_from_user(&dat
,datptr
,sizeof(dat
)))
953 error
= timod_putmsg(fd
,A(ctl
.buf
),ctl
.len
,
954 A(dat
.buf
),dat
.len
,flags
);