source: mainline/uspace/lib/c/generic/vfs/inbox.c@ 151f1cc

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 151f1cc was 9c4cf0d, checked in by Jakub Jermar <jakub@…>, 8 years ago

Rename close() to vfs_put()

This is motivated mainly by the fact that a file handle does not
necessarily correspond to an open file and close() was no longer the
the opposite operation to open().

  • Property mode set to 100644
File size: 3.1 KB
RevLine 
[bb9ec2d]1
2#include <vfs/inbox.h>
[9c4cf0d]3#include <vfs/vfs.h>
[bb9ec2d]4
5#include <adt/list.h>
6#include <str.h>
7#include <stdlib.h>
8#include <loader/pcb.h>
9#include "../private/io.h"
10#include <errno.h>
11
12/* This is an attempt at generalization of the "standard files" concept to arbitrary names.
13 * When loading a task, the parent can put arbitrary files to an "inbox" through IPC calls,
14 * every file in an inbox has a name assigned (e.g. "stdin", "stdout", "stderr", "data", "logfile",
15 * etc.). The client then retrieves those files from inbox by name. "stdin", "stdout" and "stderr"
16 * are handled automatically by libc to initialize standard <stdio.h> streams and legacy file
17 * descriptors 0, 1, 2. Other names are subject to conventions and application-specific rules.
18 */
19
20typedef struct {
21 link_t link;
22 char *name;
23 int file;
24} inbox_entry;
25
26static LIST_INITIALIZE(inb_list);
27
28/* Inserts a named file into the inbox.
29 * If a file with the same name is already present, it overwrites it and returns the original
30 * value. Otherwise, it returns -1.
31 * If the argument 'file' is -1, nothing is inserted and the file with specified name is
32 * removed and returned if present.
33 *
34 * @param name Name of the inbox entry.
35 * @param file File to insert or -1.
36 * @return Original value of the entry or -1 if not originally present.
37 */
38int inbox_set(const char *name, int file)
39{
40 inbox_entry *next = NULL;
41
42 list_foreach(inb_list, link, inbox_entry, e) {
43 int cmp = str_cmp(e->name, name);
44 switch (cmp) {
45 case -1:
46 continue;
47 case 0:;
48 int result = e->file;
49 if (file == -1) {
50 free(e->name);
51 /* Safe because we exit immediately. */
52 list_remove(&e->link);
53 } else {
54 e->file = file;
55 }
56 return result;
57 case 1:
58 next = e;
59 goto out;
60 }
61 }
62
63out:
64 if (file == -1) {
65 return -1;
66 }
67
68 inbox_entry *entry = calloc(sizeof(inbox_entry), 1);
69 entry->name = str_dup(name);
70 entry->file = file;
71
72 if (next == NULL) {
73 list_append((link_t *)entry, &inb_list);
74 } else {
75 list_insert_before((link_t *)entry, (link_t *)next);
76 }
77 return -1;
78}
79
80/* Retrieve a file with this name.
81 *
82 * @param name Name of the entry.
83 * @return Requested file or ENOENT if not set.
84 */
85int inbox_get(const char *name)
86{
87 list_foreach(inb_list, link, inbox_entry, e) {
88 int cmp = str_cmp(e->name, name);
89 switch (cmp) {
90 case 0:
91 return e->file;
92 case 1:
93 return ENOENT;
94 }
95 }
96
97 return ENOENT;
98}
99
100/* Writes names of entries that are currently set into and array provided by the user.
101 *
102 * @param names Array in which names are stored.
103 * @param capacity Capacity of the array.
104 * @return Number of entries written. If capacity == 0, return the total number of entries.
105 */
106int inbox_list(const char **names, int capacity)
107{
108 if (capacity == 0) {
109 return list_count(&inb_list);
110 }
111
112 int used = 0;
113
114 list_foreach(inb_list, link, inbox_entry, e) {
115 if (used == capacity) {
116 return used;
117 }
118 names[used] = e->name;
119 used++;
120 }
121
122 return used;
123}
124
125void __inbox_init(struct pcb_inbox_entry *entries, int count) {
126 for (int i = 0; i < count; i++) {
127 int original = inbox_set(entries[i].name, entries[i].file);
128 if (original >= 0) {
[9c4cf0d]129 vfs_put(original);
[bb9ec2d]130 }
131 }
132}
Note: See TracBrowser for help on using the repository browser.