Plan 9 from Bell Labs’s /usr/web/sources/contrib/rsc/linuxemu/sysfile.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#include <u.h>
#include <libc.h>
#include <ureg.h>
#include "linuxsys.h"
#include "linux.h"

/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
   located on an ext2 file system */
#define O_ACCMODE	  0003
#define O_RDONLY	    00
#define O_WRONLY	    01
#define O_RDWR		    02
#define O_CREAT		  0100	/* not fcntl */
#define O_EXCL		  0200	/* not fcntl */
#define O_NOCTTY	  0400	/* not fcntl */
#define O_TRUNC		 01000	/* not fcntl */
#define O_APPEND	 02000
#define O_NONBLOCK	 04000
#define O_NDELAY	O_NONBLOCK
#define O_SYNC		010000
#define FASYNC		020000	/* fcntl, for BSD compatibility */

/* 
 * BUG: can't support O_EXCL (not in plan9 semantics)
 * O_NOTTY doesn't make sense for plan9.
 * BUG: supporting O_APPEND will be hard.
 * BUG: O_NONBLOCK will be hard.
 * O_SYNC doesn't make sense for plan9.
 *
 * To support O_APPEND and O_NONBLOCK,
 * we really need to keep our own fd table.
 * I'm not willing to do that quite yet.  --rsc
 */
SYSCALL(sys_open)
{
	char *path = (char*)ARG1;
	int mode = ARG2;
	int perm = ARG3;
	int mode9, perm9, fd;

	DPRINT("open(%s, %#o, %#o)...", path, mode, (mode&O_CREAT)?perm:0);

	mode9 = mode & 3;
	if(mode & O_TRUNC)
		mode9 |= OTRUNC;
	if(mode & O_CREAT) {
		perm9 = perm & 0777;
		fd = create(path, mode9, perm9);
	} else
		fd = open(path, mode9);
	
	if(fd >= 0)
		RETURN(fd);
	RETURN(mkerror());
}

SYSCALL(sys_creat)
{
	char *path = (char*)ARG1;
	int perm = ARG2;

	DPRINT("creat(%s, 0%o)...", path, perm);

	/*
	 * open(2) says ``creat is equivalent to open with flags equal to
	 * O_CREAT|O_WRONLY|O_TRUNC''.
	 */

	ARG3 = ARG2;
	ARG2 = O_CREAT|O_WRONLY|O_TRUNC;
	sys_open(ureg);
}

SYSCALL(sys_close)
{
	int fd = ARG1;
	if(close(fd) < 0)
		RETURN(-EBADFD);
	RETURN(0);
}

SYSCALL(sys_read)
{
	int fd = ARG1;
	void *v = (void*) ARG2;
	ulong n = ARG3;
	int r;

	DPRINT("read(%d, %p, %lud)...", fd, v, n);

	r = read(fd, v, n);
	if(r >= 0)
		RETURN(r);
	RETURN(mkerror());
}

SYSCALL(sys_write)
{
	int r;
	int fd = ARG1;
	void *v = (void*) ARG2;
	ulong n = ARG3;

	DPRINT("write(%d, %p, %lud)...", fd, v, n);
	r = write(fd, v, n);
	if(r >= 0)
		RETURN(r);
	RETURN(mkerror());
}

SYSCALL(sys_link)
{
	/*
	 * link(2) says EPERM means the file system
	 * doesn't support links.
	 */
	DPRINT("link(%s, %s)...", (char*)ARG1, (char*)ARG2);
	RETURN(-EPERM);
}

SYSCALL(sys_unlink)
{
	char *file = (char*) ARG1;

	DPRINT("unlink(%s)...", file);
	if(remove(file) == 0)
		RETURN(0);
	RETURN(mkerror());
}

SYSCALL(sys_chdir)
{
	char *file = (char*) ARG1;

	DPRINT("chdir(%s)...", file);
	if(chdir(file) == 0)
		RETURN(0);
	RETURN(mkerror());
}

SYSCALL(sys_mknod)
{
	/*
	 * mknod(2) says EPERM means the file system
	 * doesn't support the requested node type,
	 * which is pretty true.
	 */
	DPRINT("mknod(%s, %#luo, %lud)...", (char*)ARG1, ARG2, ARG3);
	RETURN(-EPERM);
}

SYSCALL(sys_chmod)
{
	char *file = (char*) ARG1;
	int mode = ARG2;
	Dir *d, nd;

	DPRINT("chmod(%s, %#o)...", file, mode);
	mode &= 0777;
	if((d = dirstat(file)) == nil)
		RETURN(mkerror());
	nulldir(&nd);
	nd.mode = d->mode & ~0777;
	free(d);
	nd.mode |= mode;
	if(dirwstat(file, &nd) < 0)
		RETURN(mkerror());
	RETURN(0);
}

SYSCALL(sys_lseek)
{
	int fd = ARG1;
	int offset = ARG2;	
	int whence = ARG3;

	DPRINT("lseek(%d, %d, %d)...", fd, offset, whence);
	if(seek(fd, offset, whence) < 0)
		RETURN(mkerror());
	RETURN(0);
}

/*
 * sync() always returns zero, even
 * though we don't support it.
 */
SYSCALL(sys_sync)
{
	DPRINT("sync()...");
	RETURN(0);
}

SYSCALL(sys_rmdir)
{
	char *file = (char*) ARG1;
	DPRINT("rmdir(%s)...", file);
	if(remove(file) < 0)
		RETURN(mkerror());
	RETURN(0);
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].