Changeset 3218 in kBuild
- Timestamp:
- Mar 30, 2018 10:23:13 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/kmkbuiltin/cat.c
r3192 r3218 47 47 #include <sys/cdefs.h> 48 48 __FBSDID("$FreeBSD: src/bin/cat/cat.c,v 1.32 2005/01/10 08:39:20 imp Exp $"); 49 #else 49 #endif 50 51 /********************************************************************************************************************************* 52 * Header Files * 53 *********************************************************************************************************************************/ 54 #define FAKES_NO_GETOPT_H /* bird */ 50 55 #define NO_UDOM_SUPPORT /* kmk */ 51 #endif52 53 56 #include "config.h" 54 57 #ifndef _MSC_VER … … 71 74 #include <unistd.h> 72 75 #include <stddef.h> 73 #include "getopt .h"76 #include "getopt_r.h" 74 77 #ifdef __sun__ 75 78 # include "solfakes.h" … … 81 84 82 85 83 int bflag, eflag, nflag, sflag, tflag, vflag; 84 /*int rval;*/ 85 const char *filename; 86 86 /********************************************************************************************************************************* 87 * Structures and Typedefs * 88 *********************************************************************************************************************************/ 89 typedef struct CATINSTANCE 90 { 91 PKMKBUILTINCTX pCtx; 92 int bflag, eflag, nflag, sflag, tflag, vflag; 93 /*int rval;*/ 94 const char *filename; 95 /* function level statics from raw_cat (needs freeing): */ 96 size_t bsize; 97 char *buf; 98 } CATINSTANCE; 99 100 101 /********************************************************************************************************************************* 102 * Global Variables * 103 *********************************************************************************************************************************/ 87 104 static struct option long_options[] = 88 105 { … … 94 111 95 112 static int usage(PKMKBUILTINCTX pCtx, int fIsErr); 96 static int scanfiles( PKMKBUILTINCTX pCtx, char *argv[], int cooked);97 static int cook_cat( PKMKBUILTINCTX pCtx, FILE *);98 static int raw_cat( PKMKBUILTINCTX pCtx, int);113 static int scanfiles(CATINSTANCE *pThis, char *argv[], int cooked); 114 static int cook_cat(CATINSTANCE *pThis, FILE *); 115 static int raw_cat(CATINSTANCE *pThis, int); 99 116 100 117 #ifndef NO_UDOM_SUPPORT … … 105 122 kmk_builtin_cat(int argc, char **argv, char **envp, PKMKBUILTINCTX pCtx) 106 123 { 124 struct getopt_state_r gos; 125 CATINSTANCE This; 107 126 int ch, rc; 108 127 109 128 /* kmk: reinitialize globals */ 110 bflag = eflag = nflag = sflag = tflag = vflag = 0; 111 filename = NULL; 112 113 /* kmk: reset getopt and set progname */ 114 opterr = 1; 115 optarg = NULL; 116 optopt = 0; 117 optind = 0; /* init */ 118 119 #ifdef KMK_BUILTIN_STANDALONE /* kmk did this already. */ 120 setlocale(LC_CTYPE, ""); 121 #endif 122 123 while ((ch = getopt_long(argc, argv, "benstuv", long_options, NULL)) != -1) 129 This.pCtx = pCtx; 130 This.bflag = This.eflag = This.nflag = This.sflag = This.tflag = This.vflag = 0; 131 This.filename = NULL; 132 This.bsize = 0; 133 This.buf = 0; 134 135 getopt_initialize_r(&gos, argc, argv, "benstuv", long_options, envp, pCtx); 136 while ((ch = getopt_long_r(&gos, NULL)) != -1) 124 137 switch (ch) { 125 138 case 'b': 126 bflag =nflag = 1; /* -b implies -n */139 This.bflag = This.nflag = 1; /* -b implies -n */ 127 140 break; 128 141 case 'e': 129 eflag =vflag = 1; /* -e implies -v */142 This.eflag = This.vflag = 1; /* -e implies -v */ 130 143 break; 131 144 case 'n': 132 nflag = 1;145 This.nflag = 1; 133 146 break; 134 147 case 's': 135 sflag = 1;148 This.sflag = 1; 136 149 break; 137 150 case 't': 138 tflag =vflag = 1; /* -t implies -v */151 This.tflag = This.vflag = 1; /* -t implies -v */ 139 152 break; 140 153 case 'u': … … 144 157 break; 145 158 case 'v': 146 vflag = 1;159 This.vflag = 1; 147 160 break; 148 161 case 261: … … 154 167 return usage(pCtx, 1); 155 168 } 156 argv += optind;157 158 if ( bflag || eflag || nflag || sflag || tflag ||vflag)159 rc = scanfiles( pCtx, argv, 1);169 argv += gos.optind; 170 171 if (This.bflag || This.eflag || This.nflag || This.sflag || This.tflag || This.vflag) 172 rc = scanfiles(&This, argv, 1); 160 173 else 161 rc = scanfiles(pCtx, argv, 0); 174 rc = scanfiles(&This, argv, 0); 175 if (This.buf) { 176 free(This.buf); 177 This.buf = NULL; 178 } 162 179 #ifdef KMK_BUILTIN_STANDALONE /* don't allow messing with stdout */ 163 180 if (fclose(stdout)) … … 170 187 int main(int argc, char **argv, char **envp) 171 188 { 172 KMKBUILTINCTX Ctx = { "kmk_cat", NULL }; 173 return kmk_builtin_cat(argc, argv, envp, &Ctx); 189 KMKBUILTINCTX Ctx = { "kmk_cat", NULL }; 190 setlocale(LC_CTYPE, ""); 191 return kmk_builtin_cat(argc, argv, envp, &Ctx); 174 192 } 175 193 #endif … … 188 206 189 207 static int 190 scanfiles( PKMKBUILTINCTX pCtx, char *argv[], int cooked)208 scanfiles(CATINSTANCE *pThis, char *argv[], int cooked) 191 209 { 192 210 int i = 0; … … 200 218 201 219 if (path == NULL || strcmp(path, "-") == 0) { 202 filename = "stdin";220 pThis->filename = "stdin"; 203 221 fd = STDIN_FILENO; 204 222 } else { 205 filename = path;223 pThis->filename = path; 206 224 fd = open(path, O_RDONLY); 207 225 #ifndef NO_UDOM_SUPPORT 208 226 if (fd < 0 && errno == EOPNOTSUPP) 209 fd = udom_open(p Ctx, path, O_RDONLY);227 fd = udom_open(pThis, path, O_RDONLY); 210 228 #endif 211 229 } 212 230 if (fd < 0) { 213 warn(p Ctx, "%s", path);231 warn(pThis->pCtx, "%s", path); 214 232 rc2 = 1; /* non fatal */ 215 233 } else if (cooked) { 216 234 if (fd == STDIN_FILENO) 217 rc = cook_cat(p Ctx, stdin);235 rc = cook_cat(pThis, stdin); 218 236 else { 219 237 fp = fdopen(fd, "r"); 220 rc = cook_cat(p Ctx, fp);238 rc = cook_cat(pThis, fp); 221 239 fclose(fp); 222 240 } 223 241 } else { 224 rc = raw_cat(p Ctx, fd);242 rc = raw_cat(pThis, fd); 225 243 if (fd != STDIN_FILENO) 226 244 close(fd); … … 233 251 } 234 252 235 static int cat_putchar(PKMKBUILTINCTX pCtx, char ch) 253 static int 254 cat_putchar(PKMKBUILTINCTX pCtx, char ch) 236 255 { 237 256 #ifndef KMK_BUILTIN_STANDALONE … … 245 264 246 265 static int 247 cook_cat( PKMKBUILTINCTX pCtx, FILE *fp)266 cook_cat(CATINSTANCE *pThis, FILE *fp) 248 267 { 249 268 int ch, gobble, line, prev; … … 257 276 for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) { 258 277 if (prev == '\n') { 259 if ( sflag) {278 if (pThis->sflag) { 260 279 if (ch == '\n') { 261 280 if (gobble) … … 265 284 gobble = 0; 266 285 } 267 if ( nflag && (!bflag || ch != '\n')) {268 kmk_builtin_ctx_printf(p Ctx, 0, "%6d\t", ++line);286 if (pThis->nflag && (!pThis->bflag || ch != '\n')) { 287 kmk_builtin_ctx_printf(pThis->pCtx, 0, "%6d\t", ++line); 269 288 if (ferror(stdout)) 270 289 break; … … 272 291 } 273 292 if (ch == '\n') { 274 if ( eflag && cat_putchar(pCtx, '$') == EOF)293 if (pThis->eflag && cat_putchar(pThis->pCtx, '$') == EOF) 275 294 break; 276 295 } else if (ch == '\t') { 277 if ( tflag) {278 if (cat_putchar(p Ctx, '^') == EOF || cat_putchar(pCtx, 'I') == EOF)296 if (pThis->tflag) { 297 if (cat_putchar(pThis->pCtx, '^') == EOF || cat_putchar(pThis->pCtx, 'I') == EOF) 279 298 break; 280 299 continue; 281 300 } 282 } else if ( vflag) {301 } else if (pThis->vflag) { 283 302 if (!isascii(ch) && !isprint(ch)) { 284 if (cat_putchar(p Ctx, 'M') == EOF || cat_putchar(pCtx, '-') == EOF)303 if (cat_putchar(pThis->pCtx, 'M') == EOF || cat_putchar(pThis->pCtx, '-') == EOF) 285 304 break; 286 305 ch = toascii(ch); 287 306 } 288 307 if (iscntrl(ch)) { 289 if (cat_putchar(p Ctx, '^') == EOF ||290 cat_putchar(p Ctx, ch == '\177' ? '?' :308 if (cat_putchar(pThis->pCtx, '^') == EOF || 309 cat_putchar(pThis->pCtx, ch == '\177' ? '?' : 291 310 ch | 0100) == EOF) 292 311 break; … … 294 313 } 295 314 } 296 if (cat_putchar(p Ctx, ch) == EOF)315 if (cat_putchar(pThis->pCtx, ch) == EOF) 297 316 break; 298 317 } 299 318 if (ferror(fp)) { 300 warn(p Ctx, "%s",filename);319 warn(pThis->pCtx, "%s", pThis->filename); 301 320 rc = 1; 302 321 clearerr(fp); 303 322 } 304 323 if (ferror(stdout)) 305 return err(p Ctx, 1, "stdout");324 return err(pThis->pCtx, 1, "stdout"); 306 325 return rc; 307 326 } 308 327 309 328 static int 310 raw_cat( PKMKBUILTINCTX pCtx, int rfd)329 raw_cat(CATINSTANCE *pThis, int rfd) 311 330 { 312 331 int off, wfd = fileno(stdout); 313 332 ssize_t nr, nw; 314 static size_t bsize;315 static char *buf = NULL;316 struct stat sbuf;317 333 318 334 wfd = fileno(stdout); 319 if (buf == NULL) { 335 if (pThis->buf == NULL) { 336 struct stat sbuf; 320 337 if (fstat(wfd, &sbuf)) 321 return err(p Ctx, 1, "%s",filename);338 return err(pThis->pCtx, 1, "%s", pThis->filename); 322 339 #ifdef KBUILD_OS_WINDOWS 323 bsize = 16384;340 pThis->bsize = 16384; 324 341 #else 325 bsize = MAX(sbuf.st_blksize, 1024);326 #endif 327 if (( buf = malloc(bsize)) == NULL)328 return err(p Ctx, 1, "buffer");329 } 330 while ((nr = read(rfd, buf,bsize)) > 0)342 pThis->bsize = MAX(sbuf.st_blksize, 1024); 343 #endif 344 if ((pThis->buf = malloc(pThis->bsize)) == NULL) 345 return err(pThis->pCtx, 1, "buffer"); 346 } 347 while ((nr = read(rfd, pThis->buf, pThis->bsize)) > 0) 331 348 for (off = 0; nr; nr -= nw, off += nw) { 332 349 #ifndef KMK_BUILTIN_STANDALONE 333 if (p Ctx->pOut)334 nw = output_write_text(p Ctx->pOut, 0, buf, nr);350 if (pThis->pCtx->pOut) 351 nw = output_write_text(pThis->pCtx->pOut, 0, pThis->buf + off, nr); 335 352 else 336 353 #endif 337 nw = write(wfd, buf + off, (size_t)nr);354 nw = write(wfd, pThis->buf + off, (size_t)nr); 338 355 if (nw < 0) 339 return err(p Ctx, 1, "stdout");356 return err(pThis->pCtx, 1, "stdout"); 340 357 } 341 358 if (nr < 0) { 342 warn(p Ctx, "%s",filename);359 warn(pThis->pCtx, "%s", pThis->filename); 343 360 return 1; 344 361 } … … 349 366 350 367 static int 351 udom_open( PKMKBUILTINCTX pCtx, const char *path, int flags)368 udom_open(CATINSTANCE *pThis, const char *path, int flags) 352 369 { 353 370 struct sockaddr_un sou; … … 383 400 case O_RDONLY: 384 401 if (shutdown(fd, SHUT_WR) == -1) 385 warn(p Ctx, NULL);402 warn(pThis->pCtx, NULL); 386 403 break; 387 404 case O_WRONLY: 388 405 if (shutdown(fd, SHUT_RD) == -1) 389 warn(p Ctx, NULL);406 warn(pThis->pCtx, NULL); 390 407 break; 391 408 default:
Note:
See TracChangeset
for help on using the changeset viewer.