static foreign_t archive_next_header(term_t archive, term_t name) { archive_wrapper *ar; int rc; if ( !get_archive(archive, &ar) ) return FALSE; if ( ar->status == AR_NEW_ENTRY ) archive_read_data_skip(ar->archive); if ( ar->status == AR_OPENED_ENTRY ) return PL_permission_error("next_header", "archive", archive); while ( (rc=archive_read_next_header(ar->archive, &ar->entry)) == ARCHIVE_OK ) { if ( PL_unify_wchars(name, PL_ATOM, -1, archive_entry_pathname_w(ar->entry)) ) { ar->status = AR_NEW_ENTRY; return TRUE; } if ( PL_exception(0) ) return FALSE; } if ( rc == ARCHIVE_EOF ) return FALSE; /* simply at the end */ return archive_error(ar); }
static int error(int error, const char *op, const char *type, term_t culprit) { if ( error == EAGAIN ) return PL_resource_error("rlimit_nproc"); else if ( error == EMFILE ) return PL_resource_error("max_files"); else if ( error == ENOMEM ) return PL_resource_error("memory"); else if ( error == ERANGE ) return PL_resource_error("buffer_space"); else return PL_permission_error(op, type, culprit); }
static int zunlock(zipper *z) { int tid = PL_thread_self(); if ( z->owner == tid ) { if ( z->lock_count == 0 ) { term_t t; error: { GET_LD return ( (t=PL_new_term_ref()) && unify_zipper(t, z) && PL_permission_error("unlock", "zipper", t) ); } } if ( --z->lock_count == 0 ) { z->owner = 0; simpleMutexUnlock(&z->lock); } } else
static int get_archive(term_t t, archive_wrapper **arp) { PL_blob_t *type; void *data; if ( PL_get_blob(t, &data, NULL, &type) && type == &archive_blob) { archive_wrapper *ar = data; assert(ar->magic == ARCHIVE_MAGIC); if ( ar->symbol ) { *arp = ar; return TRUE; } PL_permission_error("access", "closed_archive", t); return FALSE; } return PL_type_error("archive", t); }
static foreign_t archive_header_prop(term_t archive, term_t field) { archive_wrapper *ar; functor_t prop; if ( !get_archive(archive, &ar) ) return FALSE; if ( !PL_get_functor(field, &prop) ) return PL_type_error("compound", field); if ( ar->status != AR_NEW_ENTRY ) return PL_permission_error("access", "archive_entry", archive); if ( prop == FUNCTOR_filetype1 ) { __LA_MODE_T type = archive_entry_filetype(ar->entry); atom_t name; term_t arg = PL_new_term_ref(); _PL_get_arg(1, field, arg); switch(type&AE_IFMT) { case AE_IFREG: name = ATOM_file; break; case AE_IFLNK: name = ATOM_link; break; case AE_IFSOCK: name = ATOM_socket; break; case AE_IFCHR: name = ATOM_character_device; break; case AE_IFBLK: name = ATOM_block_device; break; case AE_IFDIR: name = ATOM_directory; break; case AE_IFIFO: name = ATOM_fifo; break; default: return PL_unify_integer(arg, (type&AE_IFMT)); } return PL_unify_atom(arg, name); } else if ( prop == FUNCTOR_mtime1 ) { time_t stamp = archive_entry_mtime(ar->entry); term_t arg = PL_new_term_ref(); _PL_get_arg(1, field, arg); return PL_unify_float(arg, (double)stamp); } else if ( prop == FUNCTOR_size1 ) { int64_t size = archive_entry_size(ar->entry); term_t arg = PL_new_term_ref(); _PL_get_arg(1, field, arg); return PL_unify_int64(arg, size); } else if ( prop == FUNCTOR_link_target1 ) { __LA_MODE_T type = archive_entry_filetype(ar->entry); const wchar_t *target = NULL; switch(type&AE_IFMT) { case AE_IFLNK: target = archive_entry_symlink_w(ar->entry); break; } if ( target ) { term_t arg = PL_new_term_ref(); _PL_get_arg(1, field, arg); return PL_unify_wchars(arg, PL_ATOM, (size_t)-1, target); } return FALSE; } else if ( prop == FUNCTOR_format1 ) { const char *s = archive_format_name(ar->archive); if ( s ) { char lwr[50]; char *o; term_t arg = PL_new_term_ref(); _PL_get_arg(1, field, arg); for(o=lwr; *s && o < lwr+sizeof(lwr); ) *o++ = tolower(*s++); *o = '\0'; return PL_unify_atom_chars(arg, lwr); } } return PL_domain_error("archive_header_property", field); }