Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F20320658
ath.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
6 KB
Subscribers
None
ath.c
View Options
/* ath.c - Thread-safeness library.
Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of Libgcrypt.
Libgcrypt is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of
the License, or (at your option) any later version.
Libgcrypt is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with Libgcrypt; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#ifdef HAVE_CONFIG_H
#include
<config.h>
#endif
#include
<assert.h>
/* Right: We need to use assert and not gcry_assert. */
#include
<unistd.h>
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#else
# include <sys/time.h>
#endif
#include
<sys/types.h>
#ifndef _WIN32
#include
<sys/wait.h>
#endif
#include
<errno.h>
#include
"ath.h"
/* The interface table. */
static
struct
ath_ops
ops
;
/* True if we should use the external callbacks. */
static
int
ops_set
;
/* For the dummy interface. */
#define MUTEX_UNLOCKED ((ath_mutex_t) 0)
#define MUTEX_LOCKED ((ath_mutex_t) 1)
#define MUTEX_DESTROYED ((ath_mutex_t) 2)
/* Return the thread type from the option field. */
#define GET_OPTION(a) ((a) & 0xff)
/* Return the version number from the option field. */
#define GET_VERSION(a) (((a) >> 8)& 0xff)
/* The lock we take while checking for lazy lock initialization. */
static
ath_mutex_t
check_init_lock
=
ATH_MUTEX_INITIALIZER
;
int
ath_init
(
void
)
{
int
err
=
0
;
if
(
ops_set
)
{
if
(
ops
.
init
)
err
=
(
*
ops
.
init
)
();
if
(
err
)
return
err
;
err
=
(
*
ops
.
mutex_init
)
(
&
check_init_lock
);
}
return
err
;
}
/* Initialize the locking library. Returns 0 if the operation was
successful, EINVAL if the operation table was invalid and EBUSY if
we already were initialized. */
gpg_err_code_t
ath_install
(
struct
ath_ops
*
ath_ops
,
int
check_only
)
{
if
(
check_only
)
{
unsigned
int
option
=
0
;
/* Check if the requested thread option is compatible to the
thread option we are already committed to. */
if
(
ath_ops
)
option
=
ath_ops
->
option
;
if
(
!
ops_set
&&
GET_OPTION
(
option
))
return
GPG_ERR_NOT_SUPPORTED
;
if
(
GET_OPTION
(
ops
.
option
)
==
ATH_THREAD_OPTION_USER
||
GET_OPTION
(
option
)
==
ATH_THREAD_OPTION_USER
||
GET_OPTION
(
ops
.
option
)
!=
GET_OPTION
(
option
)
||
GET_VERSION
(
ops
.
option
)
!=
GET_VERSION
(
option
))
return
GPG_ERR_NOT_SUPPORTED
;
return
0
;
}
if
(
ath_ops
)
{
/* It is convenient to not require DESTROY. */
if
(
!
ath_ops
->
mutex_init
||
!
ath_ops
->
mutex_lock
||
!
ath_ops
->
mutex_unlock
)
return
GPG_ERR_INV_ARG
;
ops
=
*
ath_ops
;
ops_set
=
1
;
}
else
ops_set
=
0
;
return
0
;
}
static
int
mutex_init
(
ath_mutex_t
*
lock
,
int
just_check
)
{
int
err
=
0
;
if
(
just_check
)
(
*
ops
.
mutex_lock
)
(
&
check_init_lock
);
if
(
*
lock
==
ATH_MUTEX_INITIALIZER
||
!
just_check
)
err
=
(
*
ops
.
mutex_init
)
(
lock
);
if
(
just_check
)
(
*
ops
.
mutex_unlock
)
(
&
check_init_lock
);
return
err
;
}
int
ath_mutex_init
(
ath_mutex_t
*
lock
)
{
if
(
ops_set
)
return
mutex_init
(
lock
,
0
);
#ifndef NDEBUG
*
lock
=
MUTEX_UNLOCKED
;
#endif
return
0
;
}
int
ath_mutex_destroy
(
ath_mutex_t
*
lock
)
{
if
(
ops_set
)
{
if
(
!
ops
.
mutex_destroy
)
return
0
;
(
*
ops
.
mutex_lock
)
(
&
check_init_lock
);
if
(
*
lock
==
ATH_MUTEX_INITIALIZER
)
{
(
*
ops
.
mutex_unlock
)
(
&
check_init_lock
);
return
0
;
}
(
*
ops
.
mutex_unlock
)
(
&
check_init_lock
);
return
(
*
ops
.
mutex_destroy
)
(
lock
);
}
#ifndef NDEBUG
assert
(
*
lock
==
MUTEX_UNLOCKED
);
*
lock
=
MUTEX_DESTROYED
;
#endif
return
0
;
}
int
ath_mutex_lock
(
ath_mutex_t
*
lock
)
{
if
(
ops_set
)
{
int
ret
=
mutex_init
(
lock
,
1
);
if
(
ret
)
return
ret
;
return
(
*
ops
.
mutex_lock
)
(
lock
);
}
#ifndef NDEBUG
assert
(
*
lock
==
MUTEX_UNLOCKED
);
*
lock
=
MUTEX_LOCKED
;
#endif
return
0
;
}
int
ath_mutex_unlock
(
ath_mutex_t
*
lock
)
{
if
(
ops_set
)
{
int
ret
=
mutex_init
(
lock
,
1
);
if
(
ret
)
return
ret
;
return
(
*
ops
.
mutex_unlock
)
(
lock
);
}
#ifndef NDEBUG
assert
(
*
lock
==
MUTEX_LOCKED
);
*
lock
=
MUTEX_UNLOCKED
;
#endif
return
0
;
}
ssize_t
ath_read
(
int
fd
,
void
*
buf
,
size_t
nbytes
)
{
if
(
ops_set
&&
ops
.
read
)
return
(
*
ops
.
read
)
(
fd
,
buf
,
nbytes
);
else
return
read
(
fd
,
buf
,
nbytes
);
}
ssize_t
ath_write
(
int
fd
,
const
void
*
buf
,
size_t
nbytes
)
{
if
(
ops_set
&&
ops
.
write
)
return
(
*
ops
.
write
)
(
fd
,
buf
,
nbytes
);
else
return
write
(
fd
,
buf
,
nbytes
);
}
ssize_t
#ifdef _WIN32
ath_select
(
int
nfd
,
void
*
rset
,
void
*
wset
,
void
*
eset
,
struct
timeval
*
timeout
)
#else
ath_select
(
int
nfd
,
fd_set
*
rset
,
fd_set
*
wset
,
fd_set
*
eset
,
struct
timeval
*
timeout
)
#endif
{
if
(
ops_set
&&
ops
.
select
)
return
(
*
ops
.
select
)
(
nfd
,
rset
,
wset
,
eset
,
timeout
);
else
#ifdef _WIN32
return
-1
;
#else
return
select
(
nfd
,
rset
,
wset
,
eset
,
timeout
);
#endif
}
ssize_t
ath_waitpid
(
pid_t
pid
,
int
*
status
,
int
options
)
{
if
(
ops_set
&&
ops
.
waitpid
)
return
(
*
ops
.
waitpid
)
(
pid
,
status
,
options
);
else
#ifdef _WIN32
return
-1
;
#else
return
waitpid
(
pid
,
status
,
options
);
#endif
}
int
#ifdef _WIN32
ath_accept
(
int
s
,
void
*
addr
,
int
*
length_ptr
)
#else
ath_accept
(
int
s
,
struct
sockaddr
*
addr
,
socklen_t
*
length_ptr
)
#endif
{
if
(
ops_set
&&
ops
.
accept
)
return
(
*
ops
.
accept
)
(
s
,
addr
,
length_ptr
);
else
#ifdef _WIN32
return
-1
;
#else
return
accept
(
s
,
addr
,
length_ptr
);
#endif
}
int
#ifdef _WIN32
ath_connect
(
int
s
,
void
*
addr
,
int
length
)
#else
ath_connect
(
int
s
,
struct
sockaddr
*
addr
,
socklen_t
length
)
#endif
{
if
(
ops_set
&&
ops
.
connect
)
return
(
*
ops
.
connect
)
(
s
,
addr
,
length
);
else
#ifdef _WIN32
return
-1
;
#else
return
connect
(
s
,
addr
,
length
);
#endif
}
int
#ifdef _WIN32
ath_sendmsg
(
int
s
,
const
void
*
msg
,
int
flags
)
#else
ath_sendmsg
(
int
s
,
const
struct
msghdr
*
msg
,
int
flags
)
#endif
{
if
(
ops_set
&&
ops
.
sendmsg
)
return
(
*
ops
.
sendmsg
)
(
s
,
msg
,
flags
);
else
#ifdef _WIN32
return
-1
;
#else
return
sendmsg
(
s
,
msg
,
flags
);
#endif
}
int
#ifdef _WIN32
ath_recvmsg
(
int
s
,
void
*
msg
,
int
flags
)
#else
ath_recvmsg
(
int
s
,
struct
msghdr
*
msg
,
int
flags
)
#endif
{
if
(
ops_set
&&
ops
.
recvmsg
)
return
(
*
ops
.
recvmsg
)
(
s
,
msg
,
flags
);
else
#ifdef _WIN32
return
-1
;
#else
return
recvmsg
(
s
,
msg
,
flags
);
#endif
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Fri, Mar 14, 4:18 AM (1 d, 11 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
57/fd/4ab55dcf60fc740d6321cde919d5
Attached To
rC libgcrypt
Event Timeline
Log In to Comment