TCSBRK implementation for linux compat

Konstantin Belousov kostikbel at gmail.com
Fri Oct 26 05:05:21 UTC 2012


On Thu, Oct 25, 2012 at 09:17:39PM +0200, Marcin Mazur wrote:
> Hi.
> 
> I needed suport for this feature in FreeBSD linux emulation, because I
> have to use precompiled linux library/binary that uses it. There was a
> lot of errors in logs like:
> 
> 
> "... ioctl fd=52, cmd=0x5409 ('T',9) is not implemented"
> 
> I could not find any help so I had to do that by myself
> 
> I found implementation in NetBSD sources, and just 'translated' it to
> the FreeBSD
> 
> There is my work:
> 
> -------------------------
> --- linux_ioctl.orig    2012-08-06 01:54:33.000000000 +0200
> +++ linux_ioctl.c       2012-10-25 13:59:12.000000000 +0200
> @@ -778,8 +778,26 @@
>                     td));
>                 break;
> 
> -       /* LINUX_TCSBRK */
> -
> +       case LINUX_TCSBRK:
> +               if (args->arg)
> +                   {
> +                       args->cmd = TIOCDRAIN;
> +                       error = (sys_ioctl(td, (struct ioctl_args *)args));
> +                       break;
> +                   }
> +               else
> +                   {
> +                       if ((error = fo_ioctl(fp, TIOCSBRK, NULL,
> td->td_ucred,td)) != 0)
> +                           break;
> +                       error = tsleep(&args->arg, PZERO | PCATCH,
> "linux_tcsbrk", hz / 4);
> +                       if (error == EINTR || error == ERESTART) {
> +                           fo_ioctl(fp, TIOCCBRK, NULL, td->td_ucred, td);
> +                           error = EINTR;
> +                       } else
> +                           error = fo_ioctl (fp, TIOCCBRK, NULL,
> td->td_ucred, td);
> +                       break;
> +                   }
> +
>         case LINUX_TCXONC: {
>                 switch (args->arg) {
>                 case LINUX_TCOOFF:
> --------------------
> Could someone have a look at this if the code is correct?
> Sorry but I do not have kernel developing experience and this is my first patch
> I'm testing this patch for over 20 hours now and it seems to work
> well. No errors, load average dropped from 2.5 to 0.5
> Please CC me, I'am not on the list.
> And sorry for my bad english...


This looks good, below is the commit candidate. I did small changes
according to style and my taste. The biggest is the removal of PZERO
from tsleep flags, which is actually shall not be used, since it changes
the thread priority (instead of usual assumption that the value is to
preserve the current priority).

diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c
index 0a9cd27..5ebf7ed 100644
--- a/sys/compat/linux/linux_ioctl.c
+++ b/sys/compat/linux/linux_ioctl.c
@@ -699,7 +699,7 @@ linux_ioctl_termio(struct thread *td, struct linux_ioctl_args *args)
 	struct linux_termios lios;
 	struct linux_termio lio;
 	struct file *fp;
-	int error;
+	int error, error1;
 
 	if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0)
 		return (error);
@@ -778,7 +778,27 @@ linux_ioctl_termio(struct thread *td, struct linux_ioctl_args *args)
 		    td));
 		break;
 
-	/* LINUX_TCSBRK */
+	case LINUX_TCSBRK:
+		/*
+		 * Non-zero argument is interpreted as the request to
+		 * perform tcdrain().
+		 * Zero argument means tcsendbreak().
+		 */
+		if (args->arg != 0)
+			error = fo_ioctl(fp, TIOCDRAIN, NULL, td->td_ucred, td);
+		else {
+			error = fo_ioctl(fp, TIOCSBRK, NULL, td->td_ucred, td);
+			if (error != 0)
+				break;
+			error = tsleep(&args->arg, PCATCH, "linux_tcsbrk",
+			    hz / 4);
+			error1 = fo_ioctl(fp, TIOCCBRK, NULL, td->td_ucred, td);
+			if (error == EINTR || error == ERESTART)
+				error = EINTR;
+			else
+				error = error1;
+		}
+		break;
 
 	case LINUX_TCXONC: {
 		switch (args->arg) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
URL: <http://lists.freebsd.org/pipermail/freebsd-emulation/attachments/20121026/8f8ab099/attachment.sig>


More information about the freebsd-emulation mailing list