1.5 Die Systemrufe open und close
- open: öffnet Dateien, gibt Dateinummer zurück
- close: schliesst Dateien, gibt Dateinummer wieder frei
/* Ausschnitte aus Datei /usr/src/linux/fs/open.c, Kernel 2.2.5*/
struct file *filp_open(const char * filename, int flags, int mode)
{
struct inode * inode;
struct dentry * dentry;
struct file * f;
int flag,error;
error = -ENFILE;
f = get_empty_filp(); /*neuer Filepointer*/
if (!f)
goto out;
f->f_flags = flag = flags; /*Flags setzen*/
f->f_mode = (flag+1) & O_ACCMODE;
if (f->f_mode)
flag++;
if (flag & O_TRUNC)
flag |= 2;
dentry = open_namei(filename,flag,mode); /*voller
Verzeichnispfad*/
error = PTR_ERR(dentry);
if (IS_ERR(dentry))
goto cleanup_file;
inode = dentry->d_inode; /*Inode ermitteln*/
if (f->f_mode & FMODE_WRITE) { /*Zugriffsrechte ?*/
error = get_write_access(inode);
if (error)
goto cleanup_dentry;
}
f->f_dentry = dentry; /*File-Struktur
Inhalt setzen*/
f->f_pos = 0;
f->f_reada = 0;
f->f_op = NULL; /*File-Operationen*/
if (inode->i_op)
f->f_op = inode->i_op->default_file_ops;
if (f->f_op && f->f_op->open) {
error = f->f_op->open(inode,f);
if (error)
goto cleanup_all;
}
f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
return f; /*File-Pointer zurückgeben*/
cleanup_all:
if (f->f_mode & FMODE_WRITE)
put_write_access(inode);
cleanup_dentry:
f->f_dentry = NULL;
dput(dentry);
cleanup_file:
put_filp(f);
out:
return ERR_PTR(error); /*Fehler zurückgeben*/
}
asmlinkage int sys_open(const char * filename, int flags, int mode)
{
char * tmp;
int fd, error;
tmp = getname(filename); /*kopiert filename in den
kernel data space */
fd = PTR_ERR(tmp);
if (!IS_ERR(tmp)) {
lock_kernel(); /*lock verhindert, daß
andere Zugriff haben*/
fd = get_unused_fd(); /*neuer
File-Deskriptor(Nr.)*/
if (fd >= 0) {
struct file * f = filp_open(tmp, flags, mode);
error = PTR_ERR(f);
if (IS_ERR(f))
goto out_error;
fd_install(fd, f); /*File-Pointer der
File-Nummer zuordnen*/
}
out:
unlock_kernel();
putname(tmp);
}
return fd;
out_error:
put_unused_fd(fd); /*fd wird nicht mehr
gebraucht*/
fd = error; /*Fehler zurück*/
goto out;
}
asmlinkage int sys_close(unsigned int fd)
{
int error;
struct file * filp;
lock_kernel();
error = -EBADF;
filp = fcheck(fd); /*Filepointer holen*/
if (filp) {
struct files_struct * files = current->files;
files->fd[fd] = NULL;
put_unused_fd(fd); /*Filenummer freigeben*/
FD_CLR(fd, &files->close_on_exec);
error = filp_close(filp, files);
}
unlock_kernel();
return error;
}
int filp_close(struct file *filp, fl_owner_t id)
{
int retval;
struct dentry *dentry = filp->f_dentry;
if (filp->f_count == 0) {
printk("VFS: Close: file count is 0\n");
return 0; /*Dateigröße Null*/
}
retval = 0;
if (filp->f_op && filp->f_op->flush)
retval = filp->f_op->flush(filp); /*Dateipuffer leeren*/
if (dentry->d_inode)
locks_remove_posix(filp, id);
fput(filp); /*Pointer freigeben*/
return retval;
}
Zurück
Weiter
Inhalt