summaryrefslogtreecommitdiff
path: root/source3/lib/asys/asys.h
blob: 73f1051f614cac317058338eaee40127fe1db606 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*
 * Async syscalls
 * Copyright (C) Volker Lendecke 2012
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __ASYS_H__
#define __ASYS_H__

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

/**
 * @defgroup asys The async syscall library
 *
 * This module contains a set of asynchronous functions that directly
 * wrap normally synchronous posix system calls. The reason for this
 * module's existence is the limited set of operations the posix async
 * I/O API provides.
 *
 * The basic flow of operations is:
 *
 * The application creates a asys_context structure using
 * asys_context_create()
 *
 * The application triggers a call to the library by calling for
 * example asys_ftruncate(). asys_ftruncate() takes a private_data
 * argument that will be returned later by asys_result. The calling
 * application should hand a pointer representing the async operation
 * to the private_data argument.
 *
 * The application puts the fd returned by asys_signalfd() into its
 * event loop. When the signal fd becomes readable, the application
 * calls asys_result() to grab the final result of one of the system
 * calls that were issued in the meantime.
 *
 * For multi-user applications it is necessary to create different
 * credential contexts, as it is not clear when exactly the real
 * system call will be issued. The application might have called
 * seteuid(2) or something equivalent in the meantime. Thus, all
 * system calls doing access checks, in particular all calls doing
 * path-based operations, require a struct auth_creds_context
 * parameter. asys_creds_context_create() creates such a context. All
 * credential-checking operations take a struct asys_creds_context as
 * an argument. It can be NULL if the application never changes
 * credentials.
 *
 * @{
 */

struct asys_context;
struct asys_creds_context;

enum asys_log_level {
	ASYS_LOG_FATAL = 0,
	ASYS_DEBUG_ERROR,
	ASYS_DEBUG_WARNING,
	ASYS_DEBUG_TRACE
};

#ifndef PRINTF_ATTRIBUTE
#if (__GNUC__ >= 3)
/** Use gcc attribute to check printf fns.  a1 is the 1-based index of
 * the parameter containing the format, and a2 the index of the first
 * argument. Note that some gcc 2.x versions don't handle this
 * properly **/
#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2)))
#else
#define PRINTF_ATTRIBUTE(a1, a2)
#endif
#endif

typedef void (*asys_log_fn)(struct asys_context *ctx, void *private_data,
			    enum asys_log_level level,
			    const char *fmt, ...) PRINTF_ATTRIBUTE(4, 5);

int asys_context_init(struct asys_context **ctx, unsigned max_parallel);
int asys_context_destroy(struct asys_context *ctx);
void asys_set_log_fn(struct asys_context *ctx, asys_log_fn fn,
		     void *private_data);

/**
 * @brief Get the the signal fd
 *
 * asys_signalfd() returns a file descriptor that will become readable
 * whenever an asynchronous request has finished. When the signalfd is
 * readable, calling asys_result() will not block.
 *
 * @param[in]	ctx	The asys context
 * @return		A file descriptor indicating a finished operation
 */

int asys_signalfd(struct asys_context *ctx);

/**
 * @brief Pull the result from an async operation
 *
 * Whe the fd returned from asys_signalfd() is readable, an async
 * operation has finished. The result from the async operation can be
 * pulled with asys_result().
 *
 * @param[in]	ctx	The asys context
 * @return		success: 0, failure: errno
 */
int asys_result(struct asys_context *ctx, ssize_t *pret, int *perrno,
		void *pdata);
void asys_cancel(struct asys_context *ctx, void *private_data);

int asys_pread(struct asys_context *ctx, int fildes, void *buf, size_t nbyte,
	       off_t offset, void *private_data);
int asys_pwrite(struct asys_context *ctx, int fildes, const void *buf,
		size_t nbyte, off_t offset, void *private_data);
int asys_ftruncate(struct asys_context *ctx, int filedes, off_t length,
		   void *private_data);
int asys_fsync(struct asys_context *ctx, int fd, void *private_data);
int asys_close(struct asys_context *ctx, int fd, void *private_data);

struct asys_creds_context *asys_creds_context_create(
	struct asys_context *ctx,
	uid_t uid, gid_t gid, unsigned num_gids, gid_t *gids);

int asys_creds_context_delete(struct asys_creds_context *ctx);

int asys_open(struct asys_context *ctx, struct asys_creds_context *cctx,
	      const char *pathname, int flags, mode_t mode,
	      void *private_data);
int asys_unlink(struct asys_context *ctx, struct asys_creds_context *cctx,
		const char *pathname, void *private_data);

/* @} */

#endif /* __ASYS_H__ */