embox
1/**
2* @file
3*
4* @date 06.08.09
5* @author Anton Bondarev
6*/
7
8#include <stddef.h>
9#include <assert.h>
10#include <errno.h>
11
12#include <util/err.h>
13
14#include <fs/inode.h>
15#include <fs/file_desc.h>
16#include <fs/kfile.h>
17
18struct idesc *kopen(struct inode *node, int flag) {
19struct super_block *sb;
20struct file_desc *desc;
21const struct file_operations *ops;
22int ret;
23struct idesc *idesc;
24
25assert(node);
26assertf(!(flag & (O_CREAT | O_EXCL)), "use kcreat() instead kopen()");
27assertf(!(flag & O_DIRECTORY), "use mkdir() instead kopen()");
28
29
30sb = node->i_sb;
31/* if we try open a file (not special) we must have the file system */
32if (NULL == sb) {
33SET_ERRNO(ENOSUPP);
34return NULL;
35}
36
37if (S_ISDIR(node->i_mode)) {
38ops = sb->sb_fops;
39} else {
40if (NULL == sb->sb_fops) {
41SET_ERRNO(ENOSUPP);
42return NULL;
43}
44
45ops = sb->sb_fops;
46
47if (S_ISCHR(node->i_mode)) {
48/* Note: we suppose this node belongs to devfs */
49idesc = ops->open(node, NULL, flag);
50idesc->idesc_flags = flag;
51return idesc;
52}
53}
54
55if(ops == NULL) {
56SET_ERRNO(ENOSUPP);
57return NULL;
58}
59
60desc = file_desc_create(node, flag);
61if (0 != ptr2err(desc)) {
62SET_ERRNO(-(uintptr_t)desc);
63return NULL;
64}
65desc->f_ops = ops;
66
67if (desc->f_ops->open != NULL) {
68idesc = desc->f_ops->open(node, &desc->f_idesc, flag);
69if (ptr2err(idesc)){
70ret = (uintptr_t)idesc;
71goto free_out;
72}
73} else {
74idesc = &desc->f_idesc;
75}
76
77if ((struct idesc *)idesc == &desc->f_idesc) {
78goto out;
79} else {
80file_desc_destroy(desc);
81return idesc;
82}
83
84free_out:
85if (ret < 0) {
86file_desc_destroy(desc);
87SET_ERRNO(-ret);
88return NULL;
89}
90
91out:
92return &desc->f_idesc;
93}
94