1 | /*
|
---|
2 | * Async syscalls
|
---|
3 | * Copyright (C) Volker Lendecke 2012
|
---|
4 | *
|
---|
5 | * This program is free software; you can redistribute it and/or modify
|
---|
6 | * it under the terms of the GNU General Public License as published by
|
---|
7 | * the Free Software Foundation; either version 3 of the License, or
|
---|
8 | * (at your option) any later version.
|
---|
9 | *
|
---|
10 | * This program is distributed in the hope that it will be useful,
|
---|
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
13 | * GNU General Public License for more details.
|
---|
14 | *
|
---|
15 | * You should have received a copy of the GNU General Public License
|
---|
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
---|
17 | */
|
---|
18 |
|
---|
19 | #ifndef __ASYS_H__
|
---|
20 | #define __ASYS_H__
|
---|
21 |
|
---|
22 | #include "replace.h"
|
---|
23 | #include "system/filesys.h"
|
---|
24 |
|
---|
25 | /**
|
---|
26 | * @defgroup asys The async syscall library
|
---|
27 | *
|
---|
28 | * This module contains a set of asynchronous functions that directly
|
---|
29 | * wrap normally synchronous posix system calls. The reason for this
|
---|
30 | * module's existence is the limited set of operations the posix async
|
---|
31 | * I/O API provides.
|
---|
32 | *
|
---|
33 | * The basic flow of operations is:
|
---|
34 | *
|
---|
35 | * The application creates a asys_context structure using
|
---|
36 | * asys_context_create()
|
---|
37 | *
|
---|
38 | * The application triggers a call to the library by calling for
|
---|
39 | * example asys_ftruncate(). asys_ftruncate() takes a private_data
|
---|
40 | * argument that will be returned later by asys_result. The calling
|
---|
41 | * application should hand a pointer representing the async operation
|
---|
42 | * to the private_data argument.
|
---|
43 | *
|
---|
44 | * The application puts the fd returned by asys_signalfd() into its
|
---|
45 | * event loop. When the signal fd becomes readable, the application
|
---|
46 | * calls asys_result() to grab the final result of one of the system
|
---|
47 | * calls that were issued in the meantime.
|
---|
48 | *
|
---|
49 | * For multi-user applications it is necessary to create different
|
---|
50 | * credential contexts, as it is not clear when exactly the real
|
---|
51 | * system call will be issued. The application might have called
|
---|
52 | * seteuid(2) or something equivalent in the meantime. Thus, all
|
---|
53 | * system calls doing access checks, in particular all calls doing
|
---|
54 | * path-based operations, require a struct auth_creds_context
|
---|
55 | * parameter. asys_creds_context_create() creates such a context. All
|
---|
56 | * credential-checking operations take a struct asys_creds_context as
|
---|
57 | * an argument. It can be NULL if the application never changes
|
---|
58 | * credentials.
|
---|
59 | *
|
---|
60 | * @{
|
---|
61 | */
|
---|
62 |
|
---|
63 | struct asys_context;
|
---|
64 | struct asys_creds_context;
|
---|
65 |
|
---|
66 | enum asys_log_level {
|
---|
67 | ASYS_LOG_FATAL = 0,
|
---|
68 | ASYS_DEBUG_ERROR,
|
---|
69 | ASYS_DEBUG_WARNING,
|
---|
70 | ASYS_DEBUG_TRACE
|
---|
71 | };
|
---|
72 |
|
---|
73 | #ifndef PRINTF_ATTRIBUTE
|
---|
74 | #if (__GNUC__ >= 3)
|
---|
75 | /** Use gcc attribute to check printf fns. a1 is the 1-based index of
|
---|
76 | * the parameter containing the format, and a2 the index of the first
|
---|
77 | * argument. Note that some gcc 2.x versions don't handle this
|
---|
78 | * properly **/
|
---|
79 | #define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2)))
|
---|
80 | #else
|
---|
81 | #define PRINTF_ATTRIBUTE(a1, a2)
|
---|
82 | #endif
|
---|
83 | #endif
|
---|
84 |
|
---|
85 | typedef void (*asys_log_fn)(struct asys_context *ctx, void *private_data,
|
---|
86 | enum asys_log_level level,
|
---|
87 | const char *fmt, ...) PRINTF_ATTRIBUTE(4, 5);
|
---|
88 |
|
---|
89 | int asys_context_init(struct asys_context **ctx, unsigned max_parallel);
|
---|
90 | int asys_context_destroy(struct asys_context *ctx);
|
---|
91 | void asys_set_log_fn(struct asys_context *ctx, asys_log_fn fn,
|
---|
92 | void *private_data);
|
---|
93 |
|
---|
94 | /**
|
---|
95 | * @brief Get the the signal fd
|
---|
96 | *
|
---|
97 | * asys_signalfd() returns a file descriptor that will become readable
|
---|
98 | * whenever an asynchronous request has finished. When the signalfd is
|
---|
99 | * readable, calling asys_result() will not block.
|
---|
100 | *
|
---|
101 | * @param[in] ctx The asys context
|
---|
102 | * @return A file descriptor indicating a finished operation
|
---|
103 | */
|
---|
104 |
|
---|
105 | int asys_signalfd(struct asys_context *ctx);
|
---|
106 |
|
---|
107 | struct asys_result {
|
---|
108 | ssize_t ret;
|
---|
109 | int err;
|
---|
110 | void *private_data;
|
---|
111 | };
|
---|
112 |
|
---|
113 | /**
|
---|
114 | * @brief Pull the results from async operations
|
---|
115 | *
|
---|
116 | * Whe the fd returned from asys_signalfd() is readable, one or more async
|
---|
117 | * operations have finished. The result from the async operations can be pulled
|
---|
118 | * with asys_results().
|
---|
119 | *
|
---|
120 | * @param[in] ctx The asys context
|
---|
121 | * @param[out] results The result strutcts
|
---|
122 | * @param[in] num_results The length of the results array
|
---|
123 | * @return success: >=0, number of finished jobs
|
---|
124 | * failure: -errno
|
---|
125 | */
|
---|
126 | int asys_results(struct asys_context *ctx, struct asys_result *results,
|
---|
127 | unsigned num_results);
|
---|
128 |
|
---|
129 | void asys_cancel(struct asys_context *ctx, void *private_data);
|
---|
130 |
|
---|
131 | int asys_pread(struct asys_context *ctx, int fildes, void *buf, size_t nbyte,
|
---|
132 | off_t offset, void *private_data);
|
---|
133 | int asys_pwrite(struct asys_context *ctx, int fildes, const void *buf,
|
---|
134 | size_t nbyte, off_t offset, void *private_data);
|
---|
135 | int asys_ftruncate(struct asys_context *ctx, int filedes, off_t length,
|
---|
136 | void *private_data);
|
---|
137 | int asys_fsync(struct asys_context *ctx, int fd, void *private_data);
|
---|
138 | int asys_close(struct asys_context *ctx, int fd, void *private_data);
|
---|
139 |
|
---|
140 | struct asys_creds_context *asys_creds_context_create(
|
---|
141 | struct asys_context *ctx,
|
---|
142 | uid_t uid, gid_t gid, unsigned num_gids, gid_t *gids);
|
---|
143 |
|
---|
144 | int asys_creds_context_delete(struct asys_creds_context *ctx);
|
---|
145 |
|
---|
146 | int asys_open(struct asys_context *ctx, struct asys_creds_context *cctx,
|
---|
147 | const char *pathname, int flags, mode_t mode,
|
---|
148 | void *private_data);
|
---|
149 | int asys_unlink(struct asys_context *ctx, struct asys_creds_context *cctx,
|
---|
150 | const char *pathname, void *private_data);
|
---|
151 |
|
---|
152 | /* @} */
|
---|
153 |
|
---|
154 | #endif /* __ASYS_H__ */
|
---|