Sat Apr 11 05:24:30 2015 UTC ()
Use separate vars to track cwd and last dir a process read.


(sjg)
diff -r1.37 -r1.38 src/usr.bin/make/meta.c

cvs diff -r1.37 -r1.38 src/usr.bin/make/meta.c (expand / switch to unified diff)

--- src/usr.bin/make/meta.c 2015/04/01 01:03:55 1.37
+++ src/usr.bin/make/meta.c 2015/04/11 05:24:30 1.38
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: meta.c,v 1.37 2015/04/01 01:03:55 sjg Exp $ */ 1/* $NetBSD: meta.c,v 1.38 2015/04/11 05:24:30 sjg Exp $ */
2 2
3/* 3/*
4 * Implement 'meta' mode. 4 * Implement 'meta' mode.
5 * Adapted from John Birrell's patches to FreeBSD make. 5 * Adapted from John Birrell's patches to FreeBSD make.
6 * --sjg 6 * --sjg
7 */ 7 */
8/* 8/*
9 * Copyright (c) 2009-2010, Juniper Networks, Inc. 9 * Copyright (c) 2009-2010, Juniper Networks, Inc.
10 * Portions Copyright (c) 2009, John Birrell. 10 * Portions Copyright (c) 2009, John Birrell.
11 *  11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions  13 * modification, are permitted provided that the following conditions
14 * are met:  14 * are met:
@@ -838,56 +838,60 @@ string_match(const void *p, const void * @@ -838,56 +838,60 @@ string_match(const void *p, const void *
838{ 838{
839 const char *p1 = p; 839 const char *p1 = p;
840 const char *p2 = q; 840 const char *p2 = q;
841 841
842 return strcmp(p1, p2); 842 return strcmp(p1, p2);
843} 843}
844 844
845 845
846/* 846/*
847 * When running with 'meta' functionality, a target can be out-of-date 847 * When running with 'meta' functionality, a target can be out-of-date
848 * if any of the references in its meta data file is more recent. 848 * if any of the references in its meta data file is more recent.
849 * We have to track the latestdir on a per-process basis. 849 * We have to track the latestdir on a per-process basis.
850 */ 850 */
 851#define LCWD_VNAME_FMT ".meta.%d.lcwd"
