33 * Copyright © 2009-2023 Inria. All rights reserved.
44 * Copyright © 2009-2012 Université Bordeaux
55 * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
6+ * Copyright © 2023 Université de Reims Champagne-Ardenne. All rights reserved.
67 * See COPYING in top-level directory.
78 */
89
2627#ifdef HAVE_DIRENT_H
2728#include <dirent.h>
2829#endif
30+ #include <fcntl.h>
2931#include <assert.h>
3032
3133extern void usage (const char * name , FILE * where );
@@ -80,15 +82,19 @@ hwloc_utils_input_format_usage(FILE *where, int addspaces)
8082 addspaces , " " );
8183}
8284
83- enum hwloc_utils_input_format {
84- HWLOC_UTILS_INPUT_DEFAULT ,
85- HWLOC_UTILS_INPUT_XML ,
86- HWLOC_UTILS_INPUT_FSROOT ,
87- HWLOC_UTILS_INPUT_SYNTHETIC ,
88- HWLOC_UTILS_INPUT_CPUID ,
89- HWLOC_UTILS_INPUT_SHMEM ,
90- HWLOC_UTILS_INPUT_ARCHIVE
85+ struct hwloc_utils_input_format_s {
86+ enum hwloc_utils_input_format {
87+ HWLOC_UTILS_INPUT_DEFAULT ,
88+ HWLOC_UTILS_INPUT_XML ,
89+ HWLOC_UTILS_INPUT_FSROOT ,
90+ HWLOC_UTILS_INPUT_SYNTHETIC ,
91+ HWLOC_UTILS_INPUT_CPUID ,
92+ HWLOC_UTILS_INPUT_SHMEM ,
93+ HWLOC_UTILS_INPUT_ARCHIVE
94+ } format ;
95+ int oldworkdir ;
9196};
97+ #define HWLOC_UTILS_INPUT_FORMAT_DEFAULT (struct hwloc_utils_input_format_s) { HWLOC_UTILS_INPUT_DEFAULT, -1 }
9298
9399static __hwloc_inline enum hwloc_utils_input_format
94100hwloc_utils_parse_input_format (const char * name , const char * callname )
@@ -115,7 +121,7 @@ hwloc_utils_parse_input_format(const char *name, const char *callname)
115121
116122static __hwloc_inline int
117123hwloc_utils_lookup_input_option (char * argv [], int argc , int * consumed_opts ,
118- char * * inputp , enum hwloc_utils_input_format * input_formatp ,
124+ char * * inputp , struct hwloc_utils_input_format_s * input_formatp ,
119125 const char * callname )
120126{
121127 if (!strcmp (argv [0 ], "--input" )
@@ -137,7 +143,8 @@ hwloc_utils_lookup_input_option(char *argv[], int argc, int *consumed_opts,
137143 usage (callname , stderr );
138144 exit (EXIT_FAILURE );
139145 }
140- * input_formatp = hwloc_utils_parse_input_format (argv [1 ], callname );
146+ * input_formatp = HWLOC_UTILS_INPUT_FORMAT_DEFAULT ;
147+ input_formatp -> format = hwloc_utils_parse_input_format (argv [1 ], callname );
141148 * consumed_opts = 1 ;
142149 return 1 ;
143150 }
@@ -202,9 +209,10 @@ hwloc_utils_autodetect_input_format(const char *input, int verbose)
202209static __hwloc_inline int
203210hwloc_utils_enable_input_format (struct hwloc_topology * topology , unsigned long flags ,
204211 const char * input ,
205- enum hwloc_utils_input_format * input_format ,
212+ struct hwloc_utils_input_format_s * input_formatp ,
206213 int verbose , const char * callname )
207214{
215+ enum hwloc_utils_input_format * input_format = & input_formatp -> format ;
208216 if (* input_format == HWLOC_UTILS_INPUT_DEFAULT && !strcmp (input , "-.xml" )) {
209217 * input_format = HWLOC_UTILS_INPUT_XML ;
210218 input = "-" ;
@@ -283,19 +291,31 @@ hwloc_utils_enable_input_format(struct hwloc_topology *topology, unsigned long f
283291 char umntcmd [512 ];
284292 DIR * dir ;
285293 struct dirent * dirent ;
286- enum hwloc_utils_input_format sub_input_format ;
294+ /* oldworkdir == -1 -> close would fail if !defined(O_PATH), but we don't care */
295+ struct hwloc_utils_input_format_s sub_input_format = HWLOC_UTILS_INPUT_FORMAT_DEFAULT ;
287296 char * subdir = NULL ;
288297 int err ;
289298
299+ #ifdef O_PATH
300+ if (-1 == input_formatp -> oldworkdir ) { /* if archivemount'ed recursively, only keep the first oldworkdir */
301+ sub_input_format .oldworkdir = open ("." , O_DIRECTORY |O_PATH ); /* more efficient than getcwd(3) */
302+ if (sub_input_format .oldworkdir < 0 ) {
303+ perror ("Saving current working directory" );
304+ return EXIT_FAILURE ;
305+ }
306+ }
307+ #endif
290308 if (!mkdtemp (mntpath )) {
291309 perror ("Creating archivemount directory" );
310+ close (sub_input_format .oldworkdir );
292311 return EXIT_FAILURE ;
293312 }
294313 snprintf (mntcmd , sizeof (mntcmd ), "archivemount -o ro %s %s" , input , mntpath );
295314 err = system (mntcmd );
296315 if (err ) {
297316 perror ("Archivemount'ing the archive" );
298317 rmdir (mntpath );
318+ close (sub_input_format .oldworkdir );
299319 return EXIT_FAILURE ;
300320 }
301321 snprintf (umntcmd , sizeof (umntcmd ), "umount -l %s" , mntpath );
@@ -317,16 +337,18 @@ hwloc_utils_enable_input_format(struct hwloc_topology *topology, unsigned long f
317337
318338 if (!subdir ) {
319339 perror ("No subdirectory in archivemount directory" );
340+ close (sub_input_format .oldworkdir );
320341 return EXIT_FAILURE ;
321342 }
322343
323344 /* call ourself recursively on subdir, it should be either a fsroot or a cpuid directory */
324- sub_input_format = HWLOC_UTILS_INPUT_DEFAULT ;
325345 err = hwloc_utils_enable_input_format (topology , flags , subdir , & sub_input_format , verbose , callname );
326346 if (!err )
327- * input_format = sub_input_format ;
328- else
347+ * input_formatp = sub_input_format ;
348+ else {
349+ close (sub_input_format .oldworkdir );
329350 return err ;
351+ }
330352#else
331353 fprintf (stderr , "This installation of hwloc does not support loading from an archive, sorry.\n" );
332354 exit (EXIT_FAILURE );
@@ -351,6 +373,28 @@ hwloc_utils_enable_input_format(struct hwloc_topology *topology, unsigned long f
351373 return 0 ;
352374}
353375
376+ static __hwloc_inline void
377+ hwloc_utils_disable_input_format (struct hwloc_utils_input_format_s * input_format )
378+ {
379+ if (-1 < input_format -> oldworkdir ) {
380+ #ifdef HWLOC_LINUX_SYS
381+ #ifdef O_PATH
382+ int err = fchdir (input_format -> oldworkdir );
383+ if (err ) {
384+ perror ("Restoring current working directory" );
385+ }
386+ #else
387+ fprintf (stderr , "Couldn't restore working directory. Errors may arise.\n" );
388+ #endif
389+ close (input_format -> oldworkdir );
390+ input_format -> oldworkdir = -1 ;
391+ #else
392+ fprintf (stderr , "oldworkdir should not have been changed. You should not have reached this execution branch.\n" );
393+ exit (EXIT_FAILURE );
394+ #endif
395+ }
396+ }
397+
354398static __hwloc_inline void
355399hwloc_utils_print_distance_matrix (FILE * output , unsigned nbobjs , hwloc_obj_t * objs , hwloc_uint64_t * matrix , int logical , int show_types )
356400{
0 commit comments