int readi(struct inode *ip, char *xdst, uint off, uint n);
int writei(struct inode *ip, char *addr, uint off, uint n);
struct inode *mknod(struct inode *, char *, short, short, short);
+int unlink(char *cp);
void iupdate (struct inode *ip);
}
static void
-ifree(uint dev, struct inode *ip)
+ifree(struct inode *ip)
{
ip->type = 0;
iupdate(ip);
return ip;
}
+
+int
+unlink(char *cp)
+{
+ int i;
+ struct inode *ip, *dp;
+ struct dirent *ep = 0;
+ int off;
+ struct buf *bp = 0;
+
+ if ((ip = namei(cp)) == 0) {
+ cprintf("file to be unlinked doesn't exist\n");
+ return -1;
+ }
+
+ ip->nlink--;
+ if (ip->nlink > 0) {
+ iupdate(ip);
+ iput(ip); // is this the right order?
+ return 0;
+ }
+
+ // free inode, its blocks, and remove dir entry
+ for (i = 0; i < NDIRECT; i++) {
+ if (ip->addrs[i] != 0) {
+ bfree(ip->dev, ip->addrs[i]);
+ ip->addrs[i] = 0;
+ }
+ }
+ ip->size = 0;
+ ip->major = 0;
+ ip->minor = 0;
+ iupdate(ip);
+ ifree(ip); // is this the right order?
+
+ dp = iget(rootdev, 1); // XXX should parse name
+ for(off = 0; off < dp->size; off += BSIZE) {
+ bp = bread(dp->dev, bmap(dp, off / BSIZE));
+ for(ep = (struct dirent *) bp->data;
+ ep < (struct dirent *) (bp->data + BSIZE);
+ ep++){
+ if(ep->inum == ip->inum) {
+ goto found;
+ }
+ }
+ brelse(bp);
+ }
+ panic("mknod: XXXX no dir entry free\n");
+
+ found:
+ ep->inum = 0;
+ bwrite (dp->dev, bp, bmap(dp, off/BSIZE)); // write directory block
+ brelse(bp);
+ iput(ip);
+ iupdate (dp);
+ iput(dp);
+ return 0;
+}
ioapic_write(io, IOAPIC_REDTBL_LO(irq), l);
h = ioapic_read(io, IOAPIC_REDTBL_HI(irq));
h &= ~IOART_DEST;
- h |= (cpunum << APIC_ID_SHIFT); // for fun, disk interrupts to cpu 1
+ h |= (cpunum << APIC_ID_SHIFT);
ioapic_write(io, IOAPIC_REDTBL_HI(irq), h);
cprintf("cpu%d: intr %d: lo 0x%x hi 0x%x\n", cpu(), irq, l, h);
}
if (l >= DIRSIZ)
return -1;
dp = iget(rootdev, 1); // XXX should parse name
- if (dp->type != T_DIR)
- return -1;
- if ((ip = mknod (dp, cp->mem + arg0, T_FILE, 0, 0)) == 0)
- return -1;
+ ip = mknod (dp, cp->mem + arg0, T_FILE, 0, 0);
+ iput(dp);
+ if (ip == 0) return -1;
} else return -1;
}
if((fd = fd_alloc()) == 0){
return -1;
dp = iget(rootdev, 1); // XXX should parse name
- if (dp->type != T_DIR) {
- iput(dp);
- return -1;
- }
-
nip = mknod (dp, cp->mem + arg0, (short) arg1, (short) arg2,
(short) arg3);
-
iput(dp);
-
- if (nip == 0) return -1;
-
iput(nip);
-
- return 0;
+ return (nip == 0) ? -1 : 0;
}
int
sys_unlink(void)
{
struct proc *cp = curproc[cpu()];
- struct inode *ip;
uint arg0;
-
+ int r;
+
if(fetcharg(0, &arg0) < 0)
return -1;
-
if(checkstring(arg0) < 0)
return -1;
-
- ip = namei(cp->mem + arg0);
- ip->nlink--;
- if (ip->nlink <= 0) {
- panic("sys_link: unimplemented\n");
- }
- iupdate(ip);
- iput(ip);
-
- return 0;
+ r = unlink(cp->mem + arg0);
+ return r;
}
int
// file system tests
-char buf[2000];
+char buf[3000];
char *echo_args[] = { "echo", "hello", "goodbye", 0 };
char *cat_args[] = { "cat", "README", 0 };
} else {
printf(stdout, "error: open doesnotexist failed!\n");
}
- i = read(fd, buf, 10000);
+ i = read(fd, buf, 2000);
if (i == 2000) {
- printf(stdout, "read succeeded\\n");
+ printf(stdout, "read succeeded\n");
} else {
printf(stdout, "read failed\n");
}
close(fd);
+ unlink("doesnotexist");
//exec("echo", echo_args);
printf(stdout, "about to do exec\n");
exec("cat", cat_args);