577 /*
578 * We need absolute control over where the temporary file goes, since
579 * we rely on it for cleanup so tempnam(3C) and tmpnam(3C) are
580 * inappropriate (they use TMPDIR, preferentially).
581 *
582 * mkstemp(3C) doesn't actually help us, since the temporary file
583 * isn't used by us, only its name.
584 */
585 if (mktemp(tmpl) == NULL)
586 nomem();
587
588 (void) asprintf(&ret, "%s/%s%s", ctx->i_tmpdir, tmpl,
589 (ext != NULL) ? ext : "");
590
591 if (ret == NULL)
592 nomem();
593
594 return (ret);
595 }
596
597 static void
598 do_gcc(cw_ictx_t *ctx)
599 {
600 int c;
601 int nolibc = 0;
602 int in_output = 0, seen_o = 0, c_files = 0;
603 cw_op_t op = CW_O_LINK;
604 char *model = NULL;
605 char *nameflag;
606 int mflag = 0;
607
608 if (ctx->i_flags & CW_F_PROG) {
609 newae(ctx->i_ae, "--version");
610 return;
611 }
612
613 newae(ctx->i_ae, "-fident");
614 newae(ctx->i_ae, "-finline");
615 newae(ctx->i_ae, "-fno-inline-functions");
616 newae(ctx->i_ae, "-fno-builtin");
642 if (asprintf(&nameflag, "-_%s=", ctx->i_compiler->c_name) == -1)
643 nomem();
644
645 /*
646 * Walk the argument list, translating as we go ..
647 */
648 while (--ctx->i_oldargc > 0) {
649 char *arg = *++ctx->i_oldargv;
650 size_t arglen = strlen(arg);
651
652 if (*arg == '-') {
653 arglen--;
654 } else {
655 /*
656 * Discard inline files that gcc doesn't grok
657 */
658 if (!in_output && arglen > 3 &&
659 strcmp(arg + arglen - 3, ".il") == 0)
660 continue;
661
662 if (!in_output && arglen > 2 &&
663 arg[arglen - 2] == '.' &&
664 (arg[arglen - 1] == 'S' || arg[arglen - 1] == 's' ||
665 arg[arglen - 1] == 'c' || arg[arglen - 1] == 'i'))
666 c_files++;
667
668 /*
669 * Otherwise, filenames and partial arguments
670 * are passed through for gcc to chew on. However,
671 * output is always discarded for the secondary
672 * compiler.
673 */
674 if ((ctx->i_flags & CW_F_SHADOW) && in_output) {
675 newae(ctx->i_ae, discard_file_name(ctx, arg));
676 } else {
677 newae(ctx->i_ae, arg);
678 }
679 in_output = 0;
680 continue;
681 }
682
683 if (ctx->i_flags & CW_F_CXX) {
684 if (strncmp(arg, "-_g++=", 6) == 0) {
685 newae(ctx->i_ae, strchr(arg, '=') + 1);
1349 do_gcc(ctx);
1350 }
1351
1352 static void
1353 do_cc(cw_ictx_t *ctx)
1354 {
1355 int in_output = 0, seen_o = 0, c_files = 0;
1356 cw_op_t op = CW_O_LINK;
1357 char *nameflag;
1358
1359 if (ctx->i_flags & CW_F_PROG) {
1360 newae(ctx->i_ae, "-V");
1361 return;
1362 }
1363
1364 if (asprintf(&nameflag, "-_%s=", ctx->i_compiler->c_name) == -1)
1365 nomem();
1366
1367 while (--ctx->i_oldargc > 0) {
1368 char *arg = *++ctx->i_oldargv;
1369 size_t arglen = strlen(arg);
1370
1371 if (strncmp(arg, "-_CC=", 5) == 0) {
1372 newae(ctx->i_ae, strchr(arg, '=') + 1);
1373 continue;
1374 }
1375
1376 if (*arg != '-') {
1377 if (!in_output && arglen > 2 &&
1378 arg[arglen - 2] == '.' &&
1379 (arg[arglen - 1] == 'S' || arg[arglen - 1] == 's' ||
1380 arg[arglen - 1] == 'c' || arg[arglen - 1] == 'i'))
1381 c_files++;
1382
1383 if (in_output == 0 || !(ctx->i_flags & CW_F_SHADOW)) {
1384 newae(ctx->i_ae, arg);
1385 } else {
1386 in_output = 0;
1387 newae(ctx->i_ae, discard_file_name(ctx, arg));
1388 }
1389 continue;
1390 }
1391 switch (*(arg + 1)) {
1392 case '_':
1393 if ((strncmp(arg, nameflag, strlen(nameflag)) == 0) ||
1394 (strncmp(arg, "-_cc=", 5) == 0) ||
1395 (strncmp(arg, "-_sun=", 6) == 0)) {
1396 newae(ctx->i_ae, strchr(arg, '=') + 1);
1397 }
1398 break;
1399
1400 case 'V':
1661 cleanup(cw_ictx_t *ctx)
1662 {
1663 DIR *dirp;
1664 struct dirent *dp;
1665 char buf[MAXPATHLEN];
1666
1667 if ((dirp = opendir(ctx->i_tmpdir)) == NULL) {
1668 if (errno != ENOENT) {
1669 err(1, "couldn't open temp directory: %s",
1670 ctx->i_tmpdir);
1671 } else {
1672 return;
1673 }
1674 }
1675
1676 errno = 0;
1677 while ((dp = readdir(dirp)) != NULL) {
1678 (void) snprintf(buf, MAXPATHLEN, "%s/%s", ctx->i_tmpdir,
1679 dp->d_name);
1680
1681 if (strncmp(dp->d_name, ".", strlen(dp->d_name)) == 0 ||
1682 strncmp(dp->d_name, "..", strlen(dp->d_name)) == 0)
1683 continue;
1684
1685 if (unlink(buf) == -1)
1686 err(1, "failed to unlink temp file: %s", dp->d_name);
1687 errno = 0;
1688 }
1689
1690 if (errno != 0) {
1691 err(1, "failed to read temporary directory: %s",
1692 ctx->i_tmpdir);
1693 }
1694
1695 (void) closedir(dirp);
1696 if (rmdir(ctx->i_tmpdir) != 0) {
1697 err(1, "failed to unlink temporary directory: %s",
1698 ctx->i_tmpdir);
1699 }
1700 }
1701
1702 int
1703 main(int argc, char **argv)
|
577 /*
578 * We need absolute control over where the temporary file goes, since
579 * we rely on it for cleanup so tempnam(3C) and tmpnam(3C) are
580 * inappropriate (they use TMPDIR, preferentially).
581 *
582 * mkstemp(3C) doesn't actually help us, since the temporary file
583 * isn't used by us, only its name.
584 */
585 if (mktemp(tmpl) == NULL)
586 nomem();
587
588 (void) asprintf(&ret, "%s/%s%s", ctx->i_tmpdir, tmpl,
589 (ext != NULL) ? ext : "");
590
591 if (ret == NULL)
592 nomem();
593
594 return (ret);
595 }
596
597 static boolean_t
598 is_source_file(const char *path)
599 {
600 char *ext = strrchr(path, '.');
601
602 if ((ext == NULL) || ((ext + 1) == '\0'))
603 return (B_FALSE);
604
605 ext += 1;
606
607 if ((strcasecmp(ext, "c") == 0) ||
608 (strcmp(ext, "cc") == 0) ||
609 (strcmp(ext, "i") == 0) ||
610 (strcasecmp(ext, "s") == 0) ||
611 (strcmp(ext, "cpp") == 0)) {
612 return (B_TRUE);
613 }
614
615 return (B_FALSE);
616 }
617
618
619 static void
620 do_gcc(cw_ictx_t *ctx)
621 {
622 int c;
623 int nolibc = 0;
624 int in_output = 0, seen_o = 0, c_files = 0;
625 cw_op_t op = CW_O_LINK;
626 char *model = NULL;
627 char *nameflag;
628 int mflag = 0;
629
630 if (ctx->i_flags & CW_F_PROG) {
631 newae(ctx->i_ae, "--version");
632 return;
633 }
634
635 newae(ctx->i_ae, "-fident");
636 newae(ctx->i_ae, "-finline");
637 newae(ctx->i_ae, "-fno-inline-functions");
638 newae(ctx->i_ae, "-fno-builtin");
664 if (asprintf(&nameflag, "-_%s=", ctx->i_compiler->c_name) == -1)
665 nomem();
666
667 /*
668 * Walk the argument list, translating as we go ..
669 */
670 while (--ctx->i_oldargc > 0) {
671 char *arg = *++ctx->i_oldargv;
672 size_t arglen = strlen(arg);
673
674 if (*arg == '-') {
675 arglen--;
676 } else {
677 /*
678 * Discard inline files that gcc doesn't grok
679 */
680 if (!in_output && arglen > 3 &&
681 strcmp(arg + arglen - 3, ".il") == 0)
682 continue;
683
684 if (!in_output && is_source_file(arg))
685 c_files++;
686
687 /*
688 * Otherwise, filenames and partial arguments
689 * are passed through for gcc to chew on. However,
690 * output is always discarded for the secondary
691 * compiler.
692 */
693 if ((ctx->i_flags & CW_F_SHADOW) && in_output) {
694 newae(ctx->i_ae, discard_file_name(ctx, arg));
695 } else {
696 newae(ctx->i_ae, arg);
697 }
698 in_output = 0;
699 continue;
700 }
701
702 if (ctx->i_flags & CW_F_CXX) {
703 if (strncmp(arg, "-_g++=", 6) == 0) {
704 newae(ctx->i_ae, strchr(arg, '=') + 1);
1368 do_gcc(ctx);
1369 }
1370
1371 static void
1372 do_cc(cw_ictx_t *ctx)
1373 {
1374 int in_output = 0, seen_o = 0, c_files = 0;
1375 cw_op_t op = CW_O_LINK;
1376 char *nameflag;
1377
1378 if (ctx->i_flags & CW_F_PROG) {
1379 newae(ctx->i_ae, "-V");
1380 return;
1381 }
1382
1383 if (asprintf(&nameflag, "-_%s=", ctx->i_compiler->c_name) == -1)
1384 nomem();
1385
1386 while (--ctx->i_oldargc > 0) {
1387 char *arg = *++ctx->i_oldargv;
1388
1389 if (strncmp(arg, "-_CC=", 5) == 0) {
1390 newae(ctx->i_ae, strchr(arg, '=') + 1);
1391 continue;
1392 }
1393
1394 if (*arg != '-') {
1395 if (!in_output && is_source_file(arg))
1396 c_files++;
1397
1398 if (in_output == 0 || !(ctx->i_flags & CW_F_SHADOW)) {
1399 newae(ctx->i_ae, arg);
1400 } else {
1401 in_output = 0;
1402 newae(ctx->i_ae, discard_file_name(ctx, arg));
1403 }
1404 continue;
1405 }
1406 switch (*(arg + 1)) {
1407 case '_':
1408 if ((strncmp(arg, nameflag, strlen(nameflag)) == 0) ||
1409 (strncmp(arg, "-_cc=", 5) == 0) ||
1410 (strncmp(arg, "-_sun=", 6) == 0)) {
1411 newae(ctx->i_ae, strchr(arg, '=') + 1);
1412 }
1413 break;
1414
1415 case 'V':
1676 cleanup(cw_ictx_t *ctx)
1677 {
1678 DIR *dirp;
1679 struct dirent *dp;
1680 char buf[MAXPATHLEN];
1681
1682 if ((dirp = opendir(ctx->i_tmpdir)) == NULL) {
1683 if (errno != ENOENT) {
1684 err(1, "couldn't open temp directory: %s",
1685 ctx->i_tmpdir);
1686 } else {
1687 return;
1688 }
1689 }
1690
1691 errno = 0;
1692 while ((dp = readdir(dirp)) != NULL) {
1693 (void) snprintf(buf, MAXPATHLEN, "%s/%s", ctx->i_tmpdir,
1694 dp->d_name);
1695
1696 if (strcmp(dp->d_name, ".") == 0 ||
1697 strcmp(dp->d_name, "..") == 0) {
1698 continue;
1699 }
1700
1701 if (unlink(buf) == -1)
1702 err(1, "failed to unlink temp file: %s", dp->d_name);
1703 errno = 0;
1704 }
1705
1706 if (errno != 0) {
1707 err(1, "failed to read temporary directory: %s",
1708 ctx->i_tmpdir);
1709 }
1710
1711 (void) closedir(dirp);
1712 if (rmdir(ctx->i_tmpdir) != 0) {
1713 err(1, "failed to unlink temporary directory: %s",
1714 ctx->i_tmpdir);
1715 }
1716 }
1717
1718 int
1719 main(int argc, char **argv)
|