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
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;
|
|
}
|