@ -47,17 +47,17 @@ static int arc_mmap_unmap (void *header, size_t headersz, const char **errmsg);
/* bsearch() internal state. */
static __thread char * search_nametbl ;
/* Write out a CTF archive. The entries in CTF_FILES are referenced by name:
the names are passed in the names array , which must have CTF_FILES entries .
/* Write out a CTF archive to the start of the file referenced by the passed-in
fd . The entries in CTF_FILES are referenced by name : the names are passed in
the names array , which must have CTF_FILES entries .
Returns 0 on success , or an errno , or an ECTF_ * value . */
int
ctf_arc_write ( const char * file , ctf_file_t * * ctf_files , size_t ctf_file_cnt ,
const char * * names , size_t threshold )
ctf_arc_write_fd ( int fd , ctf_file_t * * ctf_files , size_t ctf_file_cnt ,
const char * * names , size_t threshold )
{
const char * errmsg ;
struct ctf_archive * archdr ;
int fd ;
size_t i ;
char dummy = 0 ;
size_t headersz ;
@ -68,15 +68,9 @@ ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt,
off_t nameoffs ;
struct ctf_archive_modent * modent ;
ctf_dprintf ( " Writing archive %s with %lu files \n " , file ,
ctf_dprintf ( " Writing CTF archive with %lu files \n " ,
( unsigned long ) ctf_file_cnt ) ;
if ( ( fd = open ( file , O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC , 0666 ) ) < 0 )
{
errmsg = " ctf_arc_write(): cannot create %s: %s \n " ;
goto err ;
}
/* Figure out the size of the mmap()ed header, including the
ctf_archive_modent array . We assume that all of this needs no
padding : a likely assumption , given that it ' s all made up of
@ -91,20 +85,20 @@ ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt,
ctf_startoffs = headersz ;
if ( lseek ( fd , ctf_startoffs - 1 , SEEK_SET ) < 0 )
{
errmsg = " ctf_arc_write(): cannot extend file while writing %s : %s \n " ;
goto err_close ;
errmsg = " ctf_arc_write(): cannot extend file while writing: %s \n " ;
goto err ;
}
if ( write ( fd , & dummy , 1 ) < 0 )
{
errmsg = " ctf_arc_write(): cannot extend file while writing %s : %s \n " ;
goto err_close ;
errmsg = " ctf_arc_write(): cannot extend file while writing: %s \n " ;
goto err ;
}
if ( ( archdr = arc_mmap_header ( fd , headersz ) ) = = NULL )
{
errmsg = " ctf_arc_write(): Cannot mmap() %s : %s \n " ;
goto err_close ;
errmsg = " ctf_arc_write(): Cannot mmap(): %s \n " ;
goto err ;
}
/* Fill in everything we can, which is everything other than the name
@ -137,7 +131,7 @@ ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt,
nametbl = malloc ( namesz ) ;
if ( nametbl = = NULL )
{
errmsg = " Error writing named CTF to %s : %s \n " ;
errmsg = " Error writing named CTF to archive : %s \n " ;
goto err_unmap ;
}
@ -154,12 +148,12 @@ ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt,
if ( ( off < 0 ) & & ( off > - ECTF_BASE ) )
{
errmsg = " ctf_arc_write(): Cannot determine file "
" position while writing %s : %s " ;
" position while writing to archive : %s " ;
goto err_free ;
}
if ( off < 0 )
{
errmsg = " ctf_arc_write(): Cannot write CTF file to %s : %s \n " ;
errmsg = " ctf_arc_write(): Cannot write CTF file to archive : %s \n " ;
errno = off * - 1 ;
goto err_free ;
}
@ -181,7 +175,7 @@ ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt,
if ( ( nameoffs = lseek ( fd , 0 , SEEK_CUR ) ) < 0 )
{
errmsg = " ctf_arc_write(): Cannot get current file position "
" in %s : %s \n " ;
" in archive : %s \n " ;
goto err_free ;
}
archdr - > ctfa_names = htole64 ( nameoffs ) ;
@ -191,7 +185,7 @@ ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt,
ssize_t len ;
if ( ( len = write ( fd , np , namesz ) ) < 0 )
{
errmsg = " ctf_arc_write(): Cannot write name table in %s : %s \n " ;
errmsg = " ctf_arc_write(): Cannot write name table to archive : %s \n " ;
goto err_free ;
}
namesz - = len ;
@ -202,29 +196,64 @@ ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt,
if ( arc_mmap_writeout ( fd , archdr , headersz , & errmsg ) < 0 )
goto err_unmap ;
if ( arc_mmap_unmap ( archdr , headersz , & errmsg ) < 0 )
goto err_unlink ;
if ( close ( fd ) < 0 )
{
errmsg = " ctf_arc_write(): Cannot close after writing to %s: %s \n " ;
goto err_unlink ;
}
goto err ;
return 0 ;
err_free :
free ( nametbl ) ;
err_unmap :
arc_mmap_unmap ( archdr , headersz , NULL ) ;
err_close :
close ( fd ) ;
err_unlink :
unlink ( file ) ;
err :
ctf_dprintf ( errmsg , file , errno < ECTF_BASE ? strerror ( errno ) :
ctf_dprintf ( errmsg , errno < ECTF_BASE ? strerror ( errno ) :
ctf_errmsg ( errno ) ) ;
return errno ;
}
/* Write out a CTF archive. The entries in CTF_FILES are referenced by name:
the names are passed in the names array , which must have CTF_FILES entries .
If the filename is NULL , create a temporary file and return a pointer to it .
Returns 0 on success , or an errno , or an ECTF_ * value . */
int
ctf_arc_write ( const char * file , ctf_file_t * * ctf_files , size_t ctf_file_cnt ,
const char * * names , size_t threshold )
{
int err ;
int fd ;
if ( ( fd = open ( file , O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC , 0666 ) ) < 0 )
{
ctf_dprintf ( " ctf_arc_write(): cannot create %s: %s \n " , file ,
strerror ( errno ) ) ;
return errno ;
}
err = ctf_arc_write_fd ( fd , ctf_files , ctf_file_cnt , names , threshold ) ;
if ( err )
goto err ;
if ( ( err = close ( fd ) ) < 0 )
{
ctf_dprintf ( " ctf_arc_write(): Cannot close after writing to archive: "
" %s \n " , strerror ( errno ) ) ;
goto err_close ;
}
err :
close ( fd ) ;
if ( err < 0 )
unlink ( file ) ;
return err ;
err_close :
if ( err < 0 )
unlink ( file ) ;
return err ;
}
/* Write one CTF file out. Return the file position of the written file (or
rather , of the file - size uint64_t that precedes it ) : negative return is a
negative errno or ctf_errno value . On error , the file position may no longer