source: mainline/uspace/lib/c/generic/vfs/inbox.c@ 10aaa2c

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 10aaa2c was 10aaa2c, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 8 years ago

Return -1 instead of ENOENT from inbox_get().

  • Property mode set to 100644
File size: 4.6 KB
Line 
1/*
2 * Copyright (c) 2013 Jiri Zarevucky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libc
30 * @{
31 */
32
33/**
34 * @file
35 * @brief
36 */
37
38#include <vfs/inbox.h>
39#include <vfs/vfs.h>
40
41#include <adt/list.h>
42#include <str.h>
43#include <stdlib.h>
44#include <loader/pcb.h>
45#include "../private/io.h"
46#include <errno.h>
47
48/*
49 * This is an attempt at generalization of the "standard files" concept to
50 * arbitrary names. When loading a task, the parent can put arbitrary files to
51 * an "inbox" through IPC calls, every file in an inbox has a name assigned
52 * (e.g. "stdin", "stdout", "stderr", "data", "logfile", etc.). The client then
53 * retrieves those files from inbox by name. "stdin", "stdout" and "stderr" are
54 * handled automatically by libc to initialize standard <stdio.h> streams and
55 * legacy file descriptors 0, 1, 2. Other names are subject to conventions and
56 * application-specific rules.
57 */
58
59typedef struct {
60 link_t link;
61 char *name;
62 int file;
63} inbox_entry;
64
65static LIST_INITIALIZE(inb_list);
66
67/* Inserts a named file into the inbox.
68 *
69 * If a file with the same name is already present, it overwrites it and returns
70 * the original value. Otherwise, it returns -1. If the argument 'file' is -1,
71 * nothing is inserted and the file with specified name is removed and returned
72 * if present.
73 *
74 * @param name Name of the inbox entry.
75 * @param file File to insert or -1.
76 * @return Original value of the entry or -1 if not originally present.
77 */
78int inbox_set(const char *name, int file)
79{
80 inbox_entry *next = NULL;
81
82 list_foreach(inb_list, link, inbox_entry, e) {
83 int cmp = str_cmp(e->name, name);
84 switch (cmp) {
85 case -1:
86 continue;
87 case 0:;
88 int result = e->file;
89 if (file == -1) {
90 free(e->name);
91 /* Safe because we exit immediately. */
92 list_remove(&e->link);
93 } else {
94 e->file = file;
95 }
96 return result;
97 case 1:
98 next = e;
99 goto out;
100 }
101 }
102
103out:
104 if (file == -1)
105 return -1;
106
107 inbox_entry *entry = calloc(sizeof(inbox_entry), 1);
108 entry->name = str_dup(name);
109 entry->file = file;
110
111 if (next == NULL) {
112 list_append((link_t *)entry, &inb_list);
113 } else {
114 list_insert_before((link_t *)entry, (link_t *)next);
115 }
116 return -1;
117}
118
119/* Retrieve a file with this name.
120 *
121 * @param name Name of the entry.
122 * @return Requested file or -1 if not set.
123 */
124int inbox_get(const char *name)
125{
126 list_foreach(inb_list, link, inbox_entry, e) {
127 int cmp = str_cmp(e->name, name);
128 switch (cmp) {
129 case 0:
130 return e->file;
131 case 1:
132 return -1;
133 }
134 }
135
136 return -1;
137}
138
139/* Writes names of entries that are currently set into an array provided by the
140 * user.
141 *
142 * @param names Array in which names are stored.
143 * @param capacity Capacity of the array.
144 * @return Number of entries written. If capacity == 0, return the total number
145 * of entries.
146 */
147int inbox_list(const char **names, int capacity)
148{
149 if (capacity == 0)
150 return list_count(&inb_list);
151
152 int used = 0;
153
154 list_foreach(inb_list, link, inbox_entry, e) {
155 if (used == capacity)
156 return used;
157 names[used] = e->name;
158 used++;
159 }
160
161 return used;
162}
163
164void __inbox_init(struct pcb_inbox_entry *entries, int count)
165{
166 for (int i = 0; i < count; i++) {
167 int original = inbox_set(entries[i].name, entries[i].file);
168 if (original >= 0)
169 vfs_put(original);
170 }
171}
172
173/**
174 * @}
175 */
Note: See TracBrowser for help on using the repository browser.