18c1441f8SAlexey Samsonov //
2*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
4*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
58c1441f8SAlexey Samsonov
68c1441f8SAlexey Samsonov /*
78c1441f8SAlexey Samsonov * fail.c
88c1441f8SAlexey Samsonov * testObjects
98c1441f8SAlexey Samsonov *
108c1441f8SAlexey Samsonov * Created by Blaine Garst on 9/16/08.
118c1441f8SAlexey Samsonov *
128c1441f8SAlexey Samsonov */
138c1441f8SAlexey Samsonov #include <stdio.h>
148c1441f8SAlexey Samsonov #include <unistd.h>
158c1441f8SAlexey Samsonov #include <fcntl.h>
168c1441f8SAlexey Samsonov #include <string.h>
178c1441f8SAlexey Samsonov #include <stdlib.h>
188c1441f8SAlexey Samsonov #include <stdbool.h>
198c1441f8SAlexey Samsonov
208c1441f8SAlexey Samsonov
readfile(char * buffer,const char * from)218c1441f8SAlexey Samsonov bool readfile(char *buffer, const char *from) {
228c1441f8SAlexey Samsonov int fd = open(from, 0);
238c1441f8SAlexey Samsonov if (fd < 0) return false;
248c1441f8SAlexey Samsonov int count = read(fd, buffer, 512);
258c1441f8SAlexey Samsonov if (count < 0) return false;
268c1441f8SAlexey Samsonov buffer[count] = 0; // zap newline
278c1441f8SAlexey Samsonov return true;
288c1441f8SAlexey Samsonov }
298c1441f8SAlexey Samsonov
308c1441f8SAlexey Samsonov // basic idea, take compiler args, run compiler, and verify that expected failure matches any existing one
318c1441f8SAlexey Samsonov
main(int argc,char * argv[])328c1441f8SAlexey Samsonov int main(int argc, char *argv[]) {
338c1441f8SAlexey Samsonov if (argc == 1) return 0;
348c1441f8SAlexey Samsonov char *copy[argc+1]; // make a copy
358c1441f8SAlexey Samsonov // find and strip off -e "errorfile"
368c1441f8SAlexey Samsonov char *errorfile = NULL;
378c1441f8SAlexey Samsonov int counter = 0, i = 0;
388c1441f8SAlexey Samsonov for (i = 1; i < argc; ++i) { // skip 0 arg which is "fail"
398c1441f8SAlexey Samsonov if (!strncmp(argv[i], "-e", 2)) {
408c1441f8SAlexey Samsonov errorfile = argv[++i];
418c1441f8SAlexey Samsonov }
428c1441f8SAlexey Samsonov else {
438c1441f8SAlexey Samsonov copy[counter++] = argv[i];
448c1441f8SAlexey Samsonov }
458c1441f8SAlexey Samsonov }
468c1441f8SAlexey Samsonov copy[counter] = NULL;
478c1441f8SAlexey Samsonov pid_t child = fork();
488c1441f8SAlexey Samsonov char buffer[512];
498c1441f8SAlexey Samsonov if (child == 0) {
508c1441f8SAlexey Samsonov // in child
518c1441f8SAlexey Samsonov sprintf(buffer, "/tmp/errorfile_%d", getpid());
528c1441f8SAlexey Samsonov close(1);
538c1441f8SAlexey Samsonov int fd = creat(buffer, 0777);
548c1441f8SAlexey Samsonov if (fd != 1) {
558c1441f8SAlexey Samsonov fprintf(stderr, "didn't open custom error file %s as 1, got %d\n", buffer, fd);
568c1441f8SAlexey Samsonov exit(1);
578c1441f8SAlexey Samsonov }
588c1441f8SAlexey Samsonov close(2);
598c1441f8SAlexey Samsonov dup(1);
608c1441f8SAlexey Samsonov int result = execv(copy[0], copy);
618c1441f8SAlexey Samsonov exit(10);
628c1441f8SAlexey Samsonov }
638c1441f8SAlexey Samsonov if (child < 0) {
648c1441f8SAlexey Samsonov printf("fork failed\n");
658c1441f8SAlexey Samsonov exit(1);
668c1441f8SAlexey Samsonov }
678c1441f8SAlexey Samsonov int status = 0;
688c1441f8SAlexey Samsonov pid_t deadchild = wait(&status);
698c1441f8SAlexey Samsonov if (deadchild != child) {
708c1441f8SAlexey Samsonov printf("wait got %d instead of %d\n", deadchild, child);
718c1441f8SAlexey Samsonov exit(1);
728c1441f8SAlexey Samsonov }
738c1441f8SAlexey Samsonov if (WEXITSTATUS(status) == 0) {
748c1441f8SAlexey Samsonov printf("compiler exited normally, not good under these circumstances\n");
758c1441f8SAlexey Samsonov exit(1);
768c1441f8SAlexey Samsonov }
778c1441f8SAlexey Samsonov //printf("exit status of child %d was %d\n", child, WEXITSTATUS(status));
788c1441f8SAlexey Samsonov sprintf(buffer, "/tmp/errorfile_%d", child);
798c1441f8SAlexey Samsonov if (errorfile) {
808c1441f8SAlexey Samsonov //printf("ignoring error file: %s\n", errorfile);
818c1441f8SAlexey Samsonov char desired[512];
828c1441f8SAlexey Samsonov char got[512];
838c1441f8SAlexey Samsonov bool gotErrorFile = readfile(desired, errorfile);
848c1441f8SAlexey Samsonov bool gotOutput = readfile(got, buffer);
858c1441f8SAlexey Samsonov if (!gotErrorFile && gotOutput) {
868c1441f8SAlexey Samsonov printf("didn't read errorfile %s, it should have something from\n*****\n%s\n*****\nin it.\n",
878c1441f8SAlexey Samsonov errorfile, got);
888c1441f8SAlexey Samsonov exit(1);
898c1441f8SAlexey Samsonov }
908c1441f8SAlexey Samsonov else if (gotErrorFile && gotOutput) {
918c1441f8SAlexey Samsonov char *where = strstr(got, desired);
928c1441f8SAlexey Samsonov if (!where) {
938c1441f8SAlexey Samsonov printf("didn't find contents of %s in %s\n", errorfile, buffer);
948c1441f8SAlexey Samsonov exit(1);
958c1441f8SAlexey Samsonov }
968c1441f8SAlexey Samsonov }
978c1441f8SAlexey Samsonov else {
988c1441f8SAlexey Samsonov printf("errorfile %s and output %s inconsistent\n", errorfile, buffer);
998c1441f8SAlexey Samsonov exit(1);
1008c1441f8SAlexey Samsonov }
1018c1441f8SAlexey Samsonov }
1028c1441f8SAlexey Samsonov unlink(buffer);
1038c1441f8SAlexey Samsonov printf("success\n");
1048c1441f8SAlexey Samsonov exit(0);
1058c1441f8SAlexey Samsonov }
1068c1441f8SAlexey Samsonov
107