1 /* seeker.c; part of GNU CSSC.
2 *
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007,
4 * 2008, 2009, 2010, 2001, 2014, 2019 Free Software Foundation, Inc.
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Program that determines if the target system can seek on its standard
20 * input.
21 */
22 #include <config.h>
23
24 #include <stdlib.h>
25 #include <stdarg.h>
26 #include <string.h>
27 #include <stdio.h>
28 #include <errno.h>
29
30 #include <unistd.h>
31 #include <sys/types.h>
32
33
34
35 #define ERR_USAGE (1)
36
37 void usage(const char *name, int retval);
38
39 #ifdef HAVE_FSETPOS
40 static void
try_getpos(FILE * f)41 try_getpos(FILE *f)
42 {
43 fpos_t pos;
44 int rv;
45
46 rv = fgetpos(f, &pos);
47 printf("fgetpos() returns %d\n", rv);
48 rv = fsetpos(f, &pos);
49 printf("fsetpos() returns %d\n", rv);
50 }
51 #endif
52
53 static void
try_fseek(FILE * f)54 try_fseek(FILE *f)
55 {
56 long lrv;
57 int rv;
58
59 lrv = ftell(f);
60 printf("ftell() returns %ld\n", lrv);
61 rv = fseek(f, SEEK_SET, lrv);
62 printf("fseek() returns %d\n", rv);
63 }
64
65 static void
try_lseek()66 try_lseek()
67 {
68 off_t pos;
69 pos = lseek(0, 0, SEEK_CUR);
70 printf("lseek() returns %ld [SEEK_CUR]\n", (long)pos);
71 pos = lseek(0, pos, SEEK_CUR);
72 printf("lseek() returns %ld [SEEK_SET]\n", (long)pos);
73 }
74
75
do_help(const char * name)76 int do_help(const char *name)
77 {
78 usage(name, 0);
79 return 0;
80 }
81
do_unbuffered(const char * name)82 int do_unbuffered(const char *name)
83 {
84 (void) name;
85 printf("stdin is unbuffered\n");
86 setvbuf(stdin, (char*)NULL, _IONBF, 0u);
87 return 0;
88 }
89
do_blockbuffered(const char * name)90 int do_blockbuffered(const char *name)
91 {
92 (void) name;
93 printf("stdin is fully-buffered\n");
94 setvbuf(stdin, (char*)NULL, _IOFBF, BUFSIZ);
95 return 0;
96 }
97
do_linebuffered(const char * name)98 int do_linebuffered(const char *name)
99 {
100 (void) name;
101 printf("stdin is line-buffered\n");
102 setvbuf(stdin, (char *)NULL, _IOLBF, 0);
103 return 0;
104 }
105
do_nothing(const char * name)106 int do_nothing(const char *name)
107 {
108 (void) name;
109 printf("stdin is buffered in the default way\n");
110 return 0;
111 }
112
113
114 struct optact
115 {
116 const char *option;
117 int (*action)(const char*);
118 };
119 struct optact actions[]=
120 {
121 { "--help", do_help },
122 { "--unbuffered", do_unbuffered },
123 { "--fully-buffered", do_blockbuffered },
124 { "--line-buffered", do_linebuffered },
125 { "--default-buffering", do_nothing }
126 };
127 #define NOPTIONS (sizeof(actions)/sizeof(actions[0]))
128
129
130
usage(const char * name,int retval)131 void usage(const char *name, int retval)
132 {
133 unsigned int j;
134
135 fprintf(stderr, "usage: %s ", name);
136 for (j=0u; j<NOPTIONS; ++j)
137 fprintf(stderr, "[%s] ", actions[j].option);
138 fprintf(stderr, "\n");
139 exit(retval);
140 }
141
main(int argc,char * argv[])142 int main(int argc, char *argv[])
143 {
144 int i;
145 unsigned int j;
146
147
148 for (i=1; i<argc; ++i)
149 {
150 if ('-' == argv[i][0])
151 {
152 for (j=0u; j<NOPTIONS; ++j)
153 {
154 if (0 == strcmp(argv[i], actions[j].option))
155 {
156 (*actions[j].action)(argv[0]);
157 break;
158 }
159 }
160
161 if (NOPTIONS == j)
162 {
163 fprintf(stderr, "Unknown option `%s'\n", argv[i]);
164 usage(argv[0], ERR_USAGE); /* unknown option */
165 }
166 }
167 else /* not an option */
168 {
169 usage(argv[0], ERR_USAGE);
170 }
171 }
172 #ifdef HAVE_FSETPOS
173 try_getpos(stdin);
174 #else
175 printf("fgetpos() not supported.\n");
176 #endif
177 try_fseek(stdin);
178 try_lseek();
179 return 0;
180 }
181