851#define LDIR_VNAME_FMT ".meta.%d.ldir" 852#define LDIR_VNAME_FMT ".meta.%d.ldir"
852 853
853/* 854/*
854 * It is possible that a .meta file is corrupted, 855 * It is possible that a .meta file is corrupted,
855 * if we detect this we want to reproduce it. 856 * if we detect this we want to reproduce it.
856 * Setting oodate TRUE will have that effect. 857 * Setting oodate TRUE will have that effect.
857 */ 858 */
858#define CHECK_VALID_META(p) if (!(p && *p)) { \ 859#define CHECK_VALID_META(p) if (!(p && *p)) { \
859 warnx("%s: %d: malformed", fname, lineno); \ 860 warnx("%s: %d: malformed", fname, lineno); \
860 oodate = TRUE; \ 861 oodate = TRUE; \
861 continue; \ 862 continue; \
862 } 863 }
863 864
864#define DEQUOTE(p) if (*p == '\'') { \ 865#define DEQUOTE(p) if (*p == '\'') { \
865 char *ep; \ 866 char *ep; \
866 p++; \ 867 p++; \
867 if ((ep = strchr(p, '\''))) \ 868 if ((ep = strchr(p, '\''))) \
868 *ep = '\0'; \ 869 *ep = '\0'; \
869 } 870 }
870 871
871Boolean 872Boolean
872meta_oodate(GNode *gn, Boolean oodate) 873meta_oodate(GNode *gn, Boolean oodate)
873{ 874{
874 static char *tmpdir = NULL; 875 static char *tmpdir = NULL;
875 static char cwd[MAXPATHLEN]; 876 static char cwd[MAXPATHLEN];
 877 char lcwd_vname[64];
876 char ldir_vname[64]; 878 char ldir_vname[64];
 879 char lcwd[MAXPATHLEN];
877 char latestdir[MAXPATHLEN]; 880 char latestdir[MAXPATHLEN];
878 char fname[MAXPATHLEN]; 881 char fname[MAXPATHLEN];
879 char fname1[MAXPATHLEN]; 882 char fname1[MAXPATHLEN];
880 char fname2[MAXPATHLEN]; 883 char fname2[MAXPATHLEN];
 884 char fname3[MAXPATHLEN];
881 char *p; 885 char *p;
882 char *cp; 886 char *cp;
883 char *link_src; 887 char *link_src;
884 char *move_target; 888 char *move_target;
885 static size_t cwdlen = 0; 889 static size_t cwdlen = 0;
886 static size_t tmplen = 0; 890 static size_t tmplen = 0;
887 FILE *fp; 891 FILE *fp;
888 Boolean needOODATE = FALSE; 892 Boolean needOODATE = FALSE;
889 Lst missingFiles; 893 Lst missingFiles;
890  894
891 if (oodate) 895 if (oodate)
892 return oodate; /* we're done */ 896 return oodate; /* we're done */
893 897
@@ -919,26 +923,28 @@ meta_oodate(GNode *gn, Boolean oodate) @@ -919,26 +923,28 @@ meta_oodate(GNode *gn, Boolean oodate)
919 LstNode ln; 923 LstNode ln;
920 struct stat fs; 924 struct stat fs;
921 925
922 if (!buf) { 926 if (!buf) {
923 bufsz = 8 * BUFSIZ; 927 bufsz = 8 * BUFSIZ;
924 buf = bmake_malloc(bufsz); 928 buf = bmake_malloc(bufsz);
925 } 929 }
926 930
927 if (!cwdlen) { 931 if (!cwdlen) {
928 if (getcwd(cwd, sizeof(cwd)) == NULL) 932 if (getcwd(cwd, sizeof(cwd)) == NULL)
929 err(1, "Could not get current working directory"); 933 err(1, "Could not get current working directory");
930 cwdlen = strlen(cwd); 934 cwdlen = strlen(cwd);
931 } 935 }
 936 strlcpy(lcwd, cwd, sizeof(lcwd));
 937 strlcpy(latestdir, cwd, sizeof(latestdir));
932 938
933 if (!tmpdir) { 939 if (!tmpdir) {
934 tmpdir = getTmpdir(); 940 tmpdir = getTmpdir();
935 tmplen = strlen(tmpdir); 941 tmplen = strlen(tmpdir);
936 } 942 }
937 943
938 /* we want to track all the .meta we read */ 944 /* we want to track all the .meta we read */
939 Var_Append(".MAKE.META.FILES", fname, VAR_GLOBAL); 945 Var_Append(".MAKE.META.FILES", fname, VAR_GLOBAL);
940 946
941 ln = Lst_First(gn->commands); 947 ln = Lst_First(gn->commands);
942 while (!oodate && (x = fgetLine(&buf, &bufsz, 0, fp)) > 0) { 948 while (!oodate && (x = fgetLine(&buf, &bufsz, 0, fp)) > 0) {
943 lineno++; 949 lineno++;
944 if (buf[x - 1] == '\n') 950 if (buf[x - 1] == '\n')
@@ -1002,74 +1008,99 @@ meta_oodate(GNode *gn, Boolean oodate) @@ -1002,74 +1008,99 @@ meta_oodate(GNode *gn, Boolean oodate)
1002 * Each time we spot a different process ('pid') 1008 * Each time we spot a different process ('pid')
1003 * we save the current value of 'latestdir' in a 1009 * we save the current value of 'latestdir' in a
1004 * variable qualified by 'lastpid', and 1010 * variable qualified by 'lastpid', and
1005 * re-initialize 'latestdir' to any pre-saved 1011 * re-initialize 'latestdir' to any pre-saved
1006 * value for the current 'pid' and 'CWD' if none. 1012 * value for the current 'pid' and 'CWD' if none.
1007 */ 1013 */
1008 CHECK_VALID_META(p); 1014 CHECK_VALID_META(p);
1009 pid = atoi(p); 1015 pid = atoi(p);
1010 if (pid > 0 && pid != lastpid) { 1016 if (pid > 0 && pid != lastpid) {
1011 char *ldir; 1017 char *ldir;
1012 char *tp; 1018 char *tp;
1013  1019
1014 if (lastpid > 0) { 1020 if (lastpid > 0) {
1015 /* We need to remember this. */ 1021 /* We need to remember these. */
 1022 Var_Set(lcwd_vname, lcwd, VAR_GLOBAL, 0);
1016 Var_Set(ldir_vname, latestdir, VAR_GLOBAL, 0); 1023 Var_Set(ldir_vname, latestdir, VAR_GLOBAL, 0);
1017 } 1024 }
 1025 snprintf(lcwd_vname, sizeof(lcwd_vname), LCWD_VNAME_FMT, pid);
1018 snprintf(ldir_vname, sizeof(ldir_vname), LDIR_VNAME_FMT, pid); 1026 snprintf(ldir_vname, sizeof(ldir_vname), LDIR_VNAME_FMT, pid);
1019 lastpid = pid; 1027 lastpid = pid;
1020 ldir = Var_Value(ldir_vname, VAR_GLOBAL, &tp); 1028 ldir = Var_Value(ldir_vname, VAR_GLOBAL, &tp);
1021 if (ldir) { 1029 if (ldir) {
1022 strlcpy(latestdir, ldir, sizeof(latestdir)); 1030 strlcpy(latestdir, ldir, sizeof(latestdir));
1023 if (tp) 1031 if (tp)
1024 free(tp); 1032 free(tp);
1025 } else  1033 }
1026 strlcpy(latestdir, cwd, sizeof(latestdir)); 1034 ldir = Var_Value(lcwd_vname, VAR_GLOBAL, &tp);
 1035 if (ldir) {
 1036 strlcpy(lcwd, ldir, sizeof(lcwd));
 1037 if (tp)
 1038 free(tp);
 1039 }
1027 } 1040 }
1028 /* Skip past the pid. */ 1041 /* Skip past the pid. */
1029 if (strsep(&p, " ") == NULL) 1042 if (strsep(&p, " ") == NULL)
1030 continue; 1043 continue;
1031#ifdef DEBUG_META_MODE 1044#ifdef DEBUG_META_MODE
1032 if (DEBUG(META)) 1045 if (DEBUG(META))
1033 fprintf(debug_file, "%s: %d: cwd=%s ldir=%s\n", fname, lineno, cwd, latestdir); 1046 fprintf(debug_file, "%s: %d: %d: %c: cwd=%s lcwd=%s ldir=%s\n",
 1047 fname, lineno,
 1048 pid, buf[0], cwd, lcwd, latestdir);
1034#endif 1049#endif
1035 break; 1050 break;
1036 } 1051 }
1037 1052
1038 CHECK_VALID_META(p); 1053 CHECK_VALID_META(p);
1039 1054
1040 /* Process according to record type. */ 1055 /* Process according to record type. */
1041 switch (buf[0]) { 1056 switch (buf[0]) {
1042 case 'X': /* eXit */ 1057 case 'X': /* eXit */
 1058 Var_Delete(lcwd_vname, VAR_GLOBAL);
1043 Var_Delete(ldir_vname, VAR_GLOBAL); 1059 Var_Delete(ldir_vname, VAR_GLOBAL);
1044 lastpid = 0; /* no need to save ldir_vname */ 1060 lastpid = 0; /* no need to save ldir_vname */
1045 break; 1061 break;
1046 1062
1047 case 'F': /* [v]Fork */ 1063 case 'F': /* [v]Fork */
1048 { 1064 {
1049 char cldir[64]; 1065 char cldir[64];
1050 int child; 1066 int child;
1051 1067
1052 child = atoi(p); 1068 child = atoi(p);
1053 if (child > 0) { 1069 if (child > 0) {
 1070 snprintf(cldir, sizeof(cldir), LCWD_VNAME_FMT, child);
 1071 Var_Set(cldir, lcwd, VAR_GLOBAL, 0);
1054 snprintf(cldir, sizeof(cldir), LDIR_VNAME_FMT, child); 1072 snprintf(cldir, sizeof(cldir), LDIR_VNAME_FMT, child);
1055 Var_Set(cldir, latestdir, VAR_GLOBAL, 0); 1073 Var_Set(cldir, latestdir, VAR_GLOBAL, 0);
 1074#ifdef DEBUG_META_MODE
 1075 if (DEBUG(META))
 1076 fprintf(debug_file, "%s: %d: %d: cwd=%s lcwd=%s ldir=%s\n",
 1077 fname, lineno,
 1078 child, cwd, lcwd, latestdir);
 1079#endif
1056 } 1080 }
1057 } 1081 }
1058 break; 1082 break;
1059 1083
1060 case 'C': /* Chdir */ 1084 case 'C': /* Chdir */
1061 /* Update the latest directory. */ 1085 /* Update lcwd and latest directory. */
1062 strlcpy(latestdir, p, sizeof(latestdir)); 1086 strlcpy(latestdir, p, sizeof(latestdir));
 1087 strlcpy(lcwd, p, sizeof(lcwd));
 1088 Var_Set(lcwd_vname, lcwd, VAR_GLOBAL, 0);
 1089 Var_Set(ldir_vname, lcwd, VAR_GLOBAL, 0);
 1090#ifdef DEBUG_META_MODE
 1091 if (DEBUG(META))
 1092 fprintf(debug_file, "%s: %d: cwd=%s ldir=%s\n", fname, lineno, cwd, lcwd);
 1093#endif
1063 break; 1094 break;
1064 1095
1065 case 'M': /* renaMe */ 1096 case 'M': /* renaMe */
1066 /* 1097 /*
1067 * For 'M'oves we want to check 1098 * For 'M'oves we want to check
1068 * the src as for 'R'ead 1099 * the src as for 'R'ead
1069 * and the target as for 'W'rite. 1100 * and the target as for 'W'rite.
1070 */ 1101 */
1071 cp = p; /* save this for a second */ 1102 cp = p; /* save this for a second */
1072 /* now get target */ 1103 /* now get target */
1073 if (strsep(&p, " ") == NULL) 1104 if (strsep(&p, " ") == NULL)
1074 continue; 1105 continue;
1075 CHECK_VALID_META(p); 1106 CHECK_VALID_META(p);
@@ -1198,31 +1229,36 @@ meta_oodate(GNode *gn, Boolean oodate) @@ -1198,31 +1229,36 @@ meta_oodate(GNode *gn, Boolean oodate)
1198 int sdx = 0; 1229 int sdx = 0;
1199 int found = 0; 1230 int found = 0;
1200 1231
1201 if (*p == '/') { 1232 if (*p == '/') {
1202 sdirs[sdx++] = p; /* done */ 1233 sdirs[sdx++] = p; /* done */
1203 } else { 1234 } else {
1204 if (strcmp(".", p) == 0) 1235 if (strcmp(".", p) == 0)
1205 continue; /* no point */ 1236 continue; /* no point */
1206 1237
1207 /* Check vs latestdir */ 1238 /* Check vs latestdir */
1208 snprintf(fname1, sizeof(fname1), "%s/%s", latestdir, p); 1239 snprintf(fname1, sizeof(fname1), "%s/%s", latestdir, p);
1209 sdirs[sdx++] = fname1; 1240 sdirs[sdx++] = fname1;
1210 1241
1211 if (strcmp(latestdir, cwd) != 0) { 1242 if (strcmp(latestdir, lcwd) != 0) {
1212 /* Check vs cwd */ 1243 /* Check vs lcwd */
1213 snprintf(fname2, sizeof(fname2), "%s/%s", cwd, p); 1244 snprintf(fname2, sizeof(fname2), "%s/%s", lcwd, p);
1214 sdirs[sdx++] = fname2; 1245 sdirs[sdx++] = fname2;
1215 } 1246 }
 1247 if (strcmp(lcwd, cwd) != 0) {
 1248 /* Check vs cwd */
 1249 snprintf(fname3, sizeof(fname3), "%s/%s", cwd, p);
 1250 sdirs[sdx++] = fname3;
 1251 }
1216 } 1252 }
1217 sdirs[sdx++] = NULL; 1253 sdirs[sdx++] = NULL;
1218 1254
1219 for (sdp = sdirs; *sdp && !found; sdp++) { 1255 for (sdp = sdirs; *sdp && !found; sdp++) {
1220#ifdef DEBUG_META_MODE 1256#ifdef DEBUG_META_MODE
1221 if (DEBUG(META)) 1257 if (DEBUG(META))
1222 fprintf(debug_file, "%s: %d: looking for: %s\n", fname, lineno, *sdp); 1258 fprintf(debug_file, "%s: %d: looking for: %s\n", fname, lineno, *sdp);
1223#endif 1259#endif
1224 if (stat(*sdp, &fs) == 0) { 1260 if (stat(*sdp, &fs) == 0) {
1225 found = 1; 1261 found = 1;
1226 p = *sdp; 1262 p = *sdp;
1227 } 1263 }
1228 } 1264 }
@@ -1241,26 +1277,30 @@ meta_oodate(GNode *gn, Boolean oodate) @@ -1241,26 +1277,30 @@ meta_oodate(GNode *gn, Boolean oodate)
1241 realpath(p, latestdir); 1277 realpath(p, latestdir);
1242 } 1278 }
1243 } else if (errno == ENOENT && *p == '/' && 1279 } else if (errno == ENOENT && *p == '/' &&
1244 strncmp(p, cwd, cwdlen) != 0) { 1280 strncmp(p, cwd, cwdlen) != 0) {
1245 /* 1281 /*
1246 * A referenced file outside of CWD is missing. 1282 * A referenced file outside of CWD is missing.
1247 * We cannot catch every eventuality here... 1283 * We cannot catch every eventuality here...
1248 */ 1284 */
1249 if (DEBUG(META)) 1285 if (DEBUG(META))
1250 fprintf(debug_file, "%s: %d: file '%s' may have moved?...\n", fname, lineno, p); 1286 fprintf(debug_file, "%s: %d: file '%s' may have moved?...\n", fname, lineno, p);
1251 oodate = TRUE; 1287 oodate = TRUE;
1252 } 1288 }
1253 } 1289 }
 1290 if (buf[0] == 'E') {
 1291 /* previous latestdir is no longer relevant */
 1292 strlcpy(latestdir, lcwd, sizeof(latestdir));
 1293 }
1254 break; 1294 break;
1255 default: 1295 default:
1256 break; 1296 break;
1257 } 1297 }
1258 if (!oodate && buf[0] == 'L' && link_src != NULL) 1298 if (!oodate && buf[0] == 'L' && link_src != NULL)
1259 goto check_link_src; 1299 goto check_link_src;
1260 } else if (strcmp(buf, "CMD") == 0) { 1300 } else if (strcmp(buf, "CMD") == 0) {
1261 /* 1301 /*
1262 * Compare the current command with the one in the 1302 * Compare the current command with the one in the
1263 * meta data file. 1303 * meta data file.
1264 */ 1304 */
1265 if (ln == NULL) { 1305 if (ln == NULL) {
1266 if (DEBUG(META)) 1306 if (DEBUG(META))