@@ -78,71 +78,83 @@ class CgroupController: public CHeapObj<mtInternal> {
7878
7979PRAGMA_DIAG_PUSH
8080PRAGMA_FORMAT_NONLITERAL_IGNORED
81+ // Parses a subsystem's file, looking for a matching line.
82+ // If key is null, then the first line will be matched with scan_fmt.
83+ // If key isn't null, then each line will be matched, looking for something that matches "$key $scan_fmt".
84+ // The matching value will be assigned to returnval.
85+ // scan_fmt uses scanf() syntax.
86+ // Return value: 0 on match, OSCONTAINER_ERROR on error.
8187template <typename T> int subsystem_file_line_contents (CgroupController* c,
8288 const char *filename,
83- const char *matchline ,
89+ const char *key ,
8490 const char *scan_fmt,
8591 T returnval) {
86- FILE *fp = NULL ;
87- char *p;
88- char file[MAXPATHLEN+1 ];
89- char buf[MAXPATHLEN+1 ];
90- char discard[MAXPATHLEN+1 ];
91- bool found_match = false ;
92+ if (c == nullptr ) {
93+ log_debug (os, container)(" subsystem_file_line_contents: CgroupController* is nullptr" );
94+ return OSCONTAINER_ERROR;
95+ }
96+ if (c->subsystem_path () == nullptr ) {
97+ log_debug (os, container)(" subsystem_file_line_contents: subsystem path is nullptr" );
98+ return OSCONTAINER_ERROR;
99+ }
100+
101+ stringStream file_path;
102+ file_path.print_raw (c->subsystem_path ());
103+ file_path.print_raw (filename);
92104
93- if (c == NULL ) {
94- log_debug (os, container)(" subsystem_file_line_contents: CgroupController* is NULL " );
105+ if (file_path. size () > (MAXPATHLEN- 1 ) ) {
106+ log_debug (os, container)(" File path too long %s, %s " , file_path. base (), filename );
95107 return OSCONTAINER_ERROR;
96108 }
97- if (c->subsystem_path () == NULL ) {
98- log_debug (os, container)(" subsystem_file_line_contents: subsystem path is NULL" );
109+ const char * absolute_path = file_path.freeze ();
110+ log_trace (os, container)(" Path to %s is %s" , filename, absolute_path);
111+
112+ FILE* fp = fopen (absolute_path, " r" );
113+ if (fp == nullptr ) {
114+ log_debug (os, container)(" Open of file %s failed, %s" , absolute_path, os::strerror (errno));
99115 return OSCONTAINER_ERROR;
100116 }
101117
102- strncpy (file, c->subsystem_path (), MAXPATHLEN);
103- file[MAXPATHLEN-1 ] = ' \0 ' ;
104- int filelen = strlen (file);
105- if ((filelen + strlen (filename)) > (MAXPATHLEN-1 )) {
106- log_debug (os, container)(" File path too long %s, %s" , file, filename);
118+ const int buf_len = MAXPATHLEN+1 ;
119+ char buf[buf_len];
120+ char * line = fgets (buf, buf_len, fp);
121+ if (line == nullptr ) {
122+ log_debug (os, container)(" Empty file %s" , absolute_path);
123+ fclose (fp);
107124 return OSCONTAINER_ERROR;
108125 }
109- strncat (file, filename, MAXPATHLEN-filelen);
110- log_trace (os, container)(" Path to %s is %s" , filename, file);
111- fp = fopen (file, " r" );
112- if (fp != NULL ) {
113- int err = 0 ;
114- while ((p = fgets (buf, MAXPATHLEN, fp)) != NULL ) {
115- found_match = false ;
116- if (matchline == NULL ) {
117- // single-line file case
118- int matched = sscanf (p, scan_fmt, returnval);
119- found_match = (matched == 1 );
120- } else {
121- // multi-line file case
122- if (strstr (p, matchline) != NULL ) {
123- // discard matchline string prefix
124- int matched = sscanf (p, scan_fmt, discard, returnval);
125- found_match = (matched == 2 );
126- } else {
127- continue ; // substring not found
126+
127+ bool found_match = false ;
128+ if (key == nullptr ) {
129+ // File consists of a single line according to caller, with only a value
130+ int matched = sscanf (line, scan_fmt, returnval);
131+ found_match = matched == 1 ;
132+ } else {
133+ // File consists of multiple lines in a "key value"
134+ // fashion, we have to find the key.
135+ const int key_len = strlen (key);
136+ for (; line != nullptr ; line = fgets (buf, buf_len, fp)) {
137+ char * key_substr = strstr (line, key);
138+ char after_key = line[key_len];
139+ if (key_substr == line
140+ && isspace (after_key) != 0
141+ && after_key != ' \n ' ) {
142+ // Skip key, skip space
143+ const char * value_substr = line + key_len + 1 ;
144+ int matched = sscanf (value_substr, scan_fmt, returnval);
145+ found_match = matched == 1 ;
146+ if (found_match) {
147+ break ;
128148 }
129149 }
130- if (found_match) {
131- fclose (fp);
132- return 0 ;
133- } else {
134- err = 1 ;
135- log_debug (os, container)(" Type %s not found in file %s" , scan_fmt, file);
136- }
137150 }
138- if (err == 0 ) {
139- log_debug (os, container)(" Empty file %s" , file);
140- }
141- } else {
142- log_debug (os, container)(" Open of file %s failed, %s" , file, os::strerror (errno));
143151 }
144- if (fp != NULL )
145- fclose (fp);
152+ fclose (fp);
153+ if (found_match) {
154+ return 0 ;
155+ }
156+ log_debug (os, container)(" Type %s (key == %s) not found in file %s" , scan_fmt,
157+ (key == nullptr ? " null" : key), absolute_path);
146158 return OSCONTAINER_ERROR;
147159}
148160PRAGMA_DIAG_POP
0 commit comments