DragonFly bugs List (threaded) for 2009-09
DragonFly BSD
DragonFly bugs List (threaded) for 2009-09
[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]

Re: [issue1471] Linux emulation: trouble with shared libraries


From: Francois Tigeot <ftigeot@xxxxxxxxxxxx>
Date: Wed, 2 Sep 2009 11:20:25 +0200

On Tue, Sep 01, 2009 at 04:13:50PM +0000, Alex Hornung (via DragonFly issue tracker) wrote:
> 
> Alex Hornung <ahornung@gmail.com> added the comment:
> 
> A test program showing the problem with linux_getdents (if it occurs with it) 
> would be helpful, too.

Unfortunately, I don't know enough about userland system programming to create
one.

Howewer, I have tracked the bug to this commit:
http://gitweb.dragonflybsd.org/dragonfly.git/commit/e54488bbec5c9f80e95cedd395b0e3d31fde253d
"AMD64 - Refactor uio_resid and size_t assumptions."

The attached patch allows the Linux ls(1) is again able to list files.
It is to be applied in /usr/src/sys/emulation/linux and basically reverts
linux_file.c to the previous version, with enough changes to make it compile
in a recent trunk.

Think of it as a quick-and-dirty hack, there were many more changes in the
Linux emulation files which I haven't yet reviewed.

-- 
Francois Tigeot
--- linux_file.c.orig	2009-09-02 10:26:44 +0200
+++ linux_file.c	2009-09-02 10:32:42 +0200
@@ -75,7 +75,7 @@
 	error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
 	if (error == 0) {
 		error = kern_open(&nd, O_WRONLY | O_CREAT | O_TRUNC,
-				  args->mode, &args->sysmsg_iresult);
+				    args->mode, &args->sysmsg_result);
 	}
 	linux_free_path(&path);
 	return(error);
@@ -135,14 +135,14 @@
 	error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
 	if (error == 0) {
 		error = kern_open(&nd, flags,
-				  args->mode, &args->sysmsg_iresult);
+				    args->mode, &args->sysmsg_result);
 	}
 
 	if (error == 0 && !(flags & O_NOCTTY) && 
 		SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
 		struct file *fp;
 
-		fp = holdfp(p->p_fd, args->sysmsg_iresult, -1);
+		fp = holdfp(p->p_fd, args->sysmsg_result, -1);
 		if (fp) {
 			if (fp->f_type == DTYPE_VNODE)
 				fo_ioctl(fp, TIOCSCTTY, NULL, p->p_ucred, NULL);
@@ -202,9 +202,9 @@
 	lda.fd = args->fd;
 	lda.dent = args->dent;
 	lda.count = -1;
-	lda.sysmsg_iresult = 0;
+	lda.sysmsg_result = 0;
 	error = sys_linux_getdents(&lda);
-	args->sysmsg_iresult = lda.sysmsg_iresult;
+	args->sysmsg_result = lda.sysmsg_result;
 	return(error);
 }
 
@@ -245,11 +245,9 @@
 	struct dirent *bdp;
 	struct vnode *vp;
 	caddr_t inp, buf;		/* BSD-format */
-	int reclen;			/* BSD-format */
-	size_t len;
+	int len, reclen;		/* BSD-format */
 	caddr_t outp;			/* Linux-format */
-	int linuxreclen = 0;		/* Linux-format */
-	size_t resid;
+	int resid, linuxreclen=0;	/* Linux-format */
 	struct file *fp;
 	struct uio auio;
 	struct iovec aiov;
@@ -257,8 +255,7 @@
 	off_t off;
 	struct l_dirent linux_dirent;
 	struct l_dirent64 linux_dirent64;
-	int error, eofflag, justone;
-	size_t buflen, nbytes;
+	int buflen, error, eofflag, nbytes, justone;
 	off_t *cookies = NULL, *cookiep;
 	int ncookies;
 
@@ -282,7 +279,7 @@
 		goto done;
 
 	nbytes = args->count;
-	if (nbytes == (size_t)-1) {
+	if (nbytes == -1) {
 		/* readdir(2) case. Always struct dirent. */
 		if (is64bit) {
 			error = EINVAL;
@@ -293,7 +290,7 @@
 	} else {
 		justone = 0;
 	}
-	if ((size_t)nbytes < 0)
+	if (nbytes < 0)
 		nbytes = 0;
 
 	off = fp->f_offset;
@@ -327,9 +324,9 @@
 	inp = buf;
 	outp = (caddr_t)args->dirent;
 	resid = nbytes;
-	if (auio.uio_resid >= buflen);
+	if ((len = buflen - auio.uio_resid) <= 0)
 		goto eof;
-	len = buflen - auio.uio_resid;
+
 	cookiep = cookies;
 
 	if (cookies) {
@@ -440,7 +437,7 @@
 		nbytes = resid + linuxreclen;
 
 eof:
-	args->sysmsg_iresult = (int)(nbytes - resid);
+	args->sysmsg_result = nbytes - resid;
 
 out:
 	if (cookies)
@@ -692,7 +689,7 @@
 	error = nlookup_init(&nd, path, UIO_SYSSPACE, 0);
 	if (error == 0) {
 		error = kern_readlink(&nd, args->buf, args->count,
-				      &args->sysmsg_iresult);
+					&args->sysmsg_result);
 	}
 	nlookup_done(&nd);
 	linux_free_path(&path);
@@ -814,10 +811,10 @@
 	int error;
 
 	bsd.fd = uap->fd;
-	bsd.sysmsg_iresult = 0;
+	bsd.sysmsg_result = 0;
 
 	error = sys_fsync(&bsd);
-	uap->sysmsg_iresult = bsd.sysmsg_iresult;
+	uap->sysmsg_result = bsd.sysmsg_result;
 	return(error);
 }
 
@@ -839,12 +836,10 @@
 	auio.uio_segflg = UIO_USERSPACE;
 	auio.uio_td = td;
 
-	if ((ssize_t)auio.uio_resid < 0) {
+	if (auio.uio_resid < 0)
 		error = EINVAL;
-	} else {
-		error = kern_preadv(uap->fd, &auio, O_FOFFSET,
-				    &uap->sysmsg_szresult);
-	}
+	else
+		error = kern_preadv(uap->fd, &auio, O_FOFFSET, &uap->sysmsg_result);
 	return(error);
 }
 
@@ -866,12 +861,11 @@
         auio.uio_segflg = UIO_USERSPACE;
         auio.uio_td = td;
 
-	if ((ssize_t)auio.uio_resid < 0) {
+	if (auio.uio_resid < 0)
 		error = EINVAL;
-	} else {
-		error = kern_pwritev(uap->fd, &auio, O_FOFFSET,
-				     &uap->sysmsg_szresult);
-	}
+	else
+		error = kern_pwritev(uap->fd, &auio, O_FOFFSET, &uap->sysmsg_result);
+
 	return(error);
 }
 
@@ -883,9 +877,9 @@
 
 	args2.path = args->path;
 	args2.flags = 0;
-	args2.sysmsg_iresult = 0;
+	args2.sysmsg_result = 0;
 	error = sys_linux_umount(&args2);
-	args->sysmsg_iresult = args2.sysmsg_iresult;
+	args->sysmsg_result = args2.sysmsg_result;
 	return(error);
 }
 
@@ -897,10 +891,10 @@
 
 	bsd.path = args->path;
 	bsd.flags = args->flags;	/* XXX correct? */
-	bsd.sysmsg_iresult = 0;
+	bsd.sysmsg_result = 0;
 
 	error = sys_unmount(&bsd);
-	args->sysmsg_iresult = bsd.sysmsg_iresult;
+	args->sysmsg_result = bsd.sysmsg_result;
 	return(error);
 }
 
@@ -1087,29 +1081,29 @@
 	if (error == 0) {
 		switch (args->cmd) {
 		case LINUX_F_DUPFD:
-			args->sysmsg_iresult = dat.fc_fd;
+			args->sysmsg_result = dat.fc_fd;
 			break;
 		case LINUX_F_GETFD:
-			args->sysmsg_iresult = dat.fc_cloexec;
+			args->sysmsg_result = dat.fc_cloexec;
 			break;
 		case LINUX_F_SETFD:
 			break;
 		case LINUX_F_GETFL:
-			args->sysmsg_iresult = 0;
+			args->sysmsg_result = 0;
 			if (dat.fc_flags & O_RDONLY)
-				args->sysmsg_iresult |= LINUX_O_RDONLY;
+				args->sysmsg_result |= LINUX_O_RDONLY;
 			if (dat.fc_flags & O_WRONLY)
-				args->sysmsg_iresult |= LINUX_O_WRONLY;
+				args->sysmsg_result |= LINUX_O_WRONLY;
 			if (dat.fc_flags & O_RDWR)
-				args->sysmsg_iresult |= LINUX_O_RDWR;
+				args->sysmsg_result |= LINUX_O_RDWR;
 			if (dat.fc_flags & O_NDELAY)
-				args->sysmsg_iresult |= LINUX_O_NONBLOCK;
+				args->sysmsg_result |= LINUX_O_NONBLOCK;
 			if (dat.fc_flags & O_APPEND)
-				args->sysmsg_iresult |= LINUX_O_APPEND;
+				args->sysmsg_result |= LINUX_O_APPEND;
 			if (dat.fc_flags & O_FSYNC)
-				args->sysmsg_iresult |= LINUX_O_SYNC;
+				args->sysmsg_result |= LINUX_O_SYNC;
 			if (dat.fc_flags & O_ASYNC)
-				args->sysmsg_iresult |= LINUX_FASYNC;
+				args->sysmsg_result |= LINUX_FASYNC;
 			break;
 		case LINUX_F_GETLK:
 			bsd_to_linux_flock(&dat.fc_flock, &linux_flock);
@@ -1120,7 +1114,7 @@
 		case LINUX_F_SETLKW:
 			break;
 		case LINUX_F_GETOWN:
-			args->sysmsg_iresult = dat.fc_owner;
+			args->sysmsg_result = dat.fc_owner;
 			break;
 		case LINUX_F_SETOWN:
 			break;
@@ -1144,9 +1138,9 @@
 	args64.fd = args->fd;
 	args64.cmd = args->cmd;
 	args64.arg = args->arg;
-	args64.sysmsg_iresult = 0;
+	args64.sysmsg_result = 0;
 	error = linux_fcntl_common(&args64);
-	args->sysmsg_iresult = args64.sysmsg_iresult;
+	args->sysmsg_result = args64.sysmsg_result;
 	return(error);
 }
 


[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]