1 /*
2 *
3 * Copyright (c) 2003 The Regents of the University of California. All
4 * rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * - Neither the name of the University nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
25 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 */
30
31
32 /*
33 * FUSD - The Framework for UserSpace Devices - Example program
34 *
35 * Jeremy Elson <jelson@circlemud.org>
36 *
37 * drums3.c: This example shows how to wait for both FUSD and non-FUSD
38 * events at the same time. Instead of using fusd_run, we keep
39 * control of main() by using our own select loop.
40 *
41 * Like the original drums.c, this example creates a bunch of devices
42 * in the /dev/drums directory: /dev/drums/bam, /dev/drums/bum, etc.
43 * However, it also prints a prompt to the console, asking the user if
44 * how loud the drums should be.
45 *
46 * $Id: drums3.c,v 1.5 2007-12-08 04:05:01 girod Exp $
47 */
48
49 #include <stdio.h>
50 #include <stdlib.h>
51 #include <string.h>
52 #include <ctype.h>
53 #include <errno.h>
54 #include <unistd.h>
55 #include <sys/select.h>
56
57 #include "fusd.h"
58
59 #define MIN(x, y) ((x) < (y) ? (x) : (y))
60
61
62 static char *drums_strings[] = {"bam", "bum", "beat", "boom",
63 "bang", "crash", NULL};
64
65 int volume = 2; /* default volume is 2 */
66
67 ssize_t drums_read(struct fusd_file_info *file, char *user_buffer,
68 size_t user_length, loff_t *offset)
69 {
70 int len;
71 char sound[128], *c;
72
73 /* 1st read returns the sound; 2nd returns EOF */
74 if (*offset != 0)
75 return 0;
76
77 if (volume == 1)
78 strcpy(sound, "(you hear nothing)");
79 else {
80 strcpy(sound, (char *) file->device_info);
81
82 if (volume >= 3)
83 for (c = sound; *c; c++)
84 *c = toupper(*c);
85
86 if (volume >= 4)
87 strcat(sound, "!!!!!");
88 }
89
90 strcat(sound, "\n");
91
92 /* NEVER return more data than the user asked for */
93 len = MIN(user_length, strlen(sound));
94 memcpy(user_buffer, sound, len);
95 *offset += len;
96 return len;
97 }
98
99
100 int do_open_or_close(struct fusd_file_info *file)
101 {
102 return 0; /* opens and closes always succeed */
103 }
104
105
106 struct fusd_file_operations drums_fops = {
107 open: do_open_or_close,
108 read: drums_read,
109 close: do_open_or_close
110 };
111
112
113 void read_volume(int fd)
114 {
115 char buf[100];
116 int new_vol = 0, retval;
117
118 if (fd < 0)
119 goto prompt;
120
121 retval = read(fd, buf, sizeof(buf)-1);
122
123 if (retval >= 0) {
124 buf[retval] = '\0';
125
126 if (*buf == 'q') {
127 printf("Goodbye...\n");
128 exit(0);
129 }
130
131 new_vol = atoi(buf);
132 }
133
134 if (new_vol >= 1 && new_vol <= 4) {
135 volume = new_vol;
136 printf("Volume changed to %d\n", volume);
137 } else {
138 printf("Invalid volume!\n");
139 }
140
141 prompt:
142 printf("\nHow loud would you like the /dev/drums?\n");
143 printf(" 1 - Inaudible\n");
144 printf(" 2 - Quiet\n");
145 printf(" 3 - Loud\n");
146 printf(" 4 - Permanent ear damage!\n");
147 printf(" q - Exit program\n");
148 printf("Your choice? ");
149 fflush(stdout);
150 }
151
152
153
154
155 int main(int argc, char *argv[])
156 {
157 int i;
158 char buf[128];
159 fd_set fds, tmp;
160 int max;
161
162 for (i = 0; drums_strings[i] != NULL; i++) {
163 sprintf(buf, "/dev/drums/%s", drums_strings[i]);
164 if (fusd_register(buf, 0666, drums_strings[i], &drums_fops) < 0)
165 fprintf(stderr, "%s register failed: %m\n", drums_strings[i]);
166 }
167
168 /* print the initial prompt to the user */
169 read_volume(-1);
170
171 /* EXAMPLE START drums3.c */
172 /* initialize the set */
173 FD_ZERO(&fds);
174
175 /* add stdin to the set */
176 FD_SET(STDIN_FILENO, &fds);
177 max = STDIN_FILENO;
178
179 /* add all FUSD fds to the set */
180 fusd_fdset_add(&fds, &max);
181
182 while (1) {
183 tmp = fds;
184 if (select(max+1, &tmp, NULL, NULL, NULL) < 0)
185 perror("selecting");
186 else {
187 /* if stdin is readable, read the user's response */
188 if (FD_ISSET(STDIN_FILENO, &tmp))
189 read_volume(STDIN_FILENO);
190
191 /* call any FUSD callbacks that have messages waiting */
192 fusd_dispatch_fdset(&tmp);
193 }
194 }
195 /* EXAMPLE STOP drums3.c */
196 }
197
198
199
200
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.