Changeset 79538
- Timestamp:
- 06/16/11 16:41:48 (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/gsoc11-rev-upgrade/base/src/pextlib1.0/Pextlib.c
r74010 r79538 47 47 #include <limits.h> 48 48 #include <pwd.h> 49 #include <stdbool.h> 49 50 #include <stdint.h> 50 51 #include <stdio.h> … … 53 54 #include <strings.h> 54 55 #include <unistd.h> 56 57 /* 58 people use this on non-mac systems 59 #include <mach-o/loader.h> 60 #include <mach-o/fat.h> 61 */ 62 #define MH_MAGIC (0xfeedface) 63 #define MH_MAGIC_64 (0xfeedfacf) 64 #define FAT_MAGIC (0xcafebabe) 55 65 56 66 #include <tcl.h> … … 464 474 } 465 475 476 int fileIsBinaryCmd(ClientData clientData UNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { 477 const char *path; 478 FILE *file; 479 uint32_t magic; 480 struct stat st; 481 482 if (objc != 2) { 483 Tcl_WrongNumArgs(interp, 1, objv, "filename"); 484 return TCL_ERROR; 485 } 486 487 path = Tcl_GetString(objv[1]); 488 if (-1 == lstat(path, &st)) { 489 /* an error occured */ 490 Tcl_SetErrno(errno); 491 Tcl_ResetResult(interp); 492 Tcl_AppendResult(interp, "lstat(", path, "):", (char *)Tcl_PosixError(interp), NULL); 493 return TCL_ERROR; 494 } 495 if (!S_ISREG(st.st_mode)) { 496 /* not a regular file, haven't seen directories which are binaries yet */ 497 Tcl_SetObjResult(interp, Tcl_NewBooleanObj(false)); 498 return TCL_OK; 499 } 500 if (NULL == (file = fopen(path, "r"))) { 501 Tcl_SetErrno(errno); 502 Tcl_ResetResult(interp); 503 Tcl_AppendResult(interp, "fopen(", path, "): ", (char *)Tcl_PosixError(interp), NULL); 504 return TCL_ERROR; 505 } 506 if (1 != fread(&magic, sizeof(uint32_t), 1, file)) { 507 if (feof(file)) { 508 fclose(file); 509 /* file is shorter than 4 byte, probably not a binary */ 510 Tcl_SetObjResult(interp, Tcl_NewBooleanObj(false)); 511 return TCL_OK; 512 } 513 /* error while reading */ 514 Tcl_SetErrno(errno); 515 Tcl_ResetResult(interp); 516 Tcl_AppendResult(interp, "fread(&magic, 4, 1, ", path, "): ", (char *)Tcl_PosixError(interp), NULL); 517 fclose(file); 518 return TCL_ERROR; 519 } 520 if (magic == MH_MAGIC || magic == MH_MAGIC_64) { 521 fclose(file); 522 /* this is a mach-o file */ 523 Tcl_SetObjResult(interp, Tcl_NewBooleanObj(true)); 524 return TCL_OK; 525 } 526 if (magic == htonl(FAT_MAGIC)) { 527 uint32_t archcount; 528 /* either universal binary or java class (FAT_MAGIC == 0xcafebabe) 529 see /use/share/file/magic/cafebabe for an explanation of what I'm doing here */ 530 if (1 != fread(&archcount, sizeof(uint32_t), 1, file)) { 531 if (feof(file)) { 532 fclose(file); 533 /* file shorter than 8 byte, probably not a binary either */ 534 Tcl_SetObjResult(interp, Tcl_NewBooleanObj(false)); 535 return TCL_OK; 536 } 537 /* error while reading */ 538 Tcl_SetErrno(errno); 539 Tcl_ResetResult(interp); 540 Tcl_AppendResult(interp, "fread(&archcount, 4, 1, ", path, "): ", (char *)Tcl_PosixError(interp), NULL); 541 fclose(file); 542 return TCL_ERROR; 543 } 544 545 /* universal binary header is always big endian */ 546 archcount = ntohl(archcount); 547 if (archcount > 0 && archcount < 20) { 548 fclose(file); 549 /* universal binary */ 550 Tcl_SetObjResult(interp, Tcl_NewBooleanObj(true)); 551 return TCL_OK; 552 } 553 554 fclose(file); 555 /* probably java class */ 556 Tcl_SetObjResult(interp, Tcl_NewBooleanObj(false)); 557 return TCL_OK; 558 } 559 fclose(file); 560 561 Tcl_SetObjResult(interp, Tcl_NewBooleanObj(false)); 562 return TCL_OK; 563 } 564 565 466 566 int Pextlib_Init(Tcl_Interp *interp) 467 567 { … … 496 596 Tcl_CreateObjCommand(interp, "unsetenv", UnsetEnvCmd, NULL, NULL); 497 597 Tcl_CreateObjCommand(interp, "lchown", lchownCmd, NULL, NULL); 598 Tcl_CreateObjCommand(interp, "fileIsBinary", fileIsBinaryCmd, NULL, NULL); 498 599 Tcl_CreateObjCommand(interp, "realpath", RealpathCmd, NULL, NULL); 499 600
Note: See TracChangeset
for help on using the changeset viewer.

