Exemple #1
0
/*****************************************************************************
 * Open: probe the encoder
 *****************************************************************************/
static int  Open ( vlc_object_t *p_this )
{
    encoder_t     *p_enc = (encoder_t *)p_this;
    encoder_sys_t *p_sys;
    int i_val;
    char *psz_val;
    int i_qmin = 0, i_qmax = 0;
    x264_nal_t    *nal;
    int i, i_nal;

    if( p_enc->fmt_out.i_codec != VLC_CODEC_H264 &&
        !p_enc->b_force )
    {
        return VLC_EGENERIC;
    }
    /* X264_POINTVER or X264_VERSION are not available */
    msg_Dbg ( p_enc, "version x264 0.%d.X", X264_BUILD );

    config_ChainParse( p_enc, SOUT_CFG_PREFIX, ppsz_sout_options, p_enc->p_cfg );

    p_enc->fmt_out.i_cat = VIDEO_ES;
    p_enc->fmt_out.i_codec = VLC_CODEC_H264;
    p_enc->fmt_in.i_codec = VLC_CODEC_I420;

    p_enc->pf_encode_video = Encode;
    p_enc->pf_encode_audio = NULL;
    p_enc->p_sys = p_sys = malloc( sizeof( encoder_sys_t ) );
    if( !p_sys )
        return VLC_ENOMEM;
    p_sys->i_interpolated_dts = 0;
    p_sys->psz_stat_name = NULL;
    p_sys->p_buffer = NULL;

    x264_param_default( &p_sys->param );
    p_sys->param.i_width  = p_enc->fmt_in.video.i_width;
    p_sys->param.i_height = p_enc->fmt_in.video.i_height;

    p_sys->param.rc.f_qcompress = var_GetFloat( p_enc, SOUT_CFG_PREFIX "qcomp" );

    /* transcode-default bitrate is 0,
     * set more to ABR if user specifies bitrate */
    if( p_enc->fmt_out.i_bitrate > 0 )
    {
        p_sys->param.rc.i_bitrate = p_enc->fmt_out.i_bitrate / 1000;
        p_sys->param.rc.i_rc_method = X264_RC_ABR;
    }
    else /* Set default to CRF */
    {
        i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "crf" );
        if( i_val > 0 && i_val <= 51 )
        {
            p_sys->param.rc.f_rf_constant = i_val;
            p_sys->param.rc.i_rc_method = X264_RC_CRF;
        }
    }

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "qpstep" );
    if( i_val >= 0 && i_val <= 51 ) p_sys->param.rc.i_qp_step = i_val;

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "qpmin" );
    if( i_val >= 0 && i_val <= 51 )
    {
        i_qmin = i_val;
        p_sys->param.rc.i_qp_min = i_qmin;
    }
    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "qpmax" );
    if( i_val >= 0 && i_val <= 51 )
    {
        i_qmax = i_val;
        p_sys->param.rc.i_qp_max = i_qmax;
    }

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "qp" );
    if( i_val >= 0 && i_val <= 51 )
    {
        if( i_qmin > i_val ) i_qmin = i_val;
        if( i_qmax < i_val ) i_qmax = i_val;

        /* User defined QP-value, so change ratecontrol method */
        p_sys->param.rc.i_rc_method = X264_RC_CQP;
        p_sys->param.rc.i_qp_constant = i_val;
        p_sys->param.rc.i_qp_min = i_qmin;
        p_sys->param.rc.i_qp_max = i_qmax;
    }


    p_sys->param.rc.f_rate_tolerance = var_GetFloat( p_enc,
                            SOUT_CFG_PREFIX "ratetol" );
    p_sys->param.rc.f_vbv_buffer_init = var_GetFloat( p_enc,
                            SOUT_CFG_PREFIX "vbv-init" );
    p_sys->param.rc.i_vbv_buffer_size = var_GetInteger( p_enc,
                            SOUT_CFG_PREFIX "vbv-bufsize" );

    /* max bitrate = average bitrate -> CBR */
    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "vbv-maxrate" );

    if( !i_val && p_sys->param.rc.i_rc_method == X264_RC_ABR )
        p_sys->param.rc.i_vbv_max_bitrate = p_sys->param.rc.i_bitrate;
    else if ( i_val )
        p_sys->param.rc.i_vbv_max_bitrate = i_val;

    p_sys->param.b_cabac = var_GetBool( p_enc, SOUT_CFG_PREFIX "cabac" );

    /* disable deblocking when nf (no loop filter) is enabled */
    p_sys->param.b_deblocking_filter = !var_GetBool( p_enc, SOUT_CFG_PREFIX "nf" );

    psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "deblock" );
    if( psz_val )
    {
        char *p = strchr( psz_val, ':' );
        p_sys->param.i_deblocking_filter_alphac0 = atoi( psz_val );
        p_sys->param.i_deblocking_filter_beta = p ?
                    atoi( p+1 ) : p_sys->param.i_deblocking_filter_alphac0;
        free( psz_val );
    }

    psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "psy-rd" );
    if( psz_val )
    {
        char *p = strchr( psz_val, ':' );
        p_sys->param.analyse.f_psy_rd = us_atof( psz_val );
        p_sys->param.analyse.f_psy_trellis = p ? us_atof( p+1 ) : 0;
        free( psz_val );
    }

    psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "level" );
    if( psz_val )
    {
        if( us_atof (psz_val) < 6 )
            p_sys->param.i_level_idc = (int) (10 * us_atof (psz_val)
                                              + .5);
        else
            p_sys->param.i_level_idc = atoi (psz_val);
        free( psz_val );
    }

    p_sys->param.b_interlaced = var_GetBool( p_enc, SOUT_CFG_PREFIX "interlaced" );
    p_sys->param.rc.f_ip_factor = var_GetFloat( p_enc, SOUT_CFG_PREFIX "ipratio" );
    p_sys->param.rc.f_pb_factor = var_GetFloat( p_enc, SOUT_CFG_PREFIX "pbratio" );
    p_sys->param.rc.f_complexity_blur = var_GetFloat( p_enc, SOUT_CFG_PREFIX "cplxblur" );
    p_sys->param.rc.f_qblur = var_GetFloat( p_enc, SOUT_CFG_PREFIX "qblur" );
    p_sys->param.rc.i_aq_mode = var_GetInteger( p_enc, SOUT_CFG_PREFIX "aq-mode" );
    p_sys->param.rc.f_aq_strength = var_GetFloat( p_enc, SOUT_CFG_PREFIX "aq-strength" );

    if( var_GetBool( p_enc, SOUT_CFG_PREFIX "verbose" ) )
        p_sys->param.i_log_level = X264_LOG_DEBUG;

    if( var_GetBool( p_enc, SOUT_CFG_PREFIX "quiet" ) )
        p_sys->param.i_log_level = X264_LOG_NONE;

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "sps-id" );
    if( i_val >= 0 ) p_sys->param.i_sps_id = i_val;

    if( var_GetBool( p_enc, SOUT_CFG_PREFIX "aud" ) )
        p_sys->param.b_aud = true;

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "keyint" );
    if( i_val > 0 ) p_sys->param.i_keyint_max = i_val;

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "min-keyint" );
    if( i_val > 0 ) p_sys->param.i_keyint_min = i_val;

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "bframes" );
    if( i_val >= 0 && i_val <= 16 )
        p_sys->param.i_bframe = i_val;

#if X264_BUILD >= 78
    psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "bpyramid" );
    p_sys->param.i_bframe_pyramid = X264_B_PYRAMID_NONE;
    if( !strcmp( psz_val, "none" ) )
    {
       p_sys->param.i_bframe_pyramid = X264_B_PYRAMID_NONE;
    } else if ( !strcmp( psz_val, "strict" ) )
    {
       p_sys->param.i_bframe_pyramid = X264_B_PYRAMID_STRICT;
    } else if ( !strcmp( psz_val, "normal" ) )
    {
       p_sys->param.i_bframe_pyramid = X264_B_PYRAMID_NORMAL;
    }
    free( psz_val );
#else
    p_sys->param.b_bframe_pyramid = var_GetBool( p_enc, SOUT_CFG_PREFIX "bpyramid" );
 #endif

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "ref" );
    if( i_val > 0 && i_val <= 15 )
        p_sys->param.i_frame_reference = i_val;

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "scenecut" );
    if( i_val >= -1 && i_val <= 100 )
        p_sys->param.i_scenecut_threshold = i_val;

    p_sys->param.b_deterministic = var_GetBool( p_enc,
                        SOUT_CFG_PREFIX "non-deterministic" );

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "subme" );
    if( i_val >= 1 && i_val <= SUBME_MAX )
        p_sys->param.analyse.i_subpel_refine = i_val;

    //TODO: psz_val == NULL ?
    psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "me" );
    if( !strcmp( psz_val, "dia" ) )
    {
        p_sys->param.analyse.i_me_method = X264_ME_DIA;
    }
    else if( !strcmp( psz_val, "hex" ) )
    {
        p_sys->param.analyse.i_me_method = X264_ME_HEX;
    }
    else if( !strcmp( psz_val, "umh" ) )
    {
        p_sys->param.analyse.i_me_method = X264_ME_UMH;
    }
    else if( !strcmp( psz_val, "esa" ) )
    {
        p_sys->param.analyse.i_me_method = X264_ME_ESA;
    }
    else if( !strcmp( psz_val, "tesa" ) )
    {
        p_sys->param.analyse.i_me_method = X264_ME_TESA;
    }
    free( psz_val );

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "merange" );
    if( i_val >= 0 && i_val <= 64 )
        p_sys->param.analyse.i_me_range = i_val;

    p_sys->param.analyse.i_mv_range = var_GetInteger( p_enc,
                                    SOUT_CFG_PREFIX "mvrange" );
    p_sys->param.analyse.i_mv_range_thread = var_GetInteger( p_enc,
                                    SOUT_CFG_PREFIX "mvrange-thread" );

    psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "direct" );
    if( !strcmp( psz_val, "none" ) )
    {
        p_sys->param.analyse.i_direct_mv_pred = X264_DIRECT_PRED_NONE;
    }
    else if( !strcmp( psz_val, "spatial" ) )
    {
        p_sys->param.analyse.i_direct_mv_pred = X264_DIRECT_PRED_SPATIAL;
    }
    else if( !strcmp( psz_val, "temporal" ) )
    {
        p_sys->param.analyse.i_direct_mv_pred = X264_DIRECT_PRED_TEMPORAL;
    }
    else if( !strcmp( psz_val, "auto" ) )
    {
        p_sys->param.analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO;
    }
    free( psz_val );

    p_sys->param.analyse.b_psnr = var_GetBool( p_enc, SOUT_CFG_PREFIX "psnr" );
    p_sys->param.analyse.b_ssim = var_GetBool( p_enc, SOUT_CFG_PREFIX "ssim" );
    p_sys->param.analyse.b_weighted_bipred = var_GetBool( p_enc,
                                    SOUT_CFG_PREFIX "weightb" );
    p_sys->param.i_bframe_adaptive = var_GetInteger( p_enc,
                                    SOUT_CFG_PREFIX "b-adapt" );

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "b-bias" );
    if( i_val >= -100 && i_val <= 100 )
        p_sys->param.i_bframe_bias = i_val;

    p_sys->param.analyse.b_chroma_me = var_GetBool( p_enc,
                                    SOUT_CFG_PREFIX "chroma-me" );
    p_sys->param.analyse.i_chroma_qp_offset = var_GetInteger( p_enc,
                                    SOUT_CFG_PREFIX "chroma-qp-offset" );
    p_sys->param.analyse.b_mixed_references = var_GetBool( p_enc,
                                    SOUT_CFG_PREFIX "mixed-refs" );

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "trellis" );
    if( i_val >= 0 && i_val <= 2 )
        p_sys->param.analyse.i_trellis = i_val;

    p_sys->param.analyse.b_fast_pskip = var_GetBool( p_enc,
                                    SOUT_CFG_PREFIX "fast-pskip" );

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "nr" );
    if( i_val >= 0 && i_val <= 1000 )
        p_sys->param.analyse.i_noise_reduction = i_val;

    p_sys->param.analyse.b_dct_decimate = var_GetBool( p_enc,
                                    SOUT_CFG_PREFIX "dct-decimate" );

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "deadzone-inter" );
    if( i_val >= 0 && i_val <= 32 )
        p_sys->param.analyse.i_luma_deadzone[0] = i_val;

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "deadzone-intra" );
    if( i_val >= 0 && i_val <= 32 )
        p_sys->param.analyse.i_luma_deadzone[1] = i_val;

    if( !var_GetBool( p_enc, SOUT_CFG_PREFIX "asm" ) )
        p_sys->param.cpu = 0;

