You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123 lines
2.6 KiB

/*
* linux/lib/update.c
*
* (C) 2021 Huan
*/
#include <string.h>
#include <errno.h>
#include <a.out.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <asm/segment.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <update.h>
int sys_getdents(unsigned int fd, struct linux_dirent *d, unsigned int count)
{
struct linux_dirent *tmp;
struct file *file;
struct m_inode *inode;
struct buffer_head *block;
struct dir_entry *ptr;
char *buf;
int bpos;
int dpos;
int ld_size;
int i;
ld_size = sizeof(struct linux_dirent); /* size of linux_dirent */
file = current->filp[fd]; /* opened file */
tmp = (struct linux_dirent *)malloc(ld_size);
buf = (char *)malloc(ld_size); /* for data transportation */
if (fd >= NR_OPEN)
return -EINVAL;
if (!count)
return -1;
if (!file)
return ENOTDIR;
inode = file->f_inode;
block = bread(inode->i_dev, inode->i_zone[0]);
/* count: size of linux_dirent[], target
* dd_size: size of dir_entry[], block 400?
*/
for (dpos = 0, bpos = 0; bpos < inode->i_size; bpos += sizeof(struct dir_entry))
{
if (dpos >= (count - ld_size))
return 0; /* d full */
ptr = (struct dir_entry *)(bpos + block->b_data);
if (!ptr->inode)
continue; /* when it 's empty inode, jump it */
tmp->d_ino = ptr->inode;
strcpy(tmp->d_name, ptr->name);
tmp->d_reclen = ld_size;
tmp->d_off = 0;
memcpy(buf, tmp, ld_size);
for (i = 0; i < ld_size; i++)
put_fs_byte(*(buf + i), ((char *)d) + i + dpos); /* move data from kernel to user */
dpos += ld_size;
}
return dpos;
}
int sys_pipe2(int *fildes, int x)
{
struct m_inode *inode;
struct file *f[2];
int fd[2];
int i, j;
j = 0;
for (i = 0; j < 2 && i < NR_FILE; i++)
if (!file_table[i].f_count)
(f[j++] = i + file_table)->f_count++;
if (j == 1)
f[0]->f_count = 0;
if (j < 2)
return -1;
j = 0;
for (i = 0; j < 2 && i < NR_OPEN; i++)
if (!current->filp[i])
{
current->filp[fd[j] = i] = f[j];
j++;
}
if (j == 1)
current->filp[fd[0]] = NULL;
if (j < 2)
{
f[0]->f_count = f[1]->f_count = 0;
return -1;
}
if (!(inode = get_pipe_inode()))
{
current->filp[fd[0]] =
current->filp[fd[1]] = NULL;
f[0]->f_count = f[1]->f_count = 0;
return -1;
}
f[0]->f_inode = f[1]->f_inode = inode;
f[0]->f_pos = f[1]->f_pos = 0;
f[0]->f_mode = 1; /* read */
f[1]->f_mode = 2; /* write */
put_fs_long(fd[0], 0 + fildes);
put_fs_long(fd[1], 1 + fildes);
return 0;
}
unsigned int sys_sleep(unsigned int seconds)
{
sys_signal(SIGALRM, SIG_IGN, NULL);
sys_alarm(seconds);
sys_pause();
return 0;
}