d = new FileAsync() {
@Override
public void async() {
Path existing = ERT.newFile(old_file).toPath();
Path link = new File(new_file).toPath();
try {
if (cmd == FILE_LINK) {
Files.createLink(link, existing);
} else if (cmd == FILE_SYMLINK) {
Files.createSymbolicLink(link, existing);
} else {
posix_errno = Posix.EUNKNOWN;
result_ok = false;
return;
}
result_ok = true;
} catch (IOException e) {
posix_errno = IO.exception_to_posix_code(e);
result_ok = false;
}
}
@Override
public void ready() throws Pausable {
reply(EFile.this);
}
};
} break;
case FILE_READLINK: {
d = new SimpleFileAsync(cmd, IO.strcpy(buf)) {
String outfile = null;
public void run() {
Path p = this.file.toPath();
if (!Files.exists(p, LinkOption.NOFOLLOW_LINKS)) {
result_ok = false;
posix_errno = Posix.ENOENT;
return;
}
if (!Files.isSymbolicLink(p)) {
result_ok = false;
posix_errno = Posix.EINVAL;
return;
}
try {
p = Files.readSymbolicLink(p);
outfile = p.toString();
result_ok = true;
} catch (IOException e) {
result_ok = false;
posix_errno = IO.exception_to_posix_code(e);
}
}
@Override
public void ready() throws Pausable {
if (!result_ok) {
super.ready();
} else {
ByteBuffer reply = null;
ByteBuffer data = null;
// prim_file interface from R14 on
reply = ByteBuffer.allocate(1);
data = ByteBuffer.allocate(outfile.length());
reply.put(FILE_RESP_FNAME);
IO.putstr(data, outfile, false);
driver_output2(reply, data);
}
}
};
} break;
case FILE_MKDIR: {
d = new SimpleFileAsync(cmd, IO.strcpy(buf)) {
public void run() {
result_ok = file.mkdir();
if (!result_ok) {
if (name.length() == 0) {
posix_errno = Posix.ENOENT;
} else if (file.exists()) {
posix_errno = Posix.EEXIST;
} else if (file.getParentFile() != null && !file.getParentFile().isDirectory()) {
posix_errno = Posix.ENOTDIR;
} else {
posix_errno = Posix.EUNKNOWN;
}
}
}
};
break;
}
case FILE_RMDIR: {
d = new SimpleFileAsync(cmd, IO.strcpy(buf)) {
public void run() {
result_ok = file.isDirectory() && file.delete();
if (!result_ok) {
if (!file.exists()) {
posix_errno = Posix.ENOENT;
} else if (Posix.isCWD(name, file)) {
posix_errno = Posix.EINVAL;
} else if (!file.isDirectory()) {
posix_errno = Posix.ENOTDIR;
} else if (file.exists()) {
posix_errno = Posix.EEXIST;
} else {
posix_errno = Posix.EUNKNOWN;
}
}
}
};
break;
}
case FILE_CHDIR: {
d = new SimpleFileAsync(cmd, IO.strcpy(buf)) {
public void run() {
result_ok = file.isDirectory();
if (!result_ok) {
if (!file.exists()) {
posix_errno = Posix.ENOENT;
} else if (!file.isDirectory()) {
posix_errno = Posix.ENOTDIR;
} else {
posix_errno = Posix.EUNKNOWN;
}
} else {
try {
System.setProperty("user.dir", file.getCanonicalPath());
} catch (IOException e) {
posix_errno = Posix.EUNKNOWN;
}
}
}
};
break;
}
case FILE_DELETE: {
d = new SimpleFileAsync(cmd, IO.strcpy(buf)) {
public void run() {
result_ok = file.isFile() && file.delete();
if (!result_ok) {
if (!file.exists()) {
posix_errno = Posix.ENOENT;
} else if (!file.canWrite()) {
posix_errno = Posix.EPERM;
} else if (file.isDirectory()) {
posix_errno = Posix.EEXIST;
} else {
posix_errno = Posix.EUNKNOWN;
}
}
}
};
break;
}
case FILE_PWD: {
d = new FileAsync() {
private String pwd;
{
this.command = FILE_PWD;
super.level = 2;
}
@Override
public void async() {
File pwd = Posix.getCWD();
if (pwd.exists() && pwd.isDirectory()) {
this.pwd = pwd.getAbsolutePath();
result_ok = true;
} else {
result_ok = false;
posix_errno = Posix.ENOENT;
}
again = false;
}
@Override
public void ready() throws Pausable {
if (!result_ok) {
reply_posix_error(posix_errno);
} else {
ByteBuffer reply = null;
ByteBuffer data = null;
if (isUnicodeDriverInterface()) {
// prim_file interface from R14 on
reply = ByteBuffer.allocate(1);
data = ByteBuffer.allocate(pwd.length());
reply.put(FILE_RESP_FNAME);
IO.putstr(data, pwd, false);
}
else {
// prim_file interface up to R13B
reply = ByteBuffer.allocate(1+pwd.length());
reply.put(FILE_RESP_OK);
IO.putstr(reply, pwd, false);
}
driver_output2(reply, data);
}
}
};
break;
}
case FILE_LSEEK: {
final long off = buf.getLong();
final int whence = buf.getInt();
async_lseek(null, true, off, whence);
return;
}
case FILE_OPEN: {
final int mode = buf.getInt();
final String file_name = IO.strcpy(buf);
d = new SimpleFileAsync(cmd, file_name) {
int res_fd = 1234;
public void run() {
boolean compressed = (mode & EFILE_COMPRESSED) > 0;
if (compressed && log.isLoggable(Level.FINE)) {
log.fine("EFile.open_compressed "+file_name);
}
boolean append = (mode & EFILE_MODE_APPEND) > 0;
if ((mode & ~(EFILE_MODE_APPEND | EFILE_MODE_READ_WRITE | EFILE_MODE_EXCL)) > 0) {
log.warning("ONLY APPEND AND READ_WRITE OPTIONS ARE IMPLEMENTED! mode="+mode);
throw new NotImplemented();
}
try {
if (compressed) {
if ((mode & EFILE_MODE_READ_WRITE) == EFILE_MODE_READ_WRITE && append) {
posix_errno = Posix.EINVAL;
return;
}
log.warning("COMPRESSED NOT IMPLEMENTED!");
throw new NotImplemented();
} else {
if ((mode & EFILE_MODE_EXCL) == EFILE_MODE_EXCL) {
file.createNewFile();
}
switch (mode & EFILE_MODE_READ_WRITE) {
case EFILE_MODE_READ: {
FileInputStream fo = new FileInputStream(file);
fd = fo.getChannel();
res_fd = getFDnumber(fo.getFD());
break;
}
case EFILE_MODE_WRITE: {
FileOutputStream fo = new FileOutputStream(file);
fd = fo.getChannel();
res_fd = getFDnumber(fo.getFD());
break;
}
case EFILE_MODE_READ_WRITE: {
RandomAccessFile rafff;
fd = (rafff=new RandomAccessFile(file,"rw")).getChannel();
res_fd = getFDnumber(rafff.getFD());
break;
}
default:
throw new NotImplemented();
}//switch
EFile.this.name = file;
result_ok = true;
}
} catch (FileNotFoundException fnfe) {
posix_errno = fileNotFound_to_posixErrno(file, mode);
} catch (IOException e) {
log.log(Level.WARNING, "failed to open file", e);
posix_errno = fileNotFound_to_posixErrno(file, mode);
} catch (IllegalAccessException e) {
log.log(Level.WARNING, "failed to open file", e);
posix_errno = fileNotFound_to_posixErrno(file, mode);
}
}
@Override
public void ready() throws Pausable {
if (result_ok) {
EFile.this.fd = fd;
reply_Uint(res_fd); /* TODO: fd */
} else {
reply_posix_error(posix_errno);
}
}
};
} break;
case FILE_WRITE_INFO: {
final int file_mode = buf.getInt();
final int file_uid = buf.getInt();
final int file_gid = buf.getInt();
final FileTime file_atime = FileTime.from( buf.getLong(), TimeUnit.SECONDS );
final FileTime file_mtime = FileTime.from( buf.getLong(), TimeUnit.SECONDS );
final FileTime file_ctime = FileTime.from( buf.getLong(), TimeUnit.SECONDS );
final String file_name = IO.strcpy(buf);
if (ClassPathResource.isResource(file_name)) {
reply_posix_error(Posix.EPERM);
return;
}
d = new SimpleFileAsync(cmd, file_name) {
@Override
protected void run() throws IOException {
if (!file.exists()) {
this.posix_errno = Posix.ENOENT;
this.result_ok = false;
return;
}
Path path = file.toPath();
Files.setLastModifiedTime(path, file_mtime);
Map<String,Object> atts = Files.readAttributes(path, "unix:mode,gid,uid", LinkOption.NOFOLLOW_LINKS);
if (att(atts, "mode", file_mode) != file_mode) {
Files.setAttribute(path, "unix:mode", new Integer(file_mode), LinkOption.NOFOLLOW_LINKS);
}
if (att(atts, "gid", file_gid) != file_gid) {
Files.setAttribute(path, "unix:gid", new Integer(file_gid), LinkOption.NOFOLLOW_LINKS);
}
if (att(atts, "uid", file_uid) != file_uid) {
Files.setAttribute(path, "unix:uid", new Integer(file_uid), LinkOption.NOFOLLOW_LINKS);
}
this.result_ok = true;
}
int att(Map<String,Object> atts, String name, int defaultValue) {
Number att = (Number)atts.get(name);
if (att == null) return defaultValue;
return att.intValue();
}
};
} break;
case FILE_FSTAT:
case FILE_LSTAT: {
final String file_name = IO.strcpy(buf);
final File file = ERT.newFile(file_name);
if (ClassPathResource.isResource(file_name)) {
ClassPathResource.fstat(this, file_name);
return;
}
d = new FileAsync() {
long file_size;
int file_type;
long file_access_time;
long file_modify_time;
long file_create_time;
int file_inode;
int file_gid;
int file_uid;
int file_access;
int file_mode;
int file_nlink;
int file_dev;
int file_rdev;
/** emulate fstat as close as possible */
@Override
public void async() {
if (!file.exists()) {
result_ok = false;
posix_errno = Posix.ENOENT;
return;
}
Path path = file.toPath();
PosixFileAttributes attrs;
try {
attrs = Files.readAttributes(path, PosixFileAttributes.class, LinkOption.NOFOLLOW_LINKS);
} catch (IOException e) {