#ifndef X264_ANALYSE_BSUB16x16
#   define X264_ANALYSE_BSUB16x16 0
#endif
    psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "partitions" );
    if( !strcmp( psz_val, "none" ) )
    {
        p_sys->param.analyse.inter = 0;
    }
    else if( !strcmp( psz_val, "fast" ) )
    {
        p_sys->param.analyse.inter = X264_ANALYSE_I4x4;
    }
    else if( !strcmp( psz_val, "normal" ) )
    {
        p_sys->param.analyse.inter =
            X264_ANALYSE_I4x4 |
            X264_ANALYSE_PSUB16x16;
#ifdef X264_ANALYSE_I8x8
        p_sys->param.analyse.inter |= X264_ANALYSE_I8x8;
#endif
    }
    else if( !strcmp( psz_val, "slow" ) )
    {
        p_sys->param.analyse.inter =
            X264_ANALYSE_I4x4 |
            X264_ANALYSE_PSUB16x16 |
            X264_ANALYSE_BSUB16x16;
#ifdef X264_ANALYSE_I8x8
        p_sys->param.analyse.inter |= X264_ANALYSE_I8x8;
#endif
    }
    else if( !strcmp( psz_val, "all" ) )
    {
        p_sys->param.analyse.inter = ~0;
    }
    free( psz_val );

    p_sys->param.analyse.b_transform_8x8 = var_GetBool( p_enc,
                                    SOUT_CFG_PREFIX "8x8dct" );

    if( p_enc->fmt_in.video.i_aspect > 0 )
    {
        int64_t i_num, i_den;
        unsigned int i_dst_num, i_dst_den;

        i_num = p_enc->fmt_in.video.i_aspect *
            (int64_t)p_enc->fmt_in.video.i_height;
        i_den = VOUT_ASPECT_FACTOR * p_enc->fmt_in.video.i_width;
        vlc_ureduce( &i_dst_num, &i_dst_den, i_num, i_den, 0 );

        p_sys->param.vui.i_sar_width = i_dst_num;
        p_sys->param.vui.i_sar_height = i_dst_den;
    }

    if( p_enc->fmt_in.video.i_frame_rate_base > 0 )
    {
        p_sys->param.i_fps_num = p_enc->fmt_in.video.i_frame_rate;
        p_sys->param.i_fps_den = p_enc->fmt_in.video.i_frame_rate_base;
    }

    /* x264 vbv-bufsize = 0 (default). if not provided set period
       in seconds for local maximum bitrate (cache/bufsize) based
       on average bitrate when use has told bitrate.
       vbv-buffer size is set to bitrate * secods between keyframes */
    if( !p_sys->param.rc.i_vbv_buffer_size &&
         p_sys->param.rc.i_rc_method == X264_RC_ABR &&
         p_sys->param.i_fps_num )
    {
        p_sys->param.rc.i_vbv_buffer_size = p_sys->param.rc.i_bitrate *
            p_sys->param.i_fps_den;
        p_sys->param.rc.i_vbv_buffer_size *= p_sys->param.i_keyint_max;
        p_sys->param.rc.i_vbv_buffer_size /= p_sys->param.i_fps_num;
    }

    /* Check if user has given some profile (baseline,main,high) to limit
     * settings, and apply those*/
    psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "profile" );
    if( psz_val )
    {
        if( !strcasecmp( psz_val, "baseline" ) )
        {
            msg_Dbg( p_enc, "Limiting to baseline profile");
            p_sys->param.analyse.b_transform_8x8 = 0;
            p_sys->param.b_cabac = 0;
            p_sys->param.i_bframe = 0;
        }
        else if (!strcasecmp( psz_val, "main" ) )
        {
            msg_Dbg( p_enc, "Limiting to main-profile");
            p_sys->param.analyse.b_transform_8x8 = 0;
        }
        /* high profile don't restrict stuff*/
    }
    free( psz_val );


    unsigned i_cpu = vlc_CPU();
    if( !(i_cpu & CPU_CAPABILITY_MMX) )
    {
        p_sys->param.cpu &= ~X264_CPU_MMX;
    }
    if( !(i_cpu & CPU_CAPABILITY_MMXEXT) )
    {
        p_sys->param.cpu &= ~X264_CPU_MMXEXT;
    }
    if( !(i_cpu & CPU_CAPABILITY_SSE) )
    {
        p_sys->param.cpu &= ~X264_CPU_SSE;
    }
    if( !(i_cpu & CPU_CAPABILITY_SSE2) )
    {
        p_sys->param.cpu &= ~X264_CPU_SSE2;
    }

    /* BUILD 29 adds support for multi-threaded encoding while BUILD 49 (r543)
       also adds support for threads = 0 for automatically selecting an optimal
       value (cores * 1.5) based on detected CPUs. Default behavior for x264 is
       threads = 1, however VLC usage differs and uses threads = 0 (auto) by
       default unless ofcourse transcode threads is explicitly specified.. */
    p_sys->param.i_threads = p_enc->i_threads;

    psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "stats" );
    if( psz_val )
    {
        p_sys->param.rc.psz_stat_in  =
        p_sys->param.rc.psz_stat_out =
        p_sys->psz_stat_name         = psz_val;
    }

    i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "pass" );
    if( i_val > 0 && i_val <= 3 )
    {
        p_sys->param.rc.b_stat_write = i_val & 1;
        p_sys->param.rc.b_stat_read = i_val & 2;
    }

    /* We need to initialize pthreadw32 before we open the encoder,
       but only once for the whole application. Since pthreadw32
       doesn't keep a refcount, do it ourselves. */
#ifdef PTW32_STATIC_LIB
    vlc_value_t lock, count;

    var_Create( p_enc->p_libvlc, "pthread_win32_mutex", VLC_VAR_MUTEX );
    var_Get( p_enc->p_libvlc, "pthread_win32_mutex", &lock );
    vlc_mutex_lock( lock.p_address );

    var_Create( p_enc->p_libvlc, "pthread_win32_count", VLC_VAR_INTEGER );
    var_Get( p_enc->p_libvlc, "pthread_win32_count", &count );

    if( count.i_int == 0 )
    {
        msg_Dbg( p_enc, "initializing pthread-win32" );
        if( !pthread_win32_process_attach_np() || !pthread_win32_thread_attach_np() )
        {
            msg_Warn( p_enc, "pthread Win32 Initialization failed" );
            vlc_mutex_unlock( lock.p_address );
            return VLC_EGENERIC;
        }
    }

    count.i_int++;
    var_Set( p_enc->p_libvlc, "pthread_win32_count", count );
    vlc_mutex_unlock( lock.p_address );

#endif

    /* Set lookahead value to lower than default,
     * as rtp-output without mux doesn't handle
     * difference that well yet*/
    p_sys->param.rc.i_lookahead=5;

    /* Open the encoder */
    p_sys->h = x264_encoder_open( &p_sys->param );

    if( p_sys->h == NULL )
    {
        msg_Err( p_enc, "cannot open x264 encoder" );
        Close( VLC_OBJECT(p_enc) );
        return VLC_EGENERIC;
    }

    /* alloc mem */
    p_sys->i_buffer = 4 * p_enc->fmt_in.video.i_width *
        p_enc->fmt_in.video.i_height + 1000;
    p_sys->p_buffer = malloc( p_sys->i_buffer );
    if( !p_sys->p_buffer )
    {
        Close( VLC_OBJECT(p_enc) );
        return VLC_ENOMEM;
    }

    /* get the globals headers */
    p_enc->fmt_out.i_extra = 0;
    p_enc->fmt_out.p_extra = NULL;

    p_enc->fmt_out.i_extra = x264_encoder_headers( p_sys->h, &nal, &i_nal );
    p_enc->fmt_out.p_extra = malloc( p_enc->fmt_out.i_extra );
    if( !p_enc->fmt_out.p_extra )
    {
        Close( VLC_OBJECT(p_enc) );
        return VLC_ENOMEM;
    }
    void *p_tmp = p_enc->fmt_out.p_extra;
    for( i = 0; i < i_nal; i++ )
    {
        memcpy( p_tmp, nal[i].p_payload, nal[i].i_payload );
        p_tmp += nal[i].i_payload;
    }

    return VLC_SUCCESS;
}
int
pthread_rwlock_init (pthread_rwlock_t * rwlock,
		     const pthread_rwlockattr_t * attr)
{
  int result;
  pthread_rwlock_t rwl = 0;

  if (rwlock == NULL)
    {
      return EINVAL;
    }

#ifdef PTW32_STATIC_LIB
  // This allos for C++ static initializers to function without crashes. (air)
  pthread_win32_process_attach_np();
#endif

  if (attr != NULL && *attr != NULL)
    {
      result = EINVAL;		/* Not supported */
      goto DONE;
    }

  rwl = (pthread_rwlock_t) calloc (1, sizeof (*rwl));

  if (rwl == NULL)
    {
      result = ENOMEM;
      goto DONE;
    }

  rwl->nSharedAccessCount = 0;
  rwl->nExclusiveAccessCount = 0;
  rwl->nCompletedSharedAccessCount = 0;

  result = pthread_mutex_init (&rwl->mtxExclusiveAccess, NULL);
  if (result != 0)
    {
      goto FAIL0;
    }

  result = pthread_mutex_init (&rwl->mtxSharedAccessCompleted, NULL);
  if (result != 0)
    {
      goto FAIL1;
    }

  result = pthread_cond_init (&rwl->cndSharedAccessCompleted, NULL);
  if (result != 0)
    {
      goto FAIL2;
    }

  rwl->nMagic = PTW32_RWLOCK_MAGIC;

  result = 0;
  goto DONE;

FAIL2:
  (void) pthread_mutex_destroy (&(rwl->mtxSharedAccessCompleted));

FAIL1:
  (void) pthread_mutex_destroy (&(rwl->mtxExclusiveAccess));

FAIL0:
  (void) free (rwl);
  rwl = NULL;

DONE:
  *rwlock = rwl;

  return result;
}
static void on_process_init(void)
{
    pthread_win32_process_attach_np ();
}
Exemple #4
0
static int on_process_init(void)
{
    pthread_win32_process_attach_np ();
    return 0;
}
Exemple #5
0
int main (int argc, char **argv) {
	int rv = 0;

	inst = & _plugin;

#ifdef __APPLE__
	rtk_osx_api_init();
#endif

#ifdef _WIN32
	pthread_win32_process_attach_np();
#endif
#if (defined _WIN32 && defined RTK_STATIC_INIT)
	glib_init_static();
	gobject_init_ctor();
#endif

	struct { int argc; char **argv; } rtkargv;
	rtkargv.argc = argc;
	rtkargv.argv = argv;

	const LV2_Feature external_lv_feature = { LV2_EXTERNAL_UI_URI, &extui_host};
	const LV2_Feature external_kx_feature = { LV2_EXTERNAL_UI_URI__KX__Host, &extui_host};
	const LV2_Feature robtk_argv = { "http://gareus.org/oss/lv2/robtk#argv", &rtkargv};

	// TODO add argv[] as feature
	const LV2_Feature* ui_features[] = {
		&external_lv_feature,
		&external_kx_feature,
		&robtk_argv,
		NULL
	};

	extui_host.plugin_human_id = inst->plugin_human_id;

	plugin_gui = inst->lv2ui_descriptor(inst->gui_descriptor_id);

	if (plugin_gui) {
	/* init plugin GUI */
	extui_host.ui_closed = on_external_ui_closed;
	gui_instance = plugin_gui->instantiate(plugin_gui,
			"URI TODO", NULL, NULL, NULL,
			(void **)&extui, ui_features);

	}

	if (!gui_instance || !extui) {
		fprintf(stderr, "Error: GUI was not initialized.\n");
		rv |= 2;
		goto out;
	}

#ifndef _WIN32
	signal (SIGHUP, catchsig);
	signal (SIGINT, catchsig);
#endif

	{

		LV2_EXTERNAL_UI_SHOW(extui);

#ifdef __APPLE__
		CFRunLoopRef runLoop = CFRunLoopGetCurrent();
		CFRunLoopTimerContext context = {0, NULL, NULL, NULL, NULL};
		CFRunLoopTimerRef timer = CFRunLoopTimerCreate(kCFAllocatorDefault, 0, 1.0/UI_UPDATE_FPS, 0, 0, &osx_loop, &context);
		CFRunLoopAddTimer(runLoop, timer, kCFRunLoopCommonModes);
		rtk_osx_api_run();
#else

		main_loop();
#endif

		LV2_EXTERNAL_UI_HIDE(extui);
	}

out:
	cleanup(0);
#ifdef _WIN32
	pthread_win32_process_detach_np();
#endif
#if (defined _WIN32 && defined RTK_STATIC_INIT)
	glib_cleanup_static();
#endif
	return(rv);
}
Exemple #6
0
int main(int argc, char **argv)
{
	int ds, dms, ret;
	double mb, rmb;
	struct timeval t1, t2;
#ifndef C_WINDOWS
	struct timezone tz;
	sigset_t sigset;
#endif
	struct optstruct *opts;
	const struct optstruct *opt;

#if defined(C_WINDOWS) && defined(CL_THREAD_SAFE)
    if(!pthread_win32_process_attach_np()) {
	mprintf("!Can't start the win32 pthreads layer\n");
	return 72;
    }
#endif

#if !defined(C_WINDOWS) && !defined(C_BEOS)
    sigemptyset(&sigset);
    sigaddset(&sigset, SIGXFSZ);
    sigprocmask(SIG_SETMASK, &sigset, NULL);
#endif


    if((opts = optparse(NULL, argc, argv, 1, OPT_CLAMSCAN, 0, NULL)) == NULL) {
	mprintf("!Can't parse command line options\n");
	return 40;
    }

    if(optget(opts, "verbose")->enabled) {
	mprintf_verbose = 1;
	logg_verbose = 1;
    }

    if(optget(opts, "quiet")->enabled)
	mprintf_quiet = 1;

    if(optget(opts, "stdout")->enabled)
	mprintf_stdout = 1;


    if(optget(opts, "debug")->enabled) {
#if defined(C_LINUX)
	    /* [email protected]: create a dump if needed */
	    struct rlimit rlim;

	rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
	if(setrlimit(RLIMIT_CORE, &rlim) < 0)
	    perror("setrlimit");
#endif
	cl_debug(); /* enable debug messages */
    }

    if(optget(opts, "version")->enabled) {
	print_version(optget(opts, "database")->strarg);
	optfree(opts);
	return 0;
    }

    if(optget(opts, "help")->enabled) {
	optfree(opts);
    	help();
	return 0;
    }

    if(optget(opts, "recursive")->enabled)
	recursion = 1;

    if(optget(opts, "infected")->enabled)
	printinfected = 1;

    if(optget(opts, "bell")->enabled)
	bell = 1;

    /* initialize logger */
    if((opt = optget(opts, "log"))->enabled) {
	logg_file = opt->strarg;
	if(logg("#\n-------------------------------------------------------------------------------\n\n")) {
	    mprintf("!Problem with internal logger.\n");
	    optfree(opts);
	    return 62;
	}
    } else 
	logg_file = NULL;

    if(actsetup(opts)) {
	optfree(opts);
	logg_close();
	exit(2);
    }

    memset(&info, 0, sizeof(struct s_info));

#ifdef C_WINDOWS
    _set_fmode(_O_BINARY);
#ifdef CL_DEBUG
    {
	_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
	_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
    }
#endif	
    gettimeofday(&t1, NULL);
#else
    gettimeofday(&t1, &tz);
#endif

    ret = scanmanager(opts);

    if(!optget(opts, "no-summary")->enabled) {
#ifdef C_WINDOWS
	gettimeofday(&t2, NULL);
#else
	gettimeofday(&t2, &tz);
#endif
	ds = t2.tv_sec - t1.tv_sec;
	dms = t2.tv_usec - t1.tv_usec;
	ds -= (dms < 0) ? (1):(0);
	dms += (dms < 0) ? (1000000):(0);
	logg("\n----------- SCAN SUMMARY -----------\n");
	logg("Known viruses: %u\n", info.sigs);
	logg("Engine version: %s\n", get_version());
	logg("Scanned directories: %u\n", info.dirs);
	logg("Scanned files: %u\n", info.files);
	logg("Infected files: %u\n", info.ifiles);
	if(notremoved) {
	    logg("Not removed: %u\n", notremoved);
	}
	if(notmoved) {
	    logg("Not %s: %u\n", optget(opts, "copy")->enabled ? "moved" : "copied", notmoved);
	}
	mb = info.blocks * (CL_COUNT_PRECISION / 1024) / 1024.0;
	logg("Data scanned: %2.2lf MB\n", mb);
	rmb = info.rblocks * (CL_COUNT_PRECISION / 1024) / 1024.0;
	logg("Data read: %2.2lf MB (ratio %.2f:1)\n", rmb, info.rblocks ? (double)info.blocks/(double)info.rblocks : 0);
	logg("Time: %u.%3.3u sec (%u m %u s)\n", ds, dms/1000, ds/60, ds%60);
    }

    optfree(opts);

#if defined(C_WINDOWS) && defined(CL_THREAD_SAFE)
    if(!pthread_win32_process_detach_np()) {
	logg("!Can't stop the win32 pthreads layer\n");
	return 72;
    }
#endif

    return ret;
}
/**
 * From the pthreads readme for mingw:
 * Define PTW32_STATIC_LIB when building your application. Also, your
 * application must call a two non-portable routines to initialise the
 * some state on startup and cleanup before exit. One other routine needs
 * to be called to cleanup after any Win32 threads have called POSIX API
 * routines. See README.NONPORTABLE or the html reference manual pages for
 * details on these routines:
 * 
 * BOOL pthread_win32_process_attach_np (void);
 * BOOL pthread_win32_process_detach_np (void);
 * BOOL pthread_win32_thread_attach_np (void); // Currently a no-op
 * BOOL pthread_win32_thread_detach_np (void);
 *
 */
void threadpool::win32_init()
{
    pthread_win32_process_attach_np();
    pthread_win32_thread_attach_np();
}
Exemple #8
0
int main(int argc, char* argv[]) 
{
    char *albumdir = 0, *musicfilename, *file_path = 0;
    int i, area_idx;
    sacd_reader_t *sacd_reader;

#ifdef PTW32_STATIC_LIB
    pthread_win32_process_attach_np();
    pthread_win32_thread_attach_np();
#endif

    init();
    if (parse_options(argc, argv)) 
    {
        setlocale(LC_ALL, "");
        if (fwide(stdout, 1) < 0)
        {
            fprintf(stderr, "ERROR: Output not set to wide.\n");
        }

        // default to 2 channel
        if (opts.two_channel == 0 && opts.multi_channel == 0) 
        {
            opts.two_channel = 1;
        }

        sacd_reader = sacd_open(opts.input_device);
        if (sacd_reader) 
        {

            handle = scarletbook_open(sacd_reader, 0);
            if (handle)
            {
                if (opts.print)
                {
                    scarletbook_print(handle);
                }

                if (opts.output_dsf || opts.output_iso || opts.output_dsdiff || opts.output_dsdiff_em || opts.export_cue_sheet)
                {
                    output = scarletbook_output_create(handle, handle_status_update_track_callback, handle_status_update_progress_callback, safe_fwprintf);

                    // select the channel area
                    area_idx = ((has_multi_channel(handle) && opts.multi_channel) || !has_two_channel(handle)) ? handle->mulch_area_idx : handle->twoch_area_idx;

                    albumdir = (strlen(opts.output_file) > 0 ? strdup(opts.output_file) : get_album_dir(handle));

                    if (opts.output_iso)
                    {
                        uint32_t total_sectors = sacd_get_total_sectors(sacd_reader);
#ifdef SECTOR_LIMIT
#define FAT32_SECTOR_LIMIT 2090000
                        uint32_t sector_size = FAT32_SECTOR_LIMIT;
                        uint32_t sector_offset = 0;
                        if (total_sectors > FAT32_SECTOR_LIMIT)
                        {
                            musicfilename = (char *) malloc(512);
                            file_path = make_filename(0, 0, albumdir, "iso");
                            for (i = 1; total_sectors != 0; i++)
                            {
                                sector_size = min(total_sectors, FAT32_SECTOR_LIMIT);
                                snprintf(musicfilename, 512, "%s.%03d", file_path, i);
                                scarletbook_output_enqueue_raw_sectors(output, sector_offset, sector_size, musicfilename, "iso");
                                sector_offset += sector_size;
                                total_sectors -= sector_size;
                            }
                            free(musicfilename);
                        }
                        else
#endif
                        {
                            get_unique_filename(&albumdir, "iso");
                            file_path = make_filename(0, 0, albumdir, "iso");
                            scarletbook_output_enqueue_raw_sectors(output, 0, total_sectors, file_path, "iso");
                        }
                    }
                    else if (opts.output_dsdiff_em)
                    {
                        get_unique_filename(&albumdir, "dff");
                        file_path = make_filename(0, 0, albumdir, "dff");

                        scarletbook_output_enqueue_track(output, area_idx, 0, file_path, "dsdiff_edit_master", 
                            (opts.convert_dst ? 1 : handle->area[area_idx].area_toc->frame_format != FRAME_FORMAT_DST));
                    }
                    else if (opts.output_dsf || opts.output_dsdiff)
                    {
                        // create the output folder
                        get_unique_dir(0, &albumdir);
                        recursive_mkdir(albumdir, 0774);

                        // fill the queue with items to rip
                        for (i = 0; i < handle->area[area_idx].area_toc->track_count; i++) 
                        {
                            if (opts.select_tracks && opts.selected_tracks[i] == 0)
                                continue;

                            musicfilename = get_music_filename(handle, area_idx, i, opts.output_file);

                            if (opts.output_dsf)
                            {
                                file_path = make_filename(0, albumdir, musicfilename, "dsf");
                                scarletbook_output_enqueue_track(output, area_idx, i, file_path, "dsf", 
                                    1 /* always decode to DSD */);
                            }
                            else if (opts.output_dsdiff)
                            {
                                file_path = make_filename(0, albumdir, musicfilename, "dff");
                                scarletbook_output_enqueue_track(output, area_idx, i, file_path, "dsdiff", 
                                    (opts.convert_dst ? 1 : handle->area[area_idx].area_toc->frame_format != FRAME_FORMAT_DST));
                            }

                            free(musicfilename);
                            free(file_path);
                            file_path = 0;
                        }
                    }

                    if (opts.export_cue_sheet)
                    {
                        char *cue_file_path = make_filename(0, 0, albumdir, "cue");
#ifdef _WIN32
                        wchar_t *wide_filename = (wchar_t *) charset_convert(cue_file_path, strlen(cue_file_path), "UTF-8", sizeof(wchar_t) == 2 ? "UCS-2-INTERNAL" : "UCS-4-INTERNAL");
#else
                        wchar_t *wide_filename = (wchar_t *) charset_convert(cue_file_path, strlen(cue_file_path), "UTF-8", "WCHAR_T");
#endif
                        fwprintf(stdout, L"Exporting CUE sheet [%ls]\n", wide_filename);
                        if (!file_path)
                            file_path = make_filename(0, 0, albumdir, "dff");
                        write_cue_sheet(handle, file_path, area_idx, cue_file_path);
                        free(cue_file_path);
                        free(wide_filename);
                    }

                    free(file_path);

                    started_processing = time(0);
                    scarletbook_output_start(output);
                    scarletbook_output_destroy(output);

                    fprintf(stdout, "\rWe are done..                                                          \n");
                }
                scarletbook_close(handle);

                free(albumdir);
            }
        }

        sacd_close(sacd_reader);

#ifndef _WIN32
        freopen(0, "w", stdout);
#endif
        if (fwide(stdout, -1) >= 0)
        {
            fprintf(stderr, "ERROR: Output not set to byte oriented.\n");
        }
    }

    free_lock(g_fwprintf_lock);
    destroy_logging();

#ifdef PTW32_STATIC_LIB
    pthread_win32_process_detach_np();
    pthread_win32_thread_detach_np();
#endif

    printf("\n");
    return 0;
}
/****************************************************************************
 * Function: ThreadPoolInit
 *
 *  Description:
 *      Initializes and starts ThreadPool. Must be called first.
 *      And only once for ThreadPool.
 *  Parameters:
 *      tp  - must be valid, non null, pointer to ThreadPool.
 *      minWorkerThreads - minimum number of worker threads
 *                         thread pool will never have less than this
 *                         number of threads.
 *      maxWorkerThreads - maximum number of worker threads
 *                         thread pool will never have more than this
 *                         number of threads.
 *      maxIdleTime      - maximum time that a worker thread will spend
 *                         idle. If a worker is idle longer than this
 *                         time and there are more than the min
 *                         number of workers running, than the
 *                         worker thread exits.
 *      jobsPerThread    - ratio of jobs to thread to try and maintain
 *                         if a job is scheduled and the number of jobs per
 *                         thread is greater than this number,and
 *                         if less than the maximum number of
 *                         workers are running then a new thread is
 *                         started to help out with efficiency.
 *      schedPolicy      - scheduling policy to try and set (OS dependent)
 *  Returns:
 *      0 on success, nonzero on failure.
 *      EAGAIN if not enough system resources to create minimum threads.
 *      INVALID_POLICY if schedPolicy can't be set
 *      EMAXTHREADS if minimum threads is greater than maximum threads
 *****************************************************************************/
int ThreadPoolInit( ThreadPool *tp, ThreadPoolAttr *attr )
{
	int retCode = 0;
	int i = 0;
	//printf("%s, %d\n", __FUNCTION__, __LINE__);

	assert( tp != NULL );
	if( tp == NULL ) {
		return EINVAL;
	}
#ifdef WIN32
#ifdef PTW32_STATIC_LIB
	pthread_win32_process_attach_np();
#endif
#endif
	//printf("%s, %d\n", __FUNCTION__, __LINE__);

	retCode += ithread_mutex_init( &tp->mutex, NULL );
	assert( retCode == 0 );

	retCode += ithread_mutex_lock( &tp->mutex );
	assert( retCode == 0 );

	retCode += ithread_cond_init( &tp->condition, NULL );
	assert( retCode == 0 );

	retCode += ithread_cond_init( &tp->start_and_shutdown, NULL );
	assert( retCode == 0 );
	//printf("%s, %d\n", __FUNCTION__, __LINE__);

	if( retCode != 0 ) {
		return EAGAIN;
	}

	if( attr ) {
		tp->attr = ( *attr );
	} else {
		TPAttrInit( &tp->attr );
	}
	//printf("%s, %d, minthreads: %d\n", __FUNCTION__, __LINE__, tp->attr.minThreads);

	if( SetPolicyType( tp->attr.schedPolicy ) != 0 ) {
		ithread_mutex_unlock( &tp->mutex );
		ithread_mutex_destroy( &tp->mutex );
		ithread_cond_destroy( &tp->condition );
		ithread_cond_destroy( &tp->start_and_shutdown );
		return INVALID_POLICY;
	}
	//printf("%s, %d\n", __FUNCTION__, __LINE__);

	retCode += FreeListInit(
		&tp->jobFreeList, sizeof( ThreadPoolJob ), JOBFREELISTSIZE );
	assert( retCode == 0 );

	StatsInit( &tp->stats );

	retCode += ListInit( &tp->highJobQ, CmpThreadPoolJob, NULL );
	assert( retCode == 0 );

	retCode += ListInit( &tp->medJobQ, CmpThreadPoolJob, NULL );
	assert( retCode == 0 );

	retCode += ListInit( &tp->lowJobQ, CmpThreadPoolJob, NULL );
	assert( retCode == 0 );
	//printf("%s, %d, retcode is %d\n", __FUNCTION__, __LINE__, retCode);

	if( retCode != 0 ) {
		retCode = EAGAIN;
		//printf("%s, %d\n", __FUNCTION__, __LINE__);
	} else {
	//printf("%s, %d\n", __FUNCTION__, __LINE__);
		tp->persistentJob = NULL;
		tp->lastJobId = 0;
		tp->shutdown = 0;
		tp->totalThreads = 0;
		tp->persistentThreads = 0;
		//printf("%s, %d\n", __FUNCTION__, __LINE__);
		for( i = 0; i < tp->attr.minThreads; ++i ) {
			if( ( retCode = CreateWorker( tp ) ) != 0 ) {
				//printf("%s, %d\n", __FUNCTION__, __LINE__);

				break;
			}
		}
	}
	//printf("%s, %d\n", __FUNCTION__, __LINE__);

	ithread_mutex_unlock( &tp->mutex );

	if( retCode != 0 ) {
		// clean up if the min threads could not be created
		ThreadPoolShutdown( tp );
	}
	//printf("%s, %d\n", __FUNCTION__, __LINE__);

	return retCode;
}
Exemple #10
0
void avcodec_register_all(void)
{
    static int initialized;

    if (initialized)
        return;
    initialized = 1;

    /* hardware accelerators */
    REGISTER_HWACCEL (H263_VAAPI, h263_vaapi);
    REGISTER_HWACCEL (H264_DXVA2, h264_dxva2);
    REGISTER_HWACCEL (H264_VAAPI, h264_vaapi);
    REGISTER_HWACCEL (MPEG1_VDPAU, mpeg1_vdpau);
    REGISTER_HWACCEL (MPEG2_DXVA2, mpeg2_dxva2);
    REGISTER_HWACCEL (MPEG2_VAAPI, mpeg2_vaapi);
    REGISTER_HWACCEL (MPEG2_VDPAU, mpeg2_vdpau);
    REGISTER_HWACCEL (MPEG4_VAAPI, mpeg4_vaapi);
    REGISTER_HWACCEL (VC1_DXVA2, vc1_dxva2);
    REGISTER_HWACCEL (VC1_VAAPI, vc1_vaapi);
    REGISTER_HWACCEL (WMV3_DXVA2, wmv3_dxva2);
    REGISTER_HWACCEL (WMV3_VAAPI, wmv3_vaapi);

#ifdef PTW32_STATIC_LIB
    pthread_win32_process_attach_np();
    pthread_win32_thread_attach_np();
    atexit(detach_ptw32);
#endif

#ifdef PTW32_STATIC_LIB
    pthread_win32_process_attach_np();
    pthread_win32_thread_attach_np();
    atexit(detach_ptw32);
#endif

    /* video codecs */
    REGISTER_ENCODER (A64MULTI, a64multi);
    REGISTER_ENCODER (A64MULTI5, a64multi5);
    REGISTER_DECODER (AASC, aasc);
    REGISTER_DECODER (AMV, amv);
    REGISTER_DECODER (ANM, anm);
    REGISTER_DECODER (ANSI, ansi);
    REGISTER_ENCDEC  (ASV1, asv1);
    REGISTER_ENCDEC  (ASV2, asv2);
    REGISTER_DECODER (AURA, aura);
    REGISTER_DECODER (AURA2, aura2);
    REGISTER_DECODER (AVS, avs);
    REGISTER_DECODER (BETHSOFTVID, bethsoftvid);
    REGISTER_DECODER (BFI, bfi);
    REGISTER_DECODER (BINK, bink);
    REGISTER_ENCDEC  (BMP, bmp);
    REGISTER_DECODER (C93, c93);
    REGISTER_DECODER (CAVS, cavs);
    REGISTER_DECODER (CDGRAPHICS, cdgraphics);
    REGISTER_DECODER (CINEPAK, cinepak);
    REGISTER_DECODER (CLJR, cljr);
    REGISTER_DECODER (CSCD, cscd);
    REGISTER_DECODER (CYUV, cyuv);
    REGISTER_DECODER (DFA, dfa);
    REGISTER_ENCDEC  (DNXHD, dnxhd);
    REGISTER_ENCDEC  (DPX, dpx);
    REGISTER_DECODER (DSICINVIDEO, dsicinvideo);
    REGISTER_ENCDEC  (DVVIDEO, dvvideo);
    REGISTER_DECODER (DXA, dxa);
    REGISTER_DECODER (EACMV, eacmv);
    REGISTER_DECODER (EAMAD, eamad);
    REGISTER_DECODER (EATGQ, eatgq);
    REGISTER_DECODER (EATGV, eatgv);
    REGISTER_DECODER (EATQI, eatqi);
    REGISTER_DECODER (EIGHTBPS, eightbps);
    REGISTER_DECODER (EIGHTSVX_EXP, eightsvx_exp);
    REGISTER_DECODER (EIGHTSVX_FIB, eightsvx_fib);
    REGISTER_DECODER (ESCAPE124, escape124);
    REGISTER_ENCDEC  (FFV1, ffv1);
    REGISTER_ENCDEC  (FFVHUFF, ffvhuff);
    REGISTER_ENCDEC  (FLASHSV, flashsv);
    REGISTER_DECODER (FLIC, flic);
    REGISTER_ENCDEC  (FLV, flv);
    REGISTER_DECODER (FOURXM, fourxm);
    REGISTER_DECODER (FRAPS, fraps);
    REGISTER_DECODER (FRWU, frwu);
    REGISTER_ENCDEC  (GIF, gif);
    REGISTER_ENCDEC  (H261, h261);
    REGISTER_ENCDEC  (H263, h263);
    REGISTER_DECODER (H263I, h263i);
    REGISTER_ENCODER (H263P, h263p);
    REGISTER_DECODER (H264, h264);
    REGISTER_DECODER (H264_CRYSTALHD, h264_crystalhd);
    REGISTER_DECODER (H264_VDPAU, h264_vdpau);
    REGISTER_ENCDEC  (HUFFYUV, huffyuv);
    REGISTER_DECODER (IDCIN, idcin);
    REGISTER_DECODER (IFF_BYTERUN1, iff_byterun1);
    REGISTER_DECODER (IFF_ILBM, iff_ilbm);
    REGISTER_DECODER (INDEO2, indeo2);
    REGISTER_DECODER (INDEO3, indeo3);
    REGISTER_DECODER (INDEO5, indeo5);
    REGISTER_DECODER (INTERPLAY_VIDEO, interplay_video);
    REGISTER_ENCDEC  (JPEGLS, jpegls);
    REGISTER_DECODER (JV, jv);
    REGISTER_DECODER (KGV1, kgv1);
    REGISTER_DECODER (KMVC, kmvc);
    REGISTER_DECODER (LAGARITH, lagarith);
    REGISTER_ENCODER (LJPEG, ljpeg);
    REGISTER_DECODER (LOCO, loco);
    REGISTER_DECODER (MDEC, mdec);
    REGISTER_DECODER (MIMIC, mimic);
    REGISTER_ENCDEC  (MJPEG, mjpeg);
    REGISTER_DECODER (MJPEGB, mjpegb);
    REGISTER_DECODER (MMVIDEO, mmvideo);
    REGISTER_DECODER (MOTIONPIXELS, motionpixels);
    REGISTER_DECODER (MPEG_XVMC, mpeg_xvmc);
    REGISTER_ENCDEC  (MPEG1VIDEO, mpeg1video);
    REGISTER_ENCDEC  (MPEG2VIDEO, mpeg2video);
    REGISTER_ENCDEC  (MPEG4, mpeg4);
    REGISTER_DECODER (MPEG4_CRYSTALHD, mpeg4_crystalhd);
    REGISTER_DECODER (MPEG4_VDPAU, mpeg4_vdpau);
    REGISTER_DECODER (MPEGVIDEO, mpegvideo);
    REGISTER_DECODER (MPEG_VDPAU, mpeg_vdpau);
    REGISTER_DECODER (MPEG1_VDPAU, mpeg1_vdpau);
    REGISTER_DECODER (MPEG2_CRYSTALHD, mpeg2_crystalhd);
    REGISTER_DECODER (MSMPEG4_CRYSTALHD, msmpeg4_crystalhd);
    REGISTER_ENCDEC  (MSMPEG4V1, msmpeg4v1);
    REGISTER_ENCDEC  (MSMPEG4V2, msmpeg4v2);
    REGISTER_ENCDEC  (MSMPEG4V3, msmpeg4v3);
    REGISTER_DECODER (MSRLE, msrle);
    REGISTER_DECODER (MSVIDEO1, msvideo1);
    REGISTER_DECODER (MSZH, mszh);
    REGISTER_DECODER (NUV, nuv);
    REGISTER_ENCDEC  (PAM, pam);
    REGISTER_ENCDEC  (PBM, pbm);
    REGISTER_ENCDEC  (PCX, pcx);
    REGISTER_ENCDEC  (PGM, pgm);
    REGISTER_ENCDEC  (PGMYUV, pgmyuv);
    REGISTER_DECODER (PICTOR, pictor);
    REGISTER_ENCDEC  (PNG, png);
    REGISTER_ENCDEC  (PPM, ppm);
    REGISTER_DECODER (PTX, ptx);
    REGISTER_DECODER (QDRAW, qdraw);
    REGISTER_DECODER (QPEG, qpeg);
    REGISTER_ENCDEC  (QTRLE, qtrle);
    REGISTER_DECODER (R10K,  r10k);
    REGISTER_DECODER (R210,  r210);
    REGISTER_ENCDEC  (RAWVIDEO, rawvideo);
    REGISTER_DECODER (RL2, rl2);
    REGISTER_ENCDEC  (ROQ, roq);
    REGISTER_DECODER (RPZA, rpza);
    REGISTER_ENCDEC  (RV10, rv10);
    REGISTER_ENCDEC  (RV20, rv20);
    REGISTER_DECODER (RV30, rv30);
    REGISTER_DECODER (RV40, rv40);
    REGISTER_ENCDEC  (SGI, sgi);
    REGISTER_DECODER (SMACKER, smacker);
    REGISTER_DECODER (SMC, smc);
    REGISTER_ENCDEC  (SNOW, snow);
    REGISTER_DECODER (SP5X, sp5x);
    REGISTER_DECODER (SUNRAST, sunrast);
    REGISTER_ENCDEC  (SVQ1, svq1);
    REGISTER_DECODER (SVQ3, svq3);
    REGISTER_ENCDEC  (TARGA, targa);
    REGISTER_DECODER (THEORA, theora);
    REGISTER_DECODER (THP, thp);
    REGISTER_DECODER (TIERTEXSEQVIDEO, tiertexseqvideo);
    REGISTER_ENCDEC  (TIFF, tiff);
    REGISTER_DECODER (TMV, tmv);
    REGISTER_DECODER (TRUEMOTION1, truemotion1);
    REGISTER_DECODER (TRUEMOTION2, truemotion2);
    REGISTER_DECODER (TSCC, tscc);
    REGISTER_DECODER (TXD, txd);
    REGISTER_DECODER (ULTI, ulti);
    REGISTER_ENCDEC  (V210,  v210);
    REGISTER_DECODER (V210X, v210x);
    REGISTER_DECODER (VB, vb);
    REGISTER_DECODER (VC1, vc1);
    REGISTER_DECODER (VC1_CRYSTALHD, vc1_crystalhd);
    REGISTER_DECODER (VC1_VDPAU, vc1_vdpau);
    REGISTER_DECODER (VCR1, vcr1);
    REGISTER_DECODER (VMDVIDEO, vmdvideo);
    REGISTER_DECODER (VMNC, vmnc);
    REGISTER_DECODER (VP3, vp3);
    REGISTER_DECODER (VP5, vp5);
    REGISTER_DECODER (VP6, vp6);
    REGISTER_DECODER (VP6A, vp6a);
    REGISTER_DECODER (VP6F, vp6f);
    REGISTER_DECODER (VP8, vp8);
    REGISTER_DECODER (VQA, vqa);
    REGISTER_ENCDEC  (WMV1, wmv1);
    REGISTER_ENCDEC  (WMV2, wmv2);
    REGISTER_DECODER (WMV3, wmv3);
    REGISTER_DECODER (WMV3_CRYSTALHD, wmv3_crystalhd);
    REGISTER_DECODER (WMV3_VDPAU, wmv3_vdpau);
    REGISTER_DECODER (WNV1, wnv1);
    REGISTER_DECODER (XAN_WC3, xan_wc3);
    REGISTER_DECODER (XAN_WC4, xan_wc4);
    REGISTER_DECODER (XL, xl);
    REGISTER_DECODER (YOP, yop);
    REGISTER_ENCDEC  (ZLIB, zlib);
    REGISTER_ENCDEC  (ZMBV, zmbv);

    /* audio codecs */
    REGISTER_ENCDEC  (AAC, aac);
    REGISTER_DECODER (AAC_LATM, aac_latm);
    REGISTER_ENCDEC  (AC3, ac3);
    REGISTER_ENCODER (AC3_FIXED, ac3_fixed); //deprecated, just for libav compatibility
//    REGISTER_ENCODER (AC3_FLOAT, ac3_float); dont remove dont outcomment, for configure
    REGISTER_ENCDEC  (ALAC, alac);
    REGISTER_DECODER (ALS, als);
    REGISTER_DECODER (AMRNB, amrnb);
    REGISTER_DECODER (AMRWB, amrwb);
    REGISTER_DECODER (APE, ape);
    REGISTER_DECODER (ATRAC1, atrac1);
    REGISTER_DECODER (ATRAC3, atrac3);
    REGISTER_DECODER (BINKAUDIO_DCT, binkaudio_dct);
    REGISTER_DECODER (BINKAUDIO_RDFT, binkaudio_rdft);
    REGISTER_DECODER (COOK, cook);
    REGISTER_DECODER (DCA, dca);
    REGISTER_DECODER (DSICINAUDIO, dsicinaudio);
    REGISTER_DECODER (EAC3, eac3);
    REGISTER_ENCDEC  (FLAC, flac);
    REGISTER_DECODER (GSM, gsm);
    REGISTER_DECODER (GSM_MS, gsm_ms);
    REGISTER_DECODER (IMC, imc);
    REGISTER_DECODER (MACE3, mace3);
    REGISTER_DECODER (MACE6, mace6);
    REGISTER_DECODER (MLP, mlp);
    REGISTER_DECODER (MP1, mp1);
    REGISTER_DECODER (MP1FLOAT, mp1float);
    REGISTER_ENCDEC  (MP2, mp2);
    REGISTER_DECODER (MP2FLOAT, mp2float);
    REGISTER_DECODER (MP3, mp3);
    REGISTER_DECODER (MP3FLOAT, mp3float);
    REGISTER_DECODER (MP3ADU, mp3adu);
    REGISTER_DECODER (MP3ADUFLOAT, mp3adufloat);
    REGISTER_DECODER (MP3ON4, mp3on4);
    REGISTER_DECODER (MP3ON4FLOAT, mp3on4float);
    REGISTER_DECODER (MPC7, mpc7);
    REGISTER_DECODER (MPC8, mpc8);
    REGISTER_ENCDEC  (NELLYMOSER, nellymoser);
    REGISTER_DECODER (QCELP, qcelp);
    REGISTER_DECODER (QDM2, qdm2);
    REGISTER_ENCDEC  (RA_144, ra_144);
    REGISTER_DECODER (RA_288, ra_288);
    REGISTER_DECODER (SHORTEN, shorten);
    REGISTER_DECODER (SIPR, sipr);
    REGISTER_DECODER (SMACKAUD, smackaud);
    REGISTER_ENCDEC  (SONIC, sonic);
    REGISTER_ENCODER (SONIC_LS, sonic_ls);
    REGISTER_DECODER (TRUEHD, truehd);
    REGISTER_DECODER (TRUESPEECH, truespeech);
    REGISTER_DECODER (TTA, tta);
    REGISTER_DECODER (TWINVQ, twinvq);
    REGISTER_DECODER (VMDAUDIO, vmdaudio);
    REGISTER_ENCDEC  (VORBIS, vorbis);
    REGISTER_DECODER (WAVPACK, wavpack);
    REGISTER_DECODER (WMAPRO, wmapro);
    REGISTER_ENCDEC  (WMAV1, wmav1);
    REGISTER_ENCDEC  (WMAV2, wmav2);
    REGISTER_DECODER (WMAVOICE, wmavoice);
    REGISTER_DECODER (WS_SND1, ws_snd1);

    /* PCM codecs */
    REGISTER_ENCDEC  (PCM_ALAW, pcm_alaw);
    REGISTER_DECODER (PCM_BLURAY, pcm_bluray);
    REGISTER_DECODER (PCM_DVD, pcm_dvd);
    REGISTER_ENCDEC  (PCM_F32BE, pcm_f32be);
    REGISTER_ENCDEC  (PCM_F32LE, pcm_f32le);
    REGISTER_ENCDEC  (PCM_F64BE, pcm_f64be);
    REGISTER_ENCDEC  (PCM_F64LE, pcm_f64le);
    REGISTER_DECODER (PCM_LXF, pcm_lxf);
    REGISTER_ENCDEC  (PCM_MULAW, pcm_mulaw);
    REGISTER_ENCDEC  (PCM_S8, pcm_s8);
    REGISTER_ENCDEC  (PCM_S16BE, pcm_s16be);
    REGISTER_ENCDEC  (PCM_S16LE, pcm_s16le);
    REGISTER_DECODER (PCM_S16LE_PLANAR, pcm_s16le_planar);
    REGISTER_ENCDEC  (PCM_S24BE, pcm_s24be);
    REGISTER_ENCDEC  (PCM_S24DAUD, pcm_s24daud);
    REGISTER_ENCDEC  (PCM_S24LE, pcm_s24le);
    REGISTER_ENCDEC  (PCM_S32BE, pcm_s32be);
    REGISTER_ENCDEC  (PCM_S32LE, pcm_s32le);
    REGISTER_ENCDEC  (PCM_U8, pcm_u8);
    REGISTER_ENCDEC  (PCM_U16BE, pcm_u16be);
    REGISTER_ENCDEC  (PCM_U16LE, pcm_u16le);
    REGISTER_ENCDEC  (PCM_U24BE, pcm_u24be);
    REGISTER_ENCDEC  (PCM_U24LE, pcm_u24le);
    REGISTER_ENCDEC  (PCM_U32BE, pcm_u32be);
    REGISTER_ENCDEC  (PCM_U32LE, pcm_u32le);
    REGISTER_ENCDEC  (PCM_ZORK , pcm_zork);

    /* DPCM codecs */
    REGISTER_DECODER (INTERPLAY_DPCM, interplay_dpcm);
    REGISTER_ENCDEC  (ROQ_DPCM, roq_dpcm);
    REGISTER_DECODER (SOL_DPCM, sol_dpcm);
    REGISTER_DECODER (XAN_DPCM, xan_dpcm);

    /* ADPCM codecs */
    REGISTER_DECODER (ADPCM_4XM, adpcm_4xm);
    REGISTER_ENCDEC  (ADPCM_ADX, adpcm_adx);
    REGISTER_DECODER (ADPCM_CT, adpcm_ct);
    REGISTER_DECODER (ADPCM_EA, adpcm_ea);
    REGISTER_DECODER (ADPCM_EA_MAXIS_XA, adpcm_ea_maxis_xa);
    REGISTER_DECODER (ADPCM_EA_R1, adpcm_ea_r1);
    REGISTER_DECODER (ADPCM_EA_R2, adpcm_ea_r2);
    REGISTER_DECODER (ADPCM_EA_R3, adpcm_ea_r3);
    REGISTER_DECODER (ADPCM_EA_XAS, adpcm_ea_xas);
    REGISTER_ENCDEC  (ADPCM_G722, adpcm_g722);
    REGISTER_ENCDEC  (ADPCM_G726, adpcm_g726);
    REGISTER_DECODER (ADPCM_IMA_AMV, adpcm_ima_amv);
    REGISTER_DECODER (ADPCM_IMA_DK3, adpcm_ima_dk3);
    REGISTER_DECODER (ADPCM_IMA_DK4, adpcm_ima_dk4);
    REGISTER_DECODER (ADPCM_IMA_EA_EACS, adpcm_ima_ea_eacs);
    REGISTER_DECODER (ADPCM_IMA_EA_SEAD, adpcm_ima_ea_sead);
    REGISTER_DECODER (ADPCM_IMA_ISS, adpcm_ima_iss);
    REGISTER_ENCDEC  (ADPCM_IMA_QT, adpcm_ima_qt);
    REGISTER_DECODER (ADPCM_IMA_SMJPEG, adpcm_ima_smjpeg);
    REGISTER_ENCDEC  (ADPCM_IMA_WAV, adpcm_ima_wav);
    REGISTER_DECODER (ADPCM_IMA_WS, adpcm_ima_ws);
    REGISTER_ENCDEC  (ADPCM_MS, adpcm_ms);
    REGISTER_DECODER (ADPCM_SBPRO_2, adpcm_sbpro_2);
    REGISTER_DECODER (ADPCM_SBPRO_3, adpcm_sbpro_3);
    REGISTER_DECODER (ADPCM_SBPRO_4, adpcm_sbpro_4);
    REGISTER_ENCDEC  (ADPCM_SWF, adpcm_swf);
    REGISTER_DECODER (ADPCM_THP, adpcm_thp);
    REGISTER_DECODER (ADPCM_XA, adpcm_xa);
    REGISTER_ENCDEC  (ADPCM_YAMAHA, adpcm_yamaha);

    /* subtitles */
    REGISTER_ENCDEC  (ASS, ass);
    REGISTER_ENCDEC  (DVBSUB, dvbsub);
    REGISTER_ENCDEC  (DVDSUB, dvdsub);
    REGISTER_DECODER (PGSSUB, pgssub);
    REGISTER_ENCDEC  (SRT, srt);
    REGISTER_ENCDEC  (XSUB, xsub);

    /* external libraries */
    REGISTER_DECODER (LIBCELT, libcelt);
    REGISTER_ENCDEC  (LIBDIRAC, libdirac);
    REGISTER_ENCODER (LIBFAAC, libfaac);
    REGISTER_ENCDEC  (LIBGSM, libgsm);
    REGISTER_ENCDEC  (LIBGSM_MS, libgsm_ms);
    REGISTER_ENCODER (LIBMP3LAME, libmp3lame);
    REGISTER_ENCDEC  (LIBOPENCORE_AMRNB, libopencore_amrnb);
    REGISTER_DECODER (LIBOPENCORE_AMRWB, libopencore_amrwb);
    REGISTER_DECODER (LIBOPENJPEG, libopenjpeg);
    REGISTER_ENCDEC  (LIBSCHROEDINGER, libschroedinger);
    REGISTER_DECODER (LIBSPEEX, libspeex);
    REGISTER_ENCODER (LIBTHEORA, libtheora);
    REGISTER_ENCODER (LIBVO_AACENC, libvo_aacenc);
    REGISTER_ENCODER (LIBVO_AMRWBENC, libvo_amrwbenc);
    REGISTER_ENCODER (LIBVORBIS, libvorbis);
    REGISTER_ENCDEC  (LIBVPX, libvpx);
    REGISTER_ENCODER (LIBX264, libx264);
    REGISTER_ENCODER (LIBXAVS, libxavs);
    REGISTER_ENCODER (LIBXVID, libxvid);

    /* parsers */
    REGISTER_PARSER  (AAC, aac);
    REGISTER_PARSER  (AAC_LATM, aac_latm);
    REGISTER_PARSER  (AC3, ac3);
    REGISTER_PARSER  (CAVSVIDEO, cavsvideo);
    REGISTER_PARSER  (DCA, dca);
    REGISTER_PARSER  (DIRAC, dirac);
    REGISTER_PARSER  (DNXHD, dnxhd);
    REGISTER_PARSER  (DVBSUB, dvbsub);
    REGISTER_PARSER  (DVDSUB, dvdsub);
    REGISTER_PARSER  (FLAC, flac);
    REGISTER_PARSER  (H261, h261);
    REGISTER_PARSER  (H263, h263);
    REGISTER_PARSER  (H264, h264);
    REGISTER_PARSER  (MJPEG, mjpeg);
    REGISTER_PARSER  (MLP, mlp);
    REGISTER_PARSER  (MPEG4VIDEO, mpeg4video);
    REGISTER_PARSER  (MPEGAUDIO, mpegaudio);
    REGISTER_PARSER  (MPEGVIDEO, mpegvideo);
    REGISTER_PARSER  (PNM, pnm);
    REGISTER_PARSER  (VC1, vc1);
    REGISTER_PARSER  (VP3, vp3);
    REGISTER_PARSER  (VP8, vp8);

    /* bitstream filters */
    REGISTER_BSF     (AAC_ADTSTOASC, aac_adtstoasc);
    REGISTER_BSF     (CHOMP, chomp);
    REGISTER_BSF     (DUMP_EXTRADATA, dump_extradata);
    REGISTER_BSF     (H264_MP4TOANNEXB, h264_mp4toannexb);
    REGISTER_BSF     (IMX_DUMP_HEADER, imx_dump_header);
    REGISTER_BSF     (MJPEG2JPEG, mjpeg2jpeg);
    REGISTER_BSF     (MJPEGA_DUMP_HEADER, mjpega_dump_header);
    REGISTER_BSF     (MP3_HEADER_COMPRESS, mp3_header_compress);
    REGISTER_BSF     (MP3_HEADER_DECOMPRESS, mp3_header_decompress);
    REGISTER_BSF     (MOV2TEXTSUB, mov2textsub);
    REGISTER_BSF     (NOISE, noise);
    REGISTER_BSF     (REMOVE_EXTRADATA, remove_extradata);
    REGISTER_BSF     (TEXT2MOVSUB, text2movsub);
}
int main(int argc, char **argv)
{
	int ret;

	atexit(&exit_handler);

	TEST_WRAPPER(test_sequence2);

	pthread_win32_process_detach_np(); // ptw32_processTerminate();
	pthread_win32_process_attach_np(); // ptw32_processInitialize();
	/*
	  fails when run down below; does not fail when run at start of run - turns out to be
	  due to the thread reuse logic kicking in and the test code not anticipating that
	  -->
	  introduction of test sequence2.c above to showcase the fix for this, including
	  augmentation of pthread_win32_process_attach_np() to prevent crashes.
	*/
	TEST_WRAPPER(test_reuse1);

    pthread_win32_process_detach_np(); // ptw32_processTerminate();
	pthread_win32_process_attach_np(); // ptw32_processInitialize();
	TEST_WRAPPER(test_sequence1); /* fails when run down below; does not fail when run at start of run - same issue as test reuse1 */

    pthread_win32_process_detach_np(); // ptw32_processTerminate();
	pthread_win32_process_attach_np(); // ptw32_processInitialize();
	TEST_WRAPPER(test_cancel7);
	TEST_WRAPPER(test_cancel8);
	TEST_WRAPPER(test_cleanup1);
	TEST_WRAPPER(test_condvar7);
	TEST_WRAPPER(test_condvar9);
	TEST_WRAPPER(test_exception1);
	TEST_WRAPPER(test_loadfree);
	TEST_WRAPPER(test_sequence1);

	TEST_WRAPPER(test_barrier1);
	TEST_WRAPPER(test_barrier2);
	TEST_WRAPPER(test_barrier3);
	TEST_WRAPPER(test_barrier4);
	TEST_WRAPPER(test_barrier5);
	TEST_WRAPPER(test_barrier6);
	TEST_WRAPPER(test_benchtest1);
	TEST_WRAPPER(test_benchtest2);
	TEST_WRAPPER(test_benchtest3);
	TEST_WRAPPER(test_benchtest4);
	TEST_WRAPPER(test_benchtest5);
	TEST_WRAPPER(test_cancel1);
	TEST_WRAPPER(test_cancel2);
	TEST_WRAPPER(test_cancel3);
	TEST_WRAPPER(test_cancel4);
	TEST_WRAPPER(test_cancel5);
	TEST_WRAPPER(test_cancel6a);
	TEST_WRAPPER(test_cancel6d);
//	TEST_WRAPPER(test_cancel7);
//	TEST_WRAPPER(test_cancel8);
	TEST_WRAPPER(test_cancel9);
	TEST_WRAPPER(test_cleanup0);
//	TEST_WRAPPER(test_cleanup1);
	TEST_WRAPPER(test_cleanup2);
	TEST_WRAPPER(test_cleanup3);
	TEST_WRAPPER(test_condvar1);
	TEST_WRAPPER(test_condvar1_1);
	TEST_WRAPPER(test_condvar1_2);
	TEST_WRAPPER(test_condvar2);
	TEST_WRAPPER(test_condvar2_1);
	TEST_WRAPPER(test_condvar3);
	TEST_WRAPPER(test_condvar3_1);
	TEST_WRAPPER(test_condvar3_2);
	TEST_WRAPPER(test_condvar3_3);
	TEST_WRAPPER(test_condvar4);
	TEST_WRAPPER(test_condvar5);
	TEST_WRAPPER(test_condvar6);
//	TEST_WRAPPER(test_condvar7);
	TEST_WRAPPER(test_condvar8);
//	TEST_WRAPPER(test_condvar9);
	TEST_WRAPPER(test_context1);
	TEST_WRAPPER(test_count1);
	TEST_WRAPPER(test_create1);
	TEST_WRAPPER(test_create2);
	TEST_WRAPPER(test_create3);
	TEST_WRAPPER(test_delay1);
	TEST_WRAPPER(test_delay2);
	TEST_WRAPPER(test_detach1);
	TEST_WRAPPER(test_equal1);
	TEST_WRAPPER(test_errno1);
//	TEST_WRAPPER(test_exception1);
	TEST_WRAPPER(test_exception3);
	TEST_WRAPPER(test_exception3_0);
	TEST_WRAPPER(test_exit2);
	TEST_WRAPPER(test_exit3);
	TEST_WRAPPER(test_exit4);
	TEST_WRAPPER(test_exit5);
	TEST_WRAPPER(test_eyal1);
	TEST_WRAPPER(test_inherit1);
	TEST_WRAPPER(test_join0);
	TEST_WRAPPER(test_join1);
	TEST_WRAPPER(test_join2);
	TEST_WRAPPER(test_join3);
	TEST_WRAPPER(test_join4);
	TEST_WRAPPER(test_kill1);
//	TEST_WRAPPER(test_loadfree);
	TEST_WRAPPER(test_mutex1);
	TEST_WRAPPER(test_mutex1e);
	TEST_WRAPPER(test_mutex1n);
	TEST_WRAPPER(test_mutex1r);
	TEST_WRAPPER(test_mutex2);
	TEST_WRAPPER(test_mutex2e);
	TEST_WRAPPER(test_mutex2r);
	TEST_WRAPPER(test_mutex3);
	TEST_WRAPPER(test_mutex3e);
	TEST_WRAPPER(test_mutex3r);
	TEST_WRAPPER(test_mutex4);
	TEST_WRAPPER(test_mutex5);
	TEST_WRAPPER(test_mutex6);
	TEST_WRAPPER(test_mutex6e);
	TEST_WRAPPER(test_mutex6es);
	TEST_WRAPPER(test_mutex6n);
	TEST_WRAPPER(test_mutex6r);
	TEST_WRAPPER(test_mutex6rs);
	TEST_WRAPPER(test_mutex6s);
	TEST_WRAPPER(test_mutex7);
	TEST_WRAPPER(test_mutex7e);
	TEST_WRAPPER(test_mutex7n);
	TEST_WRAPPER(test_mutex7r);
	TEST_WRAPPER(test_mutex8);
	TEST_WRAPPER(test_mutex8e);
	TEST_WRAPPER(test_mutex8n);
	TEST_WRAPPER(test_mutex8r);
	TEST_WRAPPER(test_once1);
	TEST_WRAPPER(test_once2);
	TEST_WRAPPER(test_once3);
	TEST_WRAPPER(test_once4);
	TEST_WRAPPER_W_ARGV(test_openmp1);
	TEST_WRAPPER(test_priority1);
	TEST_WRAPPER(test_priority2);
	/* TEST_WRAPPER(test_reuse1); -- fails when run here; does not fail when run at start of run :-S */
	TEST_WRAPPER(test_reuse2);
	TEST_WRAPPER(test_robust1);
	TEST_WRAPPER(test_robust2);
	TEST_WRAPPER(test_robust3);
	TEST_WRAPPER(test_robust4);
	TEST_WRAPPER(test_robust5);
	TEST_WRAPPER(test_rwlock1);
	TEST_WRAPPER(test_rwlock2);
	TEST_WRAPPER(test_rwlock2_t);
	TEST_WRAPPER(test_rwlock3);
	TEST_WRAPPER(test_rwlock3_t);
	TEST_WRAPPER(test_rwlock4);
	TEST_WRAPPER(test_rwlock4_t);
	TEST_WRAPPER(test_rwlock5);
	TEST_WRAPPER(test_rwlock5_t);
	TEST_WRAPPER(test_rwlock6);
	TEST_WRAPPER(test_rwlock6_t);
	TEST_WRAPPER(test_rwlock6_t2);
	TEST_WRAPPER(test_rwlock7);
	TEST_WRAPPER(test_rwlock8);
	TEST_WRAPPER(test_self1);
	TEST_WRAPPER(test_self2);
	TEST_WRAPPER(test_semaphore1);
	TEST_WRAPPER(test_semaphore2);
	TEST_WRAPPER(test_semaphore3);
	TEST_WRAPPER(test_semaphore4);
	TEST_WRAPPER(test_semaphore4t);
	TEST_WRAPPER(test_semaphore5);
//	TEST_WRAPPER(test_sequence1);
	TEST_WRAPPER(test_sizes);
	TEST_WRAPPER(test_spin1);
	TEST_WRAPPER(test_spin2);
	TEST_WRAPPER(test_spin3);
	TEST_WRAPPER(test_spin4);
	TEST_WRAPPER(test_stress1);
	TEST_WRAPPER(test_tryentercs);
	TEST_WRAPPER(test_tryentercs2);
	TEST_WRAPPER(test_tsd1);
	TEST_WRAPPER(test_tsd2);
	TEST_WRAPPER(test_valid1);
	TEST_WRAPPER(test_valid2);


	TEST_WRAPPER_W_ARGV(test_create3a);
	TEST_WRAPPER_W_ARGV(test_exception2);

	/* test_exit1 should be the VERY LAST test of the bunch as it will exit the application before it returns! */
	TEST_WRAPPER(test_exit1);

	printf("Should never get here!\n");
	return EXIT_FAILURE;
}
int
pthread_cond_init (pthread_cond_t * cond, const pthread_condattr_t * attr)
     /*
      * ------------------------------------------------------
      * DOCPUBLIC
      *      This function initializes a condition variable.
      *
      * PARAMETERS
      *      cond
      *              pointer to an instance of pthread_cond_t
      *
      *      attr
      *              specifies optional creation attributes.
      *
      *
      * DESCRIPTION
      *      This function initializes a condition variable.
      *
      * RESULTS
      *              0               successfully created condition variable,
      *              EINVAL          'attr' is invalid,
      *              EAGAIN          insufficient resources (other than
      *                              memory,
      *              ENOMEM          insufficient memory,
      *              EBUSY           'cond' is already initialized,
      *
      * ------------------------------------------------------
      */
{
  int result;
  pthread_cond_t cv = NULL;

  if (cond == NULL)
    {
      return EINVAL;
    }

#ifdef PTW32_STATIC_LIB
  // This allos for C++ static initializers to function without crashes. (air)
  pthread_win32_process_attach_np();
#endif

  if ((attr != NULL && *attr != NULL) &&
      ((*attr)->pshared == PTHREAD_PROCESS_SHARED))
    {
      /*
       * Creating condition variable that can be shared between
       * processes.
       */
      result = ENOSYS;
      goto DONE;
    }

  cv = (pthread_cond_t) calloc (1, sizeof (*cv));

  if (cv == NULL)
    {
      result = ENOMEM;
      goto DONE;
    }

  cv->nWaitersBlocked = 0;
  cv->nWaitersToUnblock = 0;
  cv->nWaitersGone = 0;

  if (sem_init (&(cv->semBlockLock), 0, 1) != 0)
    {
      result = errno;
      goto FAIL0;
    }

  if (sem_init (&(cv->semBlockQueue), 0, 0) != 0)
    {
      result = errno;
      goto FAIL1;
    }

  if ((result = pthread_mutex_init (&(cv->mtxUnblockLock), 0)) != 0)
    {
      goto FAIL2;
    }

  result = 0;

  goto DONE;

  /*
   * -------------
   * Failed...
   * -------------
   */
FAIL2:
  (void) sem_destroy (&(cv->semBlockQueue));

FAIL1:
  (void) sem_destroy (&(cv->semBlockLock));

FAIL0:
  (void) free (cv);
  cv = NULL;

DONE:
  if (0 == result)
    {
      EnterCriticalSection (&ptw32_cond_list_lock);

      cv->next = NULL;
      cv->prev = ptw32_cond_list_tail;

      if (ptw32_cond_list_tail != NULL)
	{
	  ptw32_cond_list_tail->next = cv;
	}

      ptw32_cond_list_tail = cv;

      if (ptw32_cond_list_head == NULL)
	{
	  ptw32_cond_list_head = cv;
	}

      LeaveCriticalSection (&ptw32_cond_list_lock);
    }

  *cond = cv;

  return result;

}				/* pthread_cond_init */
Exemple #13
0
int main(int argc, char **argv)
{
	int ds, dms, ret;
	double mb;
	struct timeval t1, t2;
#ifndef C_WINDOWS
	struct timezone tz;
	sigset_t sigset;
#endif
	struct optstruct *opt;
	const char *pt;

#if defined(C_WINDOWS) && defined(CL_THREAD_SAFE)
    if(!pthread_win32_process_attach_np()) {
	mprintf("!Can't start the win32 pthreads layer\n");
	return 72;
    }
#endif

#if !defined(C_WINDOWS) && !defined(C_BEOS)
    sigemptyset(&sigset);
    sigaddset(&sigset, SIGXFSZ);
    sigprocmask(SIG_SETMASK, &sigset, NULL);
#endif

    opt = opt_parse(argc, argv, clamscan_shortopt, clamscan_longopt, NULL, clamscan_deprecated);
    if(!opt) {
	mprintf("!Can't parse the command line\n");
	return 40;
    }

    if(opt_check(opt, "verbose")) {
	mprintf_verbose = 1;
	logg_verbose = 1;
    }

    if(opt_check(opt, "quiet"))
	mprintf_quiet = 1;

    if(opt_check(opt, "stdout"))
	mprintf_stdout = 1;


    if(opt_check(opt, "debug")) {
#if defined(C_LINUX)
	    /* [email protected]: create a dump if needed */
	    struct rlimit rlim;

	rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
	if(setrlimit(RLIMIT_CORE, &rlim) < 0)
	    perror("setrlimit");
#endif
	cl_debug(); /* enable debug messages */
    }

    if(opt_check(opt, "version")) {
	print_version(opt_arg(opt, "database"));
	opt_free(opt);
	return 0;
    }

    if(opt_check(opt, "help")) {
	opt_free(opt);
    	help();
	return 0;
    }

    if(opt_check(opt, "recursive"))
	recursion = 1;

    if(opt_check(opt, "infected"))
	printinfected = 1;

    if(opt_check(opt, "bell"))
	bell = 1;

    if(opt_check(opt, "tempdir"))
	cl_settempdir(opt_arg(opt, "tempdir"), 0);

    if(opt_check(opt, "leave-temps"))
	cl_settempdir(NULL, 1);

    /* initialize logger */
    if(opt_check(opt, "log")) {
	logg_file = opt_arg(opt, "log");
	if(logg("#\n-------------------------------------------------------------------------------\n\n")) {
	    mprintf("!Problem with internal logger.\n");
	    opt_free(opt);
	    return 62;
	}
    } else 
	logg_file = NULL;


    /* validate some numerical options */

    if(opt_check(opt, "max-scansize")) {
	pt = opt_arg(opt, "max-scansize");
	if(!strchr(pt, 'M') && !strchr(pt, 'm')) {
	    if(!cli_isnumber(pt)) {
		logg("!--max-scansize requires a natural number\n");
		opt_free(opt);
		return 40;
	    }
	}
    }

    if(opt_check(opt, "max-filesize")) {
	pt = opt_arg(opt, "max-filesize");
	if(!strchr(pt, 'M') && !strchr(pt, 'm')) {
	    if(!cli_isnumber(pt)) {
		logg("!--max-filesize requires a natural number\n");
		opt_free(opt);
		return 40;
	    }
	}
    }

    if(opt_check(opt, "max-files")) {
	if(!cli_isnumber(opt_arg(opt, "max-files"))) {
	    logg("!--max-files requires a natural number\n");
	    opt_free(opt);
	    return 40;
	}
    }

    if(opt_check(opt, "max-recursion")) {
	if(!cli_isnumber(opt_arg(opt, "max-recursion"))) {
	    logg("!--max-recursion requires a natural number\n");
	    opt_free(opt);
	    return 40;
	}
    }

    if(opt_check(opt, "max-mail-recursion")) {
	if(!cli_isnumber(opt_arg(opt, "max-mail-recursion"))) {
	    logg("!--max-mail-recursion requires a natural number\n");
	    opt_free(opt);
	    return 40;
	}
    }

    if(opt_check(opt, "max-dir-recursion")) {
	if(!cli_isnumber(opt_arg(opt, "max-dir-recursion"))) {
	    logg("!--max-dir-recursion requires a natural number\n");
	    opt_free(opt);
	    return 40;
	}
    }

    if(opt_check(opt, "max-ratio")) {
	if(!cli_isnumber(opt_arg(opt, "max-ratio"))) {
	    logg("!--max-ratio requires a natural number\n");
	    opt_free(opt);
	    return 40;
	}
    }

    memset(&info, 0, sizeof(struct s_info));

#ifdef _WIN32
    SetConsoleCtrlHandler((PHANDLER_ROUTINE) clamscan_ctrl_handler, TRUE);
#endif

#ifdef C_WINDOWS
    _set_fmode(_O_BINARY);
#ifdef CL_DEBUG
    {
	_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
	_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
    }
#endif	
    gettimeofday(&t1, NULL);
#else
    gettimeofday(&t1, &tz);
#endif

    ret = scanmanager(opt);

    if(!opt_check(opt, "disable-summary") && !opt_check(opt, "no-summary")) {
#ifdef C_WINDOWS
	gettimeofday(&t2, NULL);
#else
	gettimeofday(&t2, &tz);
#endif
	ds = t2.tv_sec - t1.tv_sec;
	dms = t2.tv_usec - t1.tv_usec;
	ds -= (dms < 0) ? (1):(0);
	dms += (dms < 0) ? (1000000):(0);
	logg("\n----------- SCAN SUMMARY -----------\n");
	logg("Known viruses: %u\n", info.sigs);
	logg("Engine version: %s\n", get_version());
	logg("Scanned directories: %u\n", info.dirs);
	logg("Scanned files: %u\n", info.files);
	logg("Infected files: %u\n", info.ifiles);
	if(info.notremoved) {
	    logg("Not removed: %u\n", info.notremoved);
	}
	if(info.notmoved) {
	    logg("Not %s: %u\n", opt_check(opt, "copy") ? "moved" : "copied", info.notmoved);
	}
	mb = info.blocks * (CL_COUNT_PRECISION / 1024) / 1024.0;
	logg("Data scanned: %2.2lf MB\n", mb);
	logg("Time: %u.%3.3u sec (%u m %u s)\n", ds, dms/1000, ds/60, ds%60);
    }

    opt_free(opt);

#if defined(C_WINDOWS) && defined(CL_THREAD_SAFE)
    if(!pthread_win32_process_detach_np()) {
	logg("!Can't stop the win32 pthreads layer\n");
	return 72;
    }
#endif

    return ret;
}
Exemple #14
0
int main(int argc, char **argv)
{
	const struct optstruct *opt;
#ifndef	C_WINDOWS
        struct passwd *user = NULL;
#endif
	time_t currtime;
	const char *dbdir, *cfgfile;
	char *pua_cats = NULL, *pt;
	int ret, tcpsock = 0, localsock = 0, i, min_port, max_port;
	unsigned int sigs = 0;
	int lsockets[2], nlsockets = 0;
	unsigned int dboptions = 0;
#ifdef C_LINUX
	struct stat sb;
#endif

#ifdef C_WINDOWS
    if(!pthread_win32_process_attach_np()) {
	mprintf("!Can't start the win32 pthreads layer\n");
        return 1;
    }
#endif

    if((opts = optparse(NULL, argc, argv, 1, OPT_CLAMD, 0, NULL)) == NULL) {
	mprintf("!Can't parse command line options\n");
	return 1;
    }

    if(optget(opts, "help")->enabled) {
    	help();
	optfree(opts);
	return 0;
    }

    if(optget(opts, "debug")->enabled) {
#if defined(C_LINUX)
	    /* [email protected]: create a dump if needed */
	    struct rlimit rlim;

	rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
	if(setrlimit(RLIMIT_CORE, &rlim) < 0)
	    perror("setrlimit");
#endif
	debug_mode = 1;
    }

    /* parse the config file */
    cfgfile = optget(opts, "config-file")->strarg;
    pt = strdup(cfgfile);
    if((opts = optparse(cfgfile, 0, NULL, 1, OPT_CLAMD, 0, opts)) == NULL) {
	fprintf(stderr, "ERROR: Can't open/parse the config file %s\n", pt);
	free(pt);
	return 1;
    }
    free(pt);

    if(optget(opts, "version")->enabled) {
	print_version(optget(opts, "DatabaseDirectory")->strarg);
	optfree(opts);
	return 0;
    }

    umask(0);

    /* drop privileges */
#if (!defined(C_OS2)) && (!defined(C_WINDOWS))
    if(geteuid() == 0 && (opt = optget(opts, "User"))->enabled) {
	if((user = getpwnam(opt->strarg)) == NULL) {
	    fprintf(stderr, "ERROR: Can't get information about user %s.\n", opt->strarg);
	    optfree(opts);
	    return 1;
	}

	if(optget(opts, "AllowSupplementaryGroups")->enabled) {
#ifdef HAVE_INITGROUPS
	    if(initgroups(opt->strarg, user->pw_gid)) {
		fprintf(stderr, "ERROR: initgroups() failed.\n");
		optfree(opts);
		return 1;
	    }
#else
	    mprintf("!AllowSupplementaryGroups: initgroups() is not available, please disable AllowSupplementaryGroups in %s\n", cfgfile);
	    optfree(opts);
	    return 1;
#endif
	} else {
#ifdef HAVE_SETGROUPS
	    if(setgroups(1, &user->pw_gid)) {
		fprintf(stderr, "ERROR: setgroups() failed.\n");
		optfree(opts);
		return 1;
	    }
#endif
	}

	if(setgid(user->pw_gid)) {
	    fprintf(stderr, "ERROR: setgid(%d) failed.\n", (int) user->pw_gid);
	    optfree(opts);
	    return 1;
	}

	if(setuid(user->pw_uid)) {
	    fprintf(stderr, "ERROR: setuid(%d) failed.\n", (int) user->pw_uid);
	    optfree(opts);
	    return 1;
	}
    }
#endif

    /* initialize logger */
    logg_lock = !optget(opts, "LogFileUnlock")->enabled;
    logg_time = optget(opts, "LogTime")->enabled;
    logok = optget(opts, "LogClean")->enabled;
    logg_size = optget(opts, "LogFileMaxSize")->numarg;
    logg_verbose = mprintf_verbose = optget(opts, "LogVerbose")->enabled;
    mprintf_send_timeout = optget(opts, "SendBufTimeout")->numarg;

    do { /* logger initialized */

    if((opt = optget(opts, "LogFile"))->enabled) {
	char timestr[32];
	logg_file = opt->strarg;
	if(strlen(logg_file) < 2 || (logg_file[0] != '/' && logg_file[0] != '\\' && logg_file[1] != ':')) {
	    fprintf(stderr, "ERROR: LogFile requires full path.\n");
	    ret = 1;
	    break;
	}
	time(&currtime);
	if(logg("#+++ Started at %s", cli_ctime(&currtime, timestr, sizeof(timestr)))) {
	    fprintf(stderr, "ERROR: Can't initialize the internal logger\n");
	    ret = 1;
	    break;
	}
    } else
	logg_file = NULL;

    if((ret = cl_init(CL_INIT_DEFAULT))) {
	logg("!Can't initialize libclamav: %s\n", cl_strerror(ret));
	ret = 1;
	break;
    }

    if(optget(opts, "Debug")->enabled) /* enable debug messages in libclamav */ {
	cl_debug();
	logg_verbose = 2;
    }

#if defined(USE_SYSLOG) && !defined(C_AIX)
    if(optget(opts, "LogSyslog")->enabled) {
	    int fac = LOG_LOCAL6;

	opt = optget(opts, "LogFacility");
	if((fac = logg_facility(opt->strarg)) == -1) {
	    logg("!LogFacility: %s: No such facility.\n", opt->strarg);
	    ret = 1;
	    break;
	}

	openlog("clamd", LOG_PID, fac);
	logg_syslog = 1;
    }
#endif

#ifdef C_LINUX
    procdev = 0;
    if(stat("/proc", &sb) != -1 && !sb.st_size)
	procdev = sb.st_dev;
#endif

    /* check socket type */

    if(optget(opts, "TCPSocket")->enabled)
	tcpsock = 1;

    if(optget(opts, "LocalSocket")->enabled)
	localsock = 1;

    if(!tcpsock && !localsock) {
	logg("!Please define server type (local and/or TCP).\n");
	ret = 1;
	break;
    }

    logg("#clamd daemon %s (OS: "TARGET_OS_TYPE", ARCH: "TARGET_ARCH_TYPE", CPU: "TARGET_CPU_TYPE")\n", get_version());

#ifndef C_WINDOWS
    if(user)
	logg("#Running as user %s (UID %u, GID %u)\n", user->pw_name, user->pw_uid, user->pw_gid);
#endif

    if(logg_size)
	logg("#Log file size limited to %d bytes.\n", logg_size);
    else
	logg("#Log file size limit disabled.\n");

    min_port = optget(opts, "StreamMinPort")->numarg;
    max_port = optget(opts, "StreamMaxPort")->numarg;
    if (min_port < 1024 || min_port > max_port || max_port > 65535) {
	logg("!Invalid StreamMinPort/StreamMaxPort: %d, %d\n", min_port, max_port);
	ret = 1;
	break;
    }

    if(!(engine = cl_engine_new())) {
	logg("!Can't initialize antivirus engine\n");
	ret = 1;
	break;
    }

    /* load the database(s) */
    dbdir = optget(opts, "DatabaseDirectory")->strarg;
    logg("#Reading databases from %s\n", dbdir);

    if(optget(opts, "DetectPUA")->enabled) {
	dboptions |= CL_DB_PUA;

	if((opt = optget(opts, "ExcludePUA"))->enabled) {
	    dboptions |= CL_DB_PUA_EXCLUDE;
	    i = 0;
	    logg("#Excluded PUA categories:");
	    while(opt) {
		if(!(pua_cats = realloc(pua_cats, i + strlen(opt->strarg) + 3))) {
		    logg("!Can't allocate memory for pua_cats\n");
		    cl_engine_free(engine);
		    ret = 1;
		    break;
		}
		logg("# %s", opt->strarg);
		sprintf(pua_cats + i, ".%s", opt->strarg);
		i += strlen(opt->strarg) + 1;
		pua_cats[i] = 0;
		opt = opt->nextarg;
	    }
	    if (ret)
		break;
	    logg("#\n");
	    pua_cats[i] = '.';
	    pua_cats[i + 1] = 0;
	}

	if((opt = optget(opts, "IncludePUA"))->enabled) {
	    if(pua_cats) {
		logg("!ExcludePUA and IncludePUA cannot be used at the same time\n");
		free(pua_cats);
		ret = 1;
		break;
	    }
	    dboptions |= CL_DB_PUA_INCLUDE;
	    i = 0;
	    logg("#Included PUA categories:");
	    while(opt) {
		if(!(pua_cats = realloc(pua_cats, i + strlen(opt->strarg) + 3))) {
		    logg("!Can't allocate memory for pua_cats\n");
		    ret = 1;
		    break;
		}
		logg("# %s", opt->strarg);
		sprintf(pua_cats + i, ".%s", opt->strarg);
		i += strlen(opt->strarg) + 1;
		pua_cats[i] = 0;
		opt = opt->nextarg;
	    }
	    if (ret)
		break;
	    logg("#\n");
	    pua_cats[i] = '.';
	    pua_cats[i + 1] = 0;
	}

	if(pua_cats) {
	    if((ret = cl_engine_set_str(engine, CL_ENGINE_PUA_CATEGORIES, pua_cats))) {
		logg("!cli_engine_set_str(CL_ENGINE_PUA_CATEGORIES) failed: %s\n", cl_strerror(ret));
		free(pua_cats);
		ret = 1;
		break;
	    }
	    free(pua_cats);
	}
    } else {
	logg("#Not loading PUA signatures.\n");
    }

    /* set the temporary dir */
    if((opt = optget(opts, "TemporaryDirectory"))->enabled) {
	if((ret = cl_engine_set_str(engine, CL_ENGINE_TMPDIR, opt->strarg))) {
	    logg("!cli_engine_set_str(CL_ENGINE_TMPDIR) failed: %s\n", cl_strerror(ret));
	    ret = 1;
	    break;
	}
    }

    if(optget(opts, "LeaveTemporaryFiles")->enabled)
	cl_engine_set_num(engine, CL_ENGINE_KEEPTMP, 1);

    if(optget(opts, "PhishingSignatures")->enabled)
	dboptions |= CL_DB_PHISHING;
    else
	logg("#Not loading phishing signatures.\n");

    if(optget(opts,"PhishingScanURLs")->enabled)
	dboptions |= CL_DB_PHISHING_URLS;
    else
	logg("#Disabling URL based phishing detection.\n");

    if(optget(opts,"DevACOnly")->enabled) {
	logg("#Only using the A-C matcher.\n");
	cl_engine_set_num(engine, CL_ENGINE_AC_ONLY, 1);
    }

    if((opt = optget(opts, "DevACDepth"))->enabled) {
        cl_engine_set_num(engine, CL_ENGINE_AC_MAXDEPTH, opt->numarg);
	logg("#Max A-C depth set to %u\n", (unsigned int) opt->numarg);
    }

    if((ret = cl_load(dbdir, engine, &sigs, dboptions))) {
	logg("!%s\n", cl_strerror(ret));
	ret = 1;
	break;
    }

    logg("#Loaded %u signatures.\n", sigs);
    if((ret = cl_engine_compile(engine)) != 0) {
	logg("!Database initialization error: %s\n", cl_strerror(ret));
	ret = 1;
	break;
    }

    if(tcpsock) {
#ifdef C_WINDOWS
	    WSADATA wsaData;

	if(WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) {
	    logg("!Error at WSAStartup(): %d\n", WSAGetLastError());
	    ret = 1;
	    break;
	}
#endif
	if ((lsockets[nlsockets] = tcpserver(opts)) == -1) {
	    ret = 1;
	    break;
	}
	nlsockets++;
    }

    if(localsock) {
	if ((lsockets[nlsockets] = localserver(opts)) == -1) {
	    ret = 1;
	    break;
	}
	nlsockets++;
    }

    /* fork into background */
    if(!optget(opts, "Foreground")->enabled) {
#ifdef C_BSD	    
	/* workaround for OpenBSD bug, see https://wwws.clamav.net/bugzilla/show_bug.cgi?id=885 */
	for(ret=0;ret<nlsockets;ret++) {
		fcntl(lsockets[ret], F_SETFL, fcntl(lsockets[ret], F_GETFL) | O_NONBLOCK);
	}
#endif
	if(daemonize() == -1) {
	    logg("!daemonize() failed\n");
	    ret = 1;
	    break;
	}
#ifdef C_BSD
	for(ret=0;ret<nlsockets;ret++) {
		fcntl(lsockets[ret], F_SETFL, fcntl(lsockets[ret], F_GETFL) & ~O_NONBLOCK);
	}
#endif
	if(!debug_mode)
	    if(chdir("/") == -1)
		logg("^Can't change current working directory to root\n");

    } else
        foreground = 1;

    ret = recvloop_th(lsockets, nlsockets, engine, dboptions, opts);

    } while (0);

    logg("*Closing the main socket%s.\n", (nlsockets > 1) ? "s" : "");

    for (i = 0; i < nlsockets; i++) {
	closesocket(lsockets[i]);
    }

#ifndef C_OS2
    if(nlsockets && localsock) {
	opt = optget(opts, "LocalSocket");
	if(unlink(opt->strarg) == -1)
	    logg("!Can't unlink the socket file %s\n", opt->strarg);
	else
	    logg("Socket file removed.\n");
    }
#endif

#ifdef C_WINDOWS
    if(tcpsock)
	WSACleanup();

    if(!pthread_win32_process_detach_np()) {
	logg("!Can't stop the win32 pthreads layer\n");
	logg_close();
	optfree(opts);
	return 1;
    }
#endif

    logg_close();
    optfree(opts);

    return ret;
}