Subject: kern/22038: Fix to linux emulation to handle trailing slashes
To: None <gnats-bugs@gnats.netbsd.org>
From: None <murray@river-styx.org>
List: netbsd-bugs
Date: 07/03/2003 02:16:37
>Number:         22038
>Category:       kern
>Synopsis:       Fix to linux emulation to handle trailing slashes
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Thu Jul 03 02:17:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     Murray Armfield
>Release:        NetBSD-current
>Organization:
>Environment:
NetBSD enterprise 1.6U NetBSD 1.6U (ENTERPRISE.MP) #0: Mon Jun 30 17:47:36 EST 2003 admin@enterprise:/usr/obj/sys/arch/i386/compile/ENTERPRISE.MP i386
>Description:
A couple of linux programs I have been playing around with make use of the mkdir syscall. As many of us know, linux programs are often in the habit of appending a trailing slash to a directory path. This is not handled by the linux emulation code and consequently I have hacked linux programs to create required directories before starting. I have heard of others who have the same issue.

I have included a patch that works for me to handle the trailing slash in pathnames passed to the linux_sys_mkdir function. I may have done this incorrectly, so please review attached patch.

This patch may not be in the best place. I don't know if other OS's handle the trailing slash pathname feature, but if they do, a more common location for the fix would probably be better.

Feel free to modify the patch as I am not a regular NetBSD kernel coder and have used a different style of variable naming. Also the memory allocation should probably only be done if required. This is easy to do.

BTW, can this be backported to NetBSD-1.6.x please.
>How-To-Repeat:
Try running linux Neverwinter Nights on NetBSD, with additional required linux libraries. The program creates and deletes directories in order to execute properly. 
>Fix:
--- compat/linux/common/linux_file.c.orig       2003-07-03 12:10:15.000000000 +1000
+++ compat/linux/common/linux_file.c
@@ -890,11 +890,29 @@ linux_sys_mkdir(l, v, retval)
                syscallarg(int) mode;
        } */ *uap = v;
        struct proc *p = l->l_proc;
-       caddr_t sg = stackgap_init(p, 0);
+       struct sys_mkdir_args bla;
+       char *correctedpath;
+       size_t pathlen = strlen(SCARG(uap, path)) - 1;
+       caddr_t sg = stackgap_init(p, 0);
+       int result;
+
+       correctedpath = (char*) malloc(pathlen * sizeof(char), M_TEMP, M_WAITOK);
+       if (SCARG(uap, path)[pathlen] == '/')   {
+               strncpy(correctedpath, SCARG(uap, path), pathlen);
+               correctedpath[pathlen] = '\0';
+               SCARG(&bla, path) = correctedpath;
+       } else {
+               SCARG(&bla, path) = SCARG(uap, path);
+       }
+       SCARG(&bla, mode) = SCARG(uap, mode);

-       CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
+       CHECK_ALT_CREAT(p, &sg, SCARG(&bla, path));
+
+       result = sys_mkdir(l, &bla, retval);
+
+       free(correctedpath, M_TEMP);

-       return sys_mkdir(l, uap, retval);
+       return result;
 }
>Release-Note:
>Audit-Trail:
>Unformatted: