135#ifdef DEBUG 136 printf("Linux-emul(%d): open returns error %d\n", 137 p->p_pid, error); 138#endif 139 return error; 140} 141 142struct linux_flock { 143 short l_type; 144 short l_whence; 145 linux_off_t l_start; 146 linux_off_t l_len; 147 linux_pid_t l_pid; 148}; 149 150static void 151linux_to_bsd_flock(struct linux_flock *linux_flock, struct flock *bsd_flock) 152{ 153 switch (linux_flock->l_type) { 154 case LINUX_F_RDLCK: 155 bsd_flock->l_type = F_RDLCK; 156 break; 157 case LINUX_F_WRLCK: 158 bsd_flock->l_type = F_WRLCK; 159 break; 160 case LINUX_F_UNLCK: 161 bsd_flock->l_type = F_UNLCK; 162 break; 163 default: 164 bsd_flock->l_type = -1; 165 break; 166 } 167 bsd_flock->l_whence = linux_flock->l_whence; 168 bsd_flock->l_start = (off_t)linux_flock->l_start; 169 bsd_flock->l_len = (off_t)linux_flock->l_len; 170 bsd_flock->l_pid = (pid_t)linux_flock->l_pid; 171} 172 173static void 174bsd_to_linux_flock(struct flock *bsd_flock, struct linux_flock *linux_flock) 175{ 176 switch (bsd_flock->l_type) { 177 case F_RDLCK: 178 linux_flock->l_type = LINUX_F_RDLCK; 179 break; 180 case F_WRLCK: 181 linux_flock->l_type = LINUX_F_WRLCK; 182 break; 183 case F_UNLCK: 184 linux_flock->l_type = LINUX_F_UNLCK; 185 break; 186 } 187 linux_flock->l_whence = bsd_flock->l_whence; 188 linux_flock->l_start = (linux_off_t)bsd_flock->l_start; 189 linux_flock->l_len = (linux_off_t)bsd_flock->l_len; 190 linux_flock->l_pid = (linux_pid_t)bsd_flock->l_pid; 191} 192 193int 194linux_fcntl(struct proc *p, struct linux_fcntl_args *args) 195{ 196 int error, result; 197 struct fcntl_args /* { 198 int fd; 199 int cmd; 200 long arg; 201 } */ fcntl_args; 202 struct linux_flock linux_flock; 203 struct flock *bsd_flock; 204 struct filedesc *fdp; 205 struct file *fp; 206 caddr_t sg; 207 208 sg = stackgap_init(); 209 bsd_flock = (struct flock *)stackgap_alloc(&sg, sizeof(struct flock)); 210 211#ifdef DEBUG 212 printf("Linux-emul(%ld): fcntl(%d, %08x, *)\n", (long)p->p_pid, 213 args->fd, args->cmd); 214#endif 215 fcntl_args.fd = args->fd; 216 217 switch (args->cmd) { 218 case LINUX_F_DUPFD: 219 fcntl_args.cmd = F_DUPFD; 220 fcntl_args.arg = args->arg; 221 return fcntl(p, &fcntl_args); 222 223 case LINUX_F_GETFD: 224 fcntl_args.cmd = F_GETFD; 225 return fcntl(p, &fcntl_args); 226 227 case LINUX_F_SETFD: 228 fcntl_args.cmd = F_SETFD; 229 fcntl_args.arg = args->arg; 230 return fcntl(p, &fcntl_args); 231 232 case LINUX_F_GETFL: 233 fcntl_args.cmd = F_GETFL; 234 error = fcntl(p, &fcntl_args); 235 result = p->p_retval[0]; 236 p->p_retval[0] = 0; 237 if (result & O_RDONLY) p->p_retval[0] |= LINUX_O_RDONLY; 238 if (result & O_WRONLY) p->p_retval[0] |= LINUX_O_WRONLY; 239 if (result & O_RDWR) p->p_retval[0] |= LINUX_O_RDWR; 240 if (result & O_NDELAY) p->p_retval[0] |= LINUX_O_NONBLOCK; 241 if (result & O_APPEND) p->p_retval[0] |= LINUX_O_APPEND; 242 if (result & O_FSYNC) p->p_retval[0] |= LINUX_O_SYNC; 243 if (result & O_ASYNC) p->p_retval[0] |= LINUX_FASYNC; 244 return error; 245 246 case LINUX_F_SETFL: 247 fcntl_args.arg = 0; 248 if (args->arg & LINUX_O_NDELAY) fcntl_args.arg |= O_NONBLOCK; 249 if (args->arg & LINUX_O_APPEND) fcntl_args.arg |= O_APPEND; 250 if (args->arg & LINUX_O_SYNC) fcntl_args.arg |= O_FSYNC; 251 if (args->arg & LINUX_FASYNC) fcntl_args.arg |= O_ASYNC; 252 fcntl_args.cmd = F_SETFL; 253 return fcntl(p, &fcntl_args); 254 255 case LINUX_F_GETLK: 256 if ((error = copyin((caddr_t)args->arg, (caddr_t)&linux_flock, 257 sizeof(struct linux_flock)))) 258 return error; 259 linux_to_bsd_flock(&linux_flock, bsd_flock); 260 fcntl_args.cmd = F_GETLK; 261 fcntl_args.arg = (long)bsd_flock; 262 error = fcntl(p, &fcntl_args); 263 if (error) 264 return error; 265 bsd_to_linux_flock(bsd_flock, &linux_flock); 266 return copyout((caddr_t)&linux_flock, (caddr_t)args->arg, 267 sizeof(struct linux_flock)); 268 269 case LINUX_F_SETLK: 270 if ((error = copyin((caddr_t)args->arg, (caddr_t)&linux_flock, 271 sizeof(struct linux_flock)))) 272 return error; 273 linux_to_bsd_flock(&linux_flock, bsd_flock); 274 fcntl_args.cmd = F_SETLK; 275 fcntl_args.arg = (long)bsd_flock; 276 return fcntl(p, &fcntl_args); 277 278 case LINUX_F_SETLKW: 279 if ((error = copyin((caddr_t)args->arg, (caddr_t)&linux_flock, 280 sizeof(struct linux_flock)))) 281 return error; 282 linux_to_bsd_flock(&linux_flock, bsd_flock); 283 fcntl_args.cmd = F_SETLKW; 284 fcntl_args.arg = (long)bsd_flock; 285 return fcntl(p, &fcntl_args); 286 287 case LINUX_F_GETOWN: 288 fcntl_args.cmd = F_GETOWN; 289 return fcntl(p, &fcntl_args); 290 291 case LINUX_F_SETOWN: 292 /* 293 * XXX some Linux applications depend on F_SETOWN having no 294 * significant effect for pipes (SIGIO is not delivered for 295 * pipes under Linux-2.2.35 at least). 296 */ 297 fdp = p->p_fd; 298 if ((u_int)args->fd >= fdp->fd_nfiles || 299 (fp = fdp->fd_ofiles[args->fd]) == NULL) 300 return EBADF; 301 if (fp->f_type == DTYPE_PIPE) 302 return EINVAL; 303 304 fcntl_args.cmd = F_SETOWN; 305 fcntl_args.arg = args->arg; 306 return fcntl(p, &fcntl_args); 307 } 308 return EINVAL; 309} 310 311int 312linux_lseek(struct proc *p, struct linux_lseek_args *args) 313{ 314 315 struct lseek_args /* { 316 int fd; 317 int pad; 318 off_t offset; 319 int whence; 320 } */ tmp_args; 321 int error; 322 323#ifdef DEBUG 324 printf("Linux-emul(%ld): lseek(%d, %ld, %d)\n", 325 (long)p->p_pid, args->fdes, args->off, args->whence); 326#endif 327 tmp_args.fd = args->fdes; 328 tmp_args.offset = (off_t)args->off; 329 tmp_args.whence = args->whence; 330 error = lseek(p, &tmp_args); 331 return error; 332} 333 334#ifndef __alpha__ 335int 336linux_llseek(struct proc *p, struct linux_llseek_args *args) 337{ 338 struct lseek_args bsd_args; 339 int error; 340 off_t off; 341 342#ifdef DEBUG 343 printf("Linux-emul(%d): llseek(%d, %d:%d, %d)\n", 344 p->p_pid, args->fd, args->ohigh, args->olow, args->whence); 345#endif 346 off = (args->olow) | (((off_t) args->ohigh) << 32); 347 348 bsd_args.fd = args->fd; 349 bsd_args.offset = off; 350 bsd_args.whence = args->whence; 351 352 if ((error = lseek(p, &bsd_args))) 353 return error; 354 355 if ((error = copyout(p->p_retval, (caddr_t)args->res, sizeof (off_t)))) 356 return error; 357 358 p->p_retval[0] = 0; 359 return 0; 360} 361#endif /*!__alpha__*/ 362 363 364struct linux_dirent { 365 long dino; 366 linux_off_t doff; 367 unsigned short dreclen; 368 char dname[LINUX_NAME_MAX + 1]; 369}; 370 371#define LINUX_RECLEN(de,namlen) \ 372 ALIGN((((char *)&(de)->dname - (char *)de) + (namlen) + 1)) 373 374#ifndef __alpha__ 375int 376linux_readdir(struct proc *p, struct linux_readdir_args *args) 377{ 378 struct linux_getdents_args lda; 379 380 lda.fd = args->fd; 381 lda.dent = args->dent; 382 lda.count = 1; 383 return linux_getdents(p, &lda); 384} 385#endif /*!__alpha__*/ 386 387int 388linux_getdents(struct proc *p, struct linux_getdents_args *args) 389{ 390 register struct dirent *bdp; 391 struct vnode *vp; 392 caddr_t inp, buf; /* BSD-format */ 393 int len, reclen; /* BSD-format */ 394 caddr_t outp; /* Linux-format */ 395 int resid, linuxreclen=0; /* Linux-format */ 396 struct file *fp; 397 struct uio auio; 398 struct iovec aiov; 399 struct vattr va; 400 off_t off; 401 struct linux_dirent linux_dirent; 402 int buflen, error, eofflag, nbytes, justone; 403 u_long *cookies = NULL, *cookiep; 404 int ncookies;
| 138#ifdef DEBUG 139 printf("Linux-emul(%d): open returns error %d\n", 140 p->p_pid, error); 141#endif 142 return error; 143} 144 145struct linux_flock { 146 short l_type; 147 short l_whence; 148 linux_off_t l_start; 149 linux_off_t l_len; 150 linux_pid_t l_pid; 151}; 152 153static void 154linux_to_bsd_flock(struct linux_flock *linux_flock, struct flock *bsd_flock) 155{ 156 switch (linux_flock->l_type) { 157 case LINUX_F_RDLCK: 158 bsd_flock->l_type = F_RDLCK; 159 break; 160 case LINUX_F_WRLCK: 161 bsd_flock->l_type = F_WRLCK; 162 break; 163 case LINUX_F_UNLCK: 164 bsd_flock->l_type = F_UNLCK; 165 break; 166 default: 167 bsd_flock->l_type = -1; 168 break; 169 } 170 bsd_flock->l_whence = linux_flock->l_whence; 171 bsd_flock->l_start = (off_t)linux_flock->l_start; 172 bsd_flock->l_len = (off_t)linux_flock->l_len; 173 bsd_flock->l_pid = (pid_t)linux_flock->l_pid; 174} 175 176static void 177bsd_to_linux_flock(struct flock *bsd_flock, struct linux_flock *linux_flock) 178{ 179 switch (bsd_flock->l_type) { 180 case F_RDLCK: 181 linux_flock->l_type = LINUX_F_RDLCK; 182 break; 183 case F_WRLCK: 184 linux_flock->l_type = LINUX_F_WRLCK; 185 break; 186 case F_UNLCK: 187 linux_flock->l_type = LINUX_F_UNLCK; 188 break; 189 } 190 linux_flock->l_whence = bsd_flock->l_whence; 191 linux_flock->l_start = (linux_off_t)bsd_flock->l_start; 192 linux_flock->l_len = (linux_off_t)bsd_flock->l_len; 193 linux_flock->l_pid = (linux_pid_t)bsd_flock->l_pid; 194} 195 196int 197linux_fcntl(struct proc *p, struct linux_fcntl_args *args) 198{ 199 int error, result; 200 struct fcntl_args /* { 201 int fd; 202 int cmd; 203 long arg; 204 } */ fcntl_args; 205 struct linux_flock linux_flock; 206 struct flock *bsd_flock; 207 struct filedesc *fdp; 208 struct file *fp; 209 caddr_t sg; 210 211 sg = stackgap_init(); 212 bsd_flock = (struct flock *)stackgap_alloc(&sg, sizeof(struct flock)); 213 214#ifdef DEBUG 215 printf("Linux-emul(%ld): fcntl(%d, %08x, *)\n", (long)p->p_pid, 216 args->fd, args->cmd); 217#endif 218 fcntl_args.fd = args->fd; 219 220 switch (args->cmd) { 221 case LINUX_F_DUPFD: 222 fcntl_args.cmd = F_DUPFD; 223 fcntl_args.arg = args->arg; 224 return fcntl(p, &fcntl_args); 225 226 case LINUX_F_GETFD: 227 fcntl_args.cmd = F_GETFD; 228 return fcntl(p, &fcntl_args); 229 230 case LINUX_F_SETFD: 231 fcntl_args.cmd = F_SETFD; 232 fcntl_args.arg = args->arg; 233 return fcntl(p, &fcntl_args); 234 235 case LINUX_F_GETFL: 236 fcntl_args.cmd = F_GETFL; 237 error = fcntl(p, &fcntl_args); 238 result = p->p_retval[0]; 239 p->p_retval[0] = 0; 240 if (result & O_RDONLY) p->p_retval[0] |= LINUX_O_RDONLY; 241 if (result & O_WRONLY) p->p_retval[0] |= LINUX_O_WRONLY; 242 if (result & O_RDWR) p->p_retval[0] |= LINUX_O_RDWR; 243 if (result & O_NDELAY) p->p_retval[0] |= LINUX_O_NONBLOCK; 244 if (result & O_APPEND) p->p_retval[0] |= LINUX_O_APPEND; 245 if (result & O_FSYNC) p->p_retval[0] |= LINUX_O_SYNC; 246 if (result & O_ASYNC) p->p_retval[0] |= LINUX_FASYNC; 247 return error; 248 249 case LINUX_F_SETFL: 250 fcntl_args.arg = 0; 251 if (args->arg & LINUX_O_NDELAY) fcntl_args.arg |= O_NONBLOCK; 252 if (args->arg & LINUX_O_APPEND) fcntl_args.arg |= O_APPEND; 253 if (args->arg & LINUX_O_SYNC) fcntl_args.arg |= O_FSYNC; 254 if (args->arg & LINUX_FASYNC) fcntl_args.arg |= O_ASYNC; 255 fcntl_args.cmd = F_SETFL; 256 return fcntl(p, &fcntl_args); 257 258 case LINUX_F_GETLK: 259 if ((error = copyin((caddr_t)args->arg, (caddr_t)&linux_flock, 260 sizeof(struct linux_flock)))) 261 return error; 262 linux_to_bsd_flock(&linux_flock, bsd_flock); 263 fcntl_args.cmd = F_GETLK; 264 fcntl_args.arg = (long)bsd_flock; 265 error = fcntl(p, &fcntl_args); 266 if (error) 267 return error; 268 bsd_to_linux_flock(bsd_flock, &linux_flock); 269 return copyout((caddr_t)&linux_flock, (caddr_t)args->arg, 270 sizeof(struct linux_flock)); 271 272 case LINUX_F_SETLK: 273 if ((error = copyin((caddr_t)args->arg, (caddr_t)&linux_flock, 274 sizeof(struct linux_flock)))) 275 return error; 276 linux_to_bsd_flock(&linux_flock, bsd_flock); 277 fcntl_args.cmd = F_SETLK; 278 fcntl_args.arg = (long)bsd_flock; 279 return fcntl(p, &fcntl_args); 280 281 case LINUX_F_SETLKW: 282 if ((error = copyin((caddr_t)args->arg, (caddr_t)&linux_flock, 283 sizeof(struct linux_flock)))) 284 return error; 285 linux_to_bsd_flock(&linux_flock, bsd_flock); 286 fcntl_args.cmd = F_SETLKW; 287 fcntl_args.arg = (long)bsd_flock; 288 return fcntl(p, &fcntl_args); 289 290 case LINUX_F_GETOWN: 291 fcntl_args.cmd = F_GETOWN; 292 return fcntl(p, &fcntl_args); 293 294 case LINUX_F_SETOWN: 295 /* 296 * XXX some Linux applications depend on F_SETOWN having no 297 * significant effect for pipes (SIGIO is not delivered for 298 * pipes under Linux-2.2.35 at least). 299 */ 300 fdp = p->p_fd; 301 if ((u_int)args->fd >= fdp->fd_nfiles || 302 (fp = fdp->fd_ofiles[args->fd]) == NULL) 303 return EBADF; 304 if (fp->f_type == DTYPE_PIPE) 305 return EINVAL; 306 307 fcntl_args.cmd = F_SETOWN; 308 fcntl_args.arg = args->arg; 309 return fcntl(p, &fcntl_args); 310 } 311 return EINVAL; 312} 313 314int 315linux_lseek(struct proc *p, struct linux_lseek_args *args) 316{ 317 318 struct lseek_args /* { 319 int fd; 320 int pad; 321 off_t offset; 322 int whence; 323 } */ tmp_args; 324 int error; 325 326#ifdef DEBUG 327 printf("Linux-emul(%ld): lseek(%d, %ld, %d)\n", 328 (long)p->p_pid, args->fdes, args->off, args->whence); 329#endif 330 tmp_args.fd = args->fdes; 331 tmp_args.offset = (off_t)args->off; 332 tmp_args.whence = args->whence; 333 error = lseek(p, &tmp_args); 334 return error; 335} 336 337#ifndef __alpha__ 338int 339linux_llseek(struct proc *p, struct linux_llseek_args *args) 340{ 341 struct lseek_args bsd_args; 342 int error; 343 off_t off; 344 345#ifdef DEBUG 346 printf("Linux-emul(%d): llseek(%d, %d:%d, %d)\n", 347 p->p_pid, args->fd, args->ohigh, args->olow, args->whence); 348#endif 349 off = (args->olow) | (((off_t) args->ohigh) << 32); 350 351 bsd_args.fd = args->fd; 352 bsd_args.offset = off; 353 bsd_args.whence = args->whence; 354 355 if ((error = lseek(p, &bsd_args))) 356 return error; 357 358 if ((error = copyout(p->p_retval, (caddr_t)args->res, sizeof (off_t)))) 359 return error; 360 361 p->p_retval[0] = 0; 362 return 0; 363} 364#endif /*!__alpha__*/ 365 366 367struct linux_dirent { 368 long dino; 369 linux_off_t doff; 370 unsigned short dreclen; 371 char dname[LINUX_NAME_MAX + 1]; 372}; 373 374#define LINUX_RECLEN(de,namlen) \ 375 ALIGN((((char *)&(de)->dname - (char *)de) + (namlen) + 1)) 376 377#ifndef __alpha__ 378int 379linux_readdir(struct proc *p, struct linux_readdir_args *args) 380{ 381 struct linux_getdents_args lda; 382 383 lda.fd = args->fd; 384 lda.dent = args->dent; 385 lda.count = 1; 386 return linux_getdents(p, &lda); 387} 388#endif /*!__alpha__*/ 389 390int 391linux_getdents(struct proc *p, struct linux_getdents_args *args) 392{ 393 register struct dirent *bdp; 394 struct vnode *vp; 395 caddr_t inp, buf; /* BSD-format */ 396 int len, reclen; /* BSD-format */ 397 caddr_t outp; /* Linux-format */ 398 int resid, linuxreclen=0; /* Linux-format */ 399 struct file *fp; 400 struct uio auio; 401 struct iovec aiov; 402 struct vattr va; 403 off_t off; 404 struct linux_dirent linux_dirent; 405 int buflen, error, eofflag, nbytes, justone; 406 u_long *cookies = NULL, *cookiep; 407 int ncookies;
|
423 return error; 424 } 425 426 nbytes = args->count; 427 if (nbytes == 1) { 428 nbytes = sizeof (struct linux_dirent); 429 justone = 1; 430 } 431 else 432 justone = 0; 433 434 off = fp->f_offset; 435#define DIRBLKSIZ 512 /* XXX we used to use ufs's DIRBLKSIZ */ 436 buflen = max(DIRBLKSIZ, nbytes); 437 buflen = min(buflen, MAXBSIZE); 438 buf = malloc(buflen, M_TEMP, M_WAITOK); 439 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 440again: 441 aiov.iov_base = buf; 442 aiov.iov_len = buflen; 443 auio.uio_iov = &aiov; 444 auio.uio_iovcnt = 1; 445 auio.uio_rw = UIO_READ; 446 auio.uio_segflg = UIO_SYSSPACE; 447 auio.uio_procp = p; 448 auio.uio_resid = buflen; 449 auio.uio_offset = off; 450 451 if (cookies) { 452 free(cookies, M_TEMP); 453 cookies = NULL; 454 } 455 456 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies, &cookies); 457 if (error) { 458 goto out; 459 } 460 461 inp = buf; 462 outp = (caddr_t) args->dent; 463 resid = nbytes; 464 if ((len = buflen - auio.uio_resid) <= 0) { 465 goto eof; 466 } 467 468 cookiep = cookies; 469 470 if (cookies) { 471 /* 472 * When using cookies, the vfs has the option of reading from 473 * a different offset than that supplied (UFS truncates the 474 * offset to a block boundary to make sure that it never reads 475 * partway through a directory entry, even if the directory 476 * has been compacted). 477 */ 478 while (len > 0 && ncookies > 0 && *cookiep <= off) { 479 bdp = (struct dirent *) inp; 480 len -= bdp->d_reclen; 481 inp += bdp->d_reclen; 482 cookiep++; 483 ncookies--; 484 } 485 } 486 487 while (len > 0) { 488 if (cookiep && ncookies == 0) 489 break; 490 bdp = (struct dirent *) inp; 491 reclen = bdp->d_reclen; 492 if (reclen & 3) { 493 printf("linux_readdir: reclen=%d\n", reclen); 494 error = EFAULT; 495 goto out; 496 } 497 498 if (bdp->d_fileno == 0) { 499 inp += reclen; 500 if (cookiep) { 501 off = *cookiep++; 502 ncookies--; 503 } else 504 off += reclen; 505 len -= reclen; 506 continue; 507 } 508 linuxreclen = LINUX_RECLEN(&linux_dirent, bdp->d_namlen); 509 if (reclen > len || resid < linuxreclen) { 510 outp++; 511 break; 512 } 513 linux_dirent.dino = (long) bdp->d_fileno; 514 if (justone) { 515 /* 516 * old linux-style readdir usage. 517 */ 518 linux_dirent.doff = (linux_off_t) linuxreclen; 519 linux_dirent.dreclen = (u_short) bdp->d_namlen; 520 } else { 521 if (cookiep) 522 linux_dirent.doff = (linux_off_t)*cookiep; 523 else 524 linux_dirent.doff = (linux_off_t)(off + reclen); 525 linux_dirent.dreclen = (u_short) linuxreclen; 526 } 527 strcpy(linux_dirent.dname, bdp->d_name); 528 if ((error = copyout((caddr_t)&linux_dirent, outp, linuxreclen))) { 529 goto out; 530 } 531 inp += reclen; 532 if (cookiep) { 533 off = *cookiep++; 534 ncookies--; 535 } else 536 off += reclen; 537 outp += linuxreclen; 538 resid -= linuxreclen; 539 len -= reclen; 540 if (justone) 541 break; 542 } 543 544 if (outp == (caddr_t) args->dent) 545 goto again; 546 fp->f_offset = off; 547 548 if (justone) 549 nbytes = resid + linuxreclen; 550 551eof: 552 p->p_retval[0] = nbytes - resid; 553out: 554 if (cookies) 555 free(cookies, M_TEMP); 556 VOP_UNLOCK(vp, 0, p); 557 free(buf, M_TEMP); 558 return error; 559} 560 561/* 562 * These exist mainly for hooks for doing /compat/linux translation. 563 */ 564 565int 566linux_access(struct proc *p, struct linux_access_args *args) 567{ 568 struct access_args bsd; 569 caddr_t sg; 570 571 sg = stackgap_init(); 572 CHECKALTEXIST(p, &sg, args->path); 573 574#ifdef DEBUG 575 printf("Linux-emul(%d): access(%s, %d)\n", 576 p->p_pid, args->path, args->flags); 577#endif 578 bsd.path = args->path; 579 bsd.flags = args->flags; 580 581 return access(p, &bsd); 582} 583 584int 585linux_unlink(struct proc *p, struct linux_unlink_args *args) 586{ 587 struct unlink_args bsd; 588 caddr_t sg; 589 590 sg = stackgap_init(); 591 CHECKALTEXIST(p, &sg, args->path); 592 593#ifdef DEBUG 594 printf("Linux-emul(%d): unlink(%s)\n", 595 p->p_pid, args->path); 596#endif 597 bsd.path = args->path; 598 599 return unlink(p, &bsd); 600} 601 602int 603linux_chdir(struct proc *p, struct linux_chdir_args *args) 604{ 605 struct chdir_args bsd; 606 caddr_t sg; 607 608 sg = stackgap_init(); 609 CHECKALTEXIST(p, &sg, args->path); 610 611#ifdef DEBUG 612 printf("Linux-emul(%d): chdir(%s)\n", 613 p->p_pid, args->path); 614#endif 615 bsd.path = args->path; 616 617 return chdir(p, &bsd); 618} 619 620int 621linux_chmod(struct proc *p, struct linux_chmod_args *args) 622{ 623 struct chmod_args bsd; 624 caddr_t sg; 625 626 sg = stackgap_init(); 627 CHECKALTEXIST(p, &sg, args->path); 628 629#ifdef DEBUG 630 printf("Linux-emul(%d): chmod(%s, %d)\n", 631 p->p_pid, args->path, args->mode); 632#endif 633 bsd.path = args->path; 634 bsd.mode = args->mode; 635 636 return chmod(p, &bsd); 637} 638 639int 640linux_chown(struct proc *p, struct linux_chown_args *args) 641{ 642 struct chown_args bsd; 643 caddr_t sg; 644 645 sg = stackgap_init(); 646 CHECKALTEXIST(p, &sg, args->path); 647 648#ifdef DEBUG 649 printf("Linux-emul(%d): chown(%s, %d, %d)\n", 650 p->p_pid, args->path, args->uid, args->gid); 651#endif 652 bsd.path = args->path; 653 /* XXX size casts here */ 654 bsd.uid = args->uid; 655 bsd.gid = args->gid; 656 657 return chown(p, &bsd); 658} 659 660int 661linux_lchown(struct proc *p, struct linux_lchown_args *args) 662{ 663 struct lchown_args bsd; 664 caddr_t sg; 665 666 sg = stackgap_init(); 667 CHECKALTEXIST(p, &sg, args->path); 668 669#ifdef DEBUG 670 printf("Linux-emul(%d): lchown(%s, %d, %d)\n", 671 p->p_pid, args->path, args->uid, args->gid); 672#endif 673 bsd.path = args->path; 674 /* XXX size casts here */ 675 bsd.uid = args->uid; 676 bsd.gid = args->gid; 677 678 return lchown(p, &bsd); 679} 680 681int 682linux_mkdir(struct proc *p, struct linux_mkdir_args *args) 683{ 684 struct mkdir_args bsd; 685 caddr_t sg; 686 687 sg = stackgap_init(); 688 CHECKALTCREAT(p, &sg, args->path); 689 690#ifdef DEBUG 691 printf("Linux-emul(%d): mkdir(%s, %d)\n", 692 p->p_pid, args->path, args->mode); 693#endif 694 bsd.path = args->path; 695 bsd.mode = args->mode; 696 697 return mkdir(p, &bsd); 698} 699 700int 701linux_rmdir(struct proc *p, struct linux_rmdir_args *args) 702{ 703 struct rmdir_args bsd; 704 caddr_t sg; 705 706 sg = stackgap_init(); 707 CHECKALTEXIST(p, &sg, args->path); 708 709#ifdef DEBUG 710 printf("Linux-emul(%d): rmdir(%s)\n", 711 p->p_pid, args->path); 712#endif 713 bsd.path = args->path; 714 715 return rmdir(p, &bsd); 716} 717 718int 719linux_rename(struct proc *p, struct linux_rename_args *args) 720{ 721 struct rename_args bsd; 722 caddr_t sg; 723 724 sg = stackgap_init(); 725 CHECKALTEXIST(p, &sg, args->from); 726 CHECKALTCREAT(p, &sg, args->to); 727 728#ifdef DEBUG 729 printf("Linux-emul(%d): rename(%s, %s)\n", 730 p->p_pid, args->from, args->to); 731#endif 732 bsd.from = args->from; 733 bsd.to = args->to; 734 735 return rename(p, &bsd); 736} 737 738int 739linux_symlink(struct proc *p, struct linux_symlink_args *args) 740{ 741 struct symlink_args bsd; 742 caddr_t sg; 743 744 sg = stackgap_init(); 745 CHECKALTEXIST(p, &sg, args->path); 746 CHECKALTCREAT(p, &sg, args->to); 747 748#ifdef DEBUG 749 printf("Linux-emul(%d): symlink(%s, %s)\n", 750 p->p_pid, args->path, args->to); 751#endif 752 bsd.path = args->path; 753 bsd.link = args->to; 754 755 return symlink(p, &bsd); 756} 757 758int 759linux_readlink(struct proc *p, struct linux_readlink_args *args) 760{ 761 struct readlink_args bsd; 762 caddr_t sg; 763 764 sg = stackgap_init(); 765 CHECKALTEXIST(p, &sg, args->name); 766 767#ifdef DEBUG 768 printf("Linux-emul(%ld): readlink(%s, %p, %d)\n", 769 (long)p->p_pid, args->name, (void *)args->buf, args->count); 770#endif 771 bsd.path = args->name; 772 bsd.buf = args->buf; 773 bsd.count = args->count; 774 775 return readlink(p, &bsd); 776} 777 778int 779linux_truncate(struct proc *p, struct linux_truncate_args *args) 780{ 781 struct truncate_args bsd; 782 caddr_t sg; 783 784 sg = stackgap_init(); 785 CHECKALTEXIST(p, &sg, args->path); 786 787#ifdef DEBUG 788 printf("Linux-emul(%d): truncate(%s, %ld)\n", 789 p->p_pid, args->path, args->length); 790#endif 791 bsd.path = args->path; 792 bsd.length = args->length; 793 794 return truncate(p, &bsd); 795} 796 797int 798linux_link(struct proc *p, struct linux_link_args *args) 799{ 800 struct link_args bsd; 801 caddr_t sg; 802 803 sg = stackgap_init(); 804 CHECKALTEXIST(p, &sg, args->path); 805 CHECKALTCREAT(p, &sg, args->to); 806 807#ifdef DEBUG 808 printf("Linux-emul(%d): link(%s, %s)\n", p->p_pid, args->path, args->to); 809#endif 810 811 bsd.path = args->path; 812 bsd.link = args->to; 813 814 return link(p, &bsd); 815} 816 817int 818linux_getcwd(struct proc *p, struct linux_getcwd_args *args) 819{ 820 struct __getcwd_args bsd; 821 caddr_t sg; 822 int error, len; 823 824#ifdef DEBUG 825 printf("Linux-emul(%ld): getcwd(%p, %ld)\n", (long)p->p_pid, 826 args->buf, args->bufsize); 827#endif 828 829 sg = stackgap_init(); 830 bsd.buf = stackgap_alloc(&sg, SPARE_USRSPACE); 831 bsd.buflen = SPARE_USRSPACE; 832 error = __getcwd(p, &bsd); 833 if (!error) { 834 len = strlen(bsd.buf) + 1; 835 if (len <= args->bufsize) { 836 p->p_retval[0] = len; 837 error = copyout(bsd.buf, args->buf, len); 838 } 839 else 840 error = ERANGE; 841 } 842 return (error); 843} 844 845#ifndef __alpha__ 846int 847linux_fdatasync(p, uap) 848 struct proc *p; 849 struct linux_fdatasync_args *uap; 850{ 851 struct fsync_args bsd; 852 853 bsd.fd = uap->fd; 854 return fsync(p, &bsd); 855} 856#endif /*!__alpha__*/ 857 858int 859linux_pread(p, uap) 860 struct proc *p; 861 struct linux_pread_args *uap; 862{ 863 struct pread_args bsd; 864 865 bsd.fd = uap->fd; 866 bsd.buf = uap->buf; 867 bsd.nbyte = uap->nbyte; 868 bsd.offset = uap->offset; 869 return pread(p, &bsd); 870} 871 872int 873linux_pwrite(p, uap) 874 struct proc *p; 875 struct linux_pwrite_args *uap; 876{ 877 struct pwrite_args bsd; 878 879 bsd.fd = uap->fd; 880 bsd.buf = uap->buf; 881 bsd.nbyte = uap->nbyte; 882 bsd.offset = uap->offset; 883 return pwrite(p, &bsd); 884}
| 433 return error; 434 } 435 436 nbytes = args->count; 437 if (nbytes == 1) { 438 nbytes = sizeof (struct linux_dirent); 439 justone = 1; 440 } 441 else 442 justone = 0; 443 444 off = fp->f_offset; 445#define DIRBLKSIZ 512 /* XXX we used to use ufs's DIRBLKSIZ */ 446 buflen = max(DIRBLKSIZ, nbytes); 447 buflen = min(buflen, MAXBSIZE); 448 buf = malloc(buflen, M_TEMP, M_WAITOK); 449 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 450again: 451 aiov.iov_base = buf; 452 aiov.iov_len = buflen; 453 auio.uio_iov = &aiov; 454 auio.uio_iovcnt = 1; 455 auio.uio_rw = UIO_READ; 456 auio.uio_segflg = UIO_SYSSPACE; 457 auio.uio_procp = p; 458 auio.uio_resid = buflen; 459 auio.uio_offset = off; 460 461 if (cookies) { 462 free(cookies, M_TEMP); 463 cookies = NULL; 464 } 465 466 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies, &cookies); 467 if (error) { 468 goto out; 469 } 470 471 inp = buf; 472 outp = (caddr_t) args->dent; 473 resid = nbytes; 474 if ((len = buflen - auio.uio_resid) <= 0) { 475 goto eof; 476 } 477 478 cookiep = cookies; 479 480 if (cookies) { 481 /* 482 * When using cookies, the vfs has the option of reading from 483 * a different offset than that supplied (UFS truncates the 484 * offset to a block boundary to make sure that it never reads 485 * partway through a directory entry, even if the directory 486 * has been compacted). 487 */ 488 while (len > 0 && ncookies > 0 && *cookiep <= off) { 489 bdp = (struct dirent *) inp; 490 len -= bdp->d_reclen; 491 inp += bdp->d_reclen; 492 cookiep++; 493 ncookies--; 494 } 495 } 496 497 while (len > 0) { 498 if (cookiep && ncookies == 0) 499 break; 500 bdp = (struct dirent *) inp; 501 reclen = bdp->d_reclen; 502 if (reclen & 3) { 503 printf("linux_readdir: reclen=%d\n", reclen); 504 error = EFAULT; 505 goto out; 506 } 507 508 if (bdp->d_fileno == 0) { 509 inp += reclen; 510 if (cookiep) { 511 off = *cookiep++; 512 ncookies--; 513 } else 514 off += reclen; 515 len -= reclen; 516 continue; 517 } 518 linuxreclen = LINUX_RECLEN(&linux_dirent, bdp->d_namlen); 519 if (reclen > len || resid < linuxreclen) { 520 outp++; 521 break; 522 } 523 linux_dirent.dino = (long) bdp->d_fileno; 524 if (justone) { 525 /* 526 * old linux-style readdir usage. 527 */ 528 linux_dirent.doff = (linux_off_t) linuxreclen; 529 linux_dirent.dreclen = (u_short) bdp->d_namlen; 530 } else { 531 if (cookiep) 532 linux_dirent.doff = (linux_off_t)*cookiep; 533 else 534 linux_dirent.doff = (linux_off_t)(off + reclen); 535 linux_dirent.dreclen = (u_short) linuxreclen; 536 } 537 strcpy(linux_dirent.dname, bdp->d_name); 538 if ((error = copyout((caddr_t)&linux_dirent, outp, linuxreclen))) { 539 goto out; 540 } 541 inp += reclen; 542 if (cookiep) { 543 off = *cookiep++; 544 ncookies--; 545 } else 546 off += reclen; 547 outp += linuxreclen; 548 resid -= linuxreclen; 549 len -= reclen; 550 if (justone) 551 break; 552 } 553 554 if (outp == (caddr_t) args->dent) 555 goto again; 556 fp->f_offset = off; 557 558 if (justone) 559 nbytes = resid + linuxreclen; 560 561eof: 562 p->p_retval[0] = nbytes - resid; 563out: 564 if (cookies) 565 free(cookies, M_TEMP); 566 VOP_UNLOCK(vp, 0, p); 567 free(buf, M_TEMP); 568 return error; 569} 570 571/* 572 * These exist mainly for hooks for doing /compat/linux translation. 573 */ 574 575int 576linux_access(struct proc *p, struct linux_access_args *args) 577{ 578 struct access_args bsd; 579 caddr_t sg; 580 581 sg = stackgap_init(); 582 CHECKALTEXIST(p, &sg, args->path); 583 584#ifdef DEBUG 585 printf("Linux-emul(%d): access(%s, %d)\n", 586 p->p_pid, args->path, args->flags); 587#endif 588 bsd.path = args->path; 589 bsd.flags = args->flags; 590 591 return access(p, &bsd); 592} 593 594int 595linux_unlink(struct proc *p, struct linux_unlink_args *args) 596{ 597 struct unlink_args bsd; 598 caddr_t sg; 599 600 sg = stackgap_init(); 601 CHECKALTEXIST(p, &sg, args->path); 602 603#ifdef DEBUG 604 printf("Linux-emul(%d): unlink(%s)\n", 605 p->p_pid, args->path); 606#endif 607 bsd.path = args->path; 608 609 return unlink(p, &bsd); 610} 611 612int 613linux_chdir(struct proc *p, struct linux_chdir_args *args) 614{ 615 struct chdir_args bsd; 616 caddr_t sg; 617 618 sg = stackgap_init(); 619 CHECKALTEXIST(p, &sg, args->path); 620 621#ifdef DEBUG 622 printf("Linux-emul(%d): chdir(%s)\n", 623 p->p_pid, args->path); 624#endif 625 bsd.path = args->path; 626 627 return chdir(p, &bsd); 628} 629 630int 631linux_chmod(struct proc *p, struct linux_chmod_args *args) 632{ 633 struct chmod_args bsd; 634 caddr_t sg; 635 636 sg = stackgap_init(); 637 CHECKALTEXIST(p, &sg, args->path); 638 639#ifdef DEBUG 640 printf("Linux-emul(%d): chmod(%s, %d)\n", 641 p->p_pid, args->path, args->mode); 642#endif 643 bsd.path = args->path; 644 bsd.mode = args->mode; 645 646 return chmod(p, &bsd); 647} 648 649int 650linux_chown(struct proc *p, struct linux_chown_args *args) 651{ 652 struct chown_args bsd; 653 caddr_t sg; 654 655 sg = stackgap_init(); 656 CHECKALTEXIST(p, &sg, args->path); 657 658#ifdef DEBUG 659 printf("Linux-emul(%d): chown(%s, %d, %d)\n", 660 p->p_pid, args->path, args->uid, args->gid); 661#endif 662 bsd.path = args->path; 663 /* XXX size casts here */ 664 bsd.uid = args->uid; 665 bsd.gid = args->gid; 666 667 return chown(p, &bsd); 668} 669 670int 671linux_lchown(struct proc *p, struct linux_lchown_args *args) 672{ 673 struct lchown_args bsd; 674 caddr_t sg; 675 676 sg = stackgap_init(); 677 CHECKALTEXIST(p, &sg, args->path); 678 679#ifdef DEBUG 680 printf("Linux-emul(%d): lchown(%s, %d, %d)\n", 681 p->p_pid, args->path, args->uid, args->gid); 682#endif 683 bsd.path = args->path; 684 /* XXX size casts here */ 685 bsd.uid = args->uid; 686 bsd.gid = args->gid; 687 688 return lchown(p, &bsd); 689} 690 691int 692linux_mkdir(struct proc *p, struct linux_mkdir_args *args) 693{ 694 struct mkdir_args bsd; 695 caddr_t sg; 696 697 sg = stackgap_init(); 698 CHECKALTCREAT(p, &sg, args->path); 699 700#ifdef DEBUG 701 printf("Linux-emul(%d): mkdir(%s, %d)\n", 702 p->p_pid, args->path, args->mode); 703#endif 704 bsd.path = args->path; 705 bsd.mode = args->mode; 706 707 return mkdir(p, &bsd); 708} 709 710int 711linux_rmdir(struct proc *p, struct linux_rmdir_args *args) 712{ 713 struct rmdir_args bsd; 714 caddr_t sg; 715 716 sg = stackgap_init(); 717 CHECKALTEXIST(p, &sg, args->path); 718 719#ifdef DEBUG 720 printf("Linux-emul(%d): rmdir(%s)\n", 721 p->p_pid, args->path); 722#endif 723 bsd.path = args->path; 724 725 return rmdir(p, &bsd); 726} 727 728int 729linux_rename(struct proc *p, struct linux_rename_args *args) 730{ 731 struct rename_args bsd; 732 caddr_t sg; 733 734 sg = stackgap_init(); 735 CHECKALTEXIST(p, &sg, args->from); 736 CHECKALTCREAT(p, &sg, args->to); 737 738#ifdef DEBUG 739 printf("Linux-emul(%d): rename(%s, %s)\n", 740 p->p_pid, args->from, args->to); 741#endif 742 bsd.from = args->from; 743 bsd.to = args->to; 744 745 return rename(p, &bsd); 746} 747 748int 749linux_symlink(struct proc *p, struct linux_symlink_args *args) 750{ 751 struct symlink_args bsd; 752 caddr_t sg; 753 754 sg = stackgap_init(); 755 CHECKALTEXIST(p, &sg, args->path); 756 CHECKALTCREAT(p, &sg, args->to); 757 758#ifdef DEBUG 759 printf("Linux-emul(%d): symlink(%s, %s)\n", 760 p->p_pid, args->path, args->to); 761#endif 762 bsd.path = args->path; 763 bsd.link = args->to; 764 765 return symlink(p, &bsd); 766} 767 768int 769linux_readlink(struct proc *p, struct linux_readlink_args *args) 770{ 771 struct readlink_args bsd; 772 caddr_t sg; 773 774 sg = stackgap_init(); 775 CHECKALTEXIST(p, &sg, args->name); 776 777#ifdef DEBUG 778 printf("Linux-emul(%ld): readlink(%s, %p, %d)\n", 779 (long)p->p_pid, args->name, (void *)args->buf, args->count); 780#endif 781 bsd.path = args->name; 782 bsd.buf = args->buf; 783 bsd.count = args->count; 784 785 return readlink(p, &bsd); 786} 787 788int 789linux_truncate(struct proc *p, struct linux_truncate_args *args) 790{ 791 struct truncate_args bsd; 792 caddr_t sg; 793 794 sg = stackgap_init(); 795 CHECKALTEXIST(p, &sg, args->path); 796 797#ifdef DEBUG 798 printf("Linux-emul(%d): truncate(%s, %ld)\n", 799 p->p_pid, args->path, args->length); 800#endif 801 bsd.path = args->path; 802 bsd.length = args->length; 803 804 return truncate(p, &bsd); 805} 806 807int 808linux_link(struct proc *p, struct linux_link_args *args) 809{ 810 struct link_args bsd; 811 caddr_t sg; 812 813 sg = stackgap_init(); 814 CHECKALTEXIST(p, &sg, args->path); 815 CHECKALTCREAT(p, &sg, args->to); 816 817#ifdef DEBUG 818 printf("Linux-emul(%d): link(%s, %s)\n", p->p_pid, args->path, args->to); 819#endif 820 821 bsd.path = args->path; 822 bsd.link = args->to; 823 824 return link(p, &bsd); 825} 826 827int 828linux_getcwd(struct proc *p, struct linux_getcwd_args *args) 829{ 830 struct __getcwd_args bsd; 831 caddr_t sg; 832 int error, len; 833 834#ifdef DEBUG 835 printf("Linux-emul(%ld): getcwd(%p, %ld)\n", (long)p->p_pid, 836 args->buf, args->bufsize); 837#endif 838 839 sg = stackgap_init(); 840 bsd.buf = stackgap_alloc(&sg, SPARE_USRSPACE); 841 bsd.buflen = SPARE_USRSPACE; 842 error = __getcwd(p, &bsd); 843 if (!error) { 844 len = strlen(bsd.buf) + 1; 845 if (len <= args->bufsize) { 846 p->p_retval[0] = len; 847 error = copyout(bsd.buf, args->buf, len); 848 } 849 else 850 error = ERANGE; 851 } 852 return (error); 853} 854 855#ifndef __alpha__ 856int 857linux_fdatasync(p, uap) 858 struct proc *p; 859 struct linux_fdatasync_args *uap; 860{ 861 struct fsync_args bsd; 862 863 bsd.fd = uap->fd; 864 return fsync(p, &bsd); 865} 866#endif /*!__alpha__*/ 867 868int 869linux_pread(p, uap) 870 struct proc *p; 871 struct linux_pread_args *uap; 872{ 873 struct pread_args bsd; 874 875 bsd.fd = uap->fd; 876 bsd.buf = uap->buf; 877 bsd.nbyte = uap->nbyte; 878 bsd.offset = uap->offset; 879 return pread(p, &bsd); 880} 881 882int 883linux_pwrite(p, uap) 884 struct proc *p; 885 struct linux_pwrite_args *uap; 886{ 887 struct pwrite_args bsd; 888 889 bsd.fd = uap->fd; 890 bsd.buf = uap->buf; 891 bsd.nbyte = uap->nbyte; 892 bsd.offset = uap->offset; 893 return pwrite(p, &bsd); 894}
|