source: mainline/uspace/app/bdsh/cmds/modules/cmp/cmp.c@ 86cf96d

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 86cf96d was 86cf96d, checked in by Jakub Jermar <jakub@…>, 10 years ago

Set optreset before each option parsing
(Thanks to Luka Strižić)

bdsh modules such as ls can be used repeatedly within the lifetime of
the bdsh task. As such, they need to set the optreset variable before
each command line options evaluation.

  • Property mode set to 100644
File size: 4.0 KB
Line 
1/*
2 * Copyright (c) 2012 Sean Bartell
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#include <errno.h>
30#include <fcntl.h>
31#include <getopt.h>
32#include <mem.h>
33#include <stdio.h>
34#include <stdlib.h>
35#include <unistd.h>
36#include <vfs/vfs.h>
37
38#include "cmds.h"
39#include "cmp.h"
40#include "config.h"
41#include "entry.h"
42#include "errors.h"
43#include "util.h"
44
45static const char *cmdname = "cmp";
46#define CMP_VERSION "0.0.1"
47#define CMP_BUFLEN 1024
48
49static struct option const long_options[] = {
50 { "help", no_argument, 0, 'h' },
51 { "version", no_argument, 0, 'v' },
52 { 0, 0, 0, 0 }
53};
54
55/* Dispays help for cat in various levels */
56void help_cmd_cmp(unsigned int level)
57{
58 if (level == HELP_SHORT) {
59 printf("`%s' compares the contents of two files\n", cmdname);
60 } else {
61 help_cmd_cmp(HELP_SHORT);
62 printf(
63 "Usage: %s [options] <file1> <file2>\n"
64 "Options:\n"
65 " -h, --help A short option summary\n"
66 " -v, --version Print version information and exit\n"
67 "No output is printed; the return code is 1 if the files differ.\n",
68 cmdname);
69 }
70
71 return;
72}
73
74static int cmp_files(const char *fn0, const char *fn1)
75{
76 int rc = 0;
77 const char *fn[2] = {fn0, fn1};
78 int fd[2] = {-1, -1};
79 char buffer[2][CMP_BUFLEN];
80 ssize_t offset[2];
81
82 for (int i = 0; i < 2; i++) {
83 fd[i] = open(fn[i], O_RDONLY);
84 if (fd[i] < 0) {
85 rc = errno;
86 printf("Unable to open %s\n", fn[i]);
87 goto end;
88 }
89 }
90
91 do {
92 for (int i = 0; i < 2; i++) {
93 offset[i] = 0;
94 ssize_t size;
95 do {
96 size = read(fd[i], buffer[i] + offset[i],
97 CMP_BUFLEN - offset[i]);
98 if (size < 0) {
99 rc = errno;
100 printf("Error reading from %s\n",
101 fn[i]);
102 goto end;
103 }
104 offset[i] += size;
105 } while (size && offset[i] < CMP_BUFLEN);
106 }
107
108 if (offset[0] != offset[1] ||
109 memcmp(buffer[0], buffer[1], offset[0]) != 0) {
110 rc = 1;
111 goto end;
112 }
113 } while (offset[0] == CMP_BUFLEN);
114
115end:
116 if (fd[0] >= 0)
117 close(fd[0]);
118 if (fd[1] >= 0)
119 close(fd[1]);
120 return rc;
121}
122
123/* Main entry point for cmd, accepts an array of arguments */
124int cmd_cmp(char **argv)
125{
126 int rc;
127 unsigned int argc;
128 int c, opt_ind;
129
130 argc = cli_count_args(argv);
131
132 for (c = 0, optreset = 1, optind = 0, opt_ind = 0; c != -1;) {
133 c = getopt_long(argc, argv, "hv", long_options, &opt_ind);
134 switch (c) {
135 case 'h':
136 help_cmd_cmp(HELP_LONG);
137 return CMD_SUCCESS;
138 case 'v':
139 printf("%s\n", CMP_VERSION);
140 return CMD_SUCCESS;
141 }
142 }
143
144 if (argc - optind != 2) {
145 printf("%s - incorrect number of arguments. Try `%s --help'\n",
146 cmdname, cmdname);
147 return CMD_FAILURE;
148 }
149
150 rc = cmp_files(argv[optind], argv[optind + 1]);
151 if (rc)
152 return CMD_FAILURE;
153 else
154 return CMD_SUCCESS;
155}
Note: See TracBrowser for help on using the repository browser.