Get rid of PATH_MAX and MAXPATHLEN

There could be no upper limit on the length of a path according
to POSIX, therefore these macros may not be defined at all on
some systems (such as GNU Hurd).

Signed-off-by: Arnaud Fontaine <arnau@debian.org>
Reviewed-by: Peter Harris <pharris@opentext.com>
This commit is contained in:
Arnaud Fontaine 2010-04-30 14:47:16 +02:00
parent d068572173
commit a546d00091
2 changed files with 83 additions and 16 deletions

View File

@ -89,8 +89,7 @@ static int authname_match(enum auth_protos kind, char *name, size_t namelen)
#define SIN6_ADDR(s) (&((struct sockaddr_in6 *)s)->sin6_addr)
static Xauth *get_authptr(struct sockaddr *sockname, unsigned int socknamelen,
int display)
static Xauth *get_authptr(struct sockaddr *sockname, int display)
{
char *addr = 0;
int addrlen = 0;
@ -243,13 +242,55 @@ static int compute_auth(xcb_auth_info_t *info, Xauth *authptr, struct sockaddr *
return 0; /* Unknown authorization type */
}
/* `sockaddr_un.sun_path' typical size usually ranges between 92 and 108 */
#define INITIAL_SOCKNAME_SLACK 108
/* Return a dynamically allocated socket address structure according
to the value returned by either getpeername() or getsockname()
(according to POSIX, applications should not assume a particular
length for `sockaddr_un.sun_path') */
static struct sockaddr *get_peer_sock_name(int (*socket_func)(int,
struct sockaddr *,
socklen_t *),
int fd)
{
socklen_t socknamelen = sizeof(struct sockaddr) + INITIAL_SOCKNAME_SLACK;
socklen_t actual_socknamelen = socknamelen;
struct sockaddr *sockname = malloc(socknamelen), *new_sockname = NULL;
if (sockname == NULL)
return NULL;
/* Both getpeername() and getsockname() truncates sockname if
there is not enough space and set the required length in
actual_socknamelen */
if (socket_func(fd, sockname, &actual_socknamelen) == -1)
goto sock_or_realloc_error;
if (actual_socknamelen > socknamelen)
{
socknamelen = actual_socknamelen;
if ((new_sockname = realloc(sockname, actual_socknamelen)) == NULL ||
socket_func(fd, new_sockname, &actual_socknamelen) == -1 ||
actual_socknamelen > socknamelen)
goto sock_or_realloc_error;
sockname = new_sockname;
}
return sockname;
sock_or_realloc_error:
free(sockname);
return NULL;
}
int _xcb_get_auth_info(int fd, xcb_auth_info_t *info, int display)
{
/* code adapted from Xlib/ConnDis.c, xtrans/Xtranssocket.c,
xtrans/Xtransutils.c */
char sockbuf[sizeof(struct sockaddr) + MAXPATHLEN];
unsigned int socknamelen = sizeof(sockbuf); /* need extra space */
struct sockaddr *sockname = (struct sockaddr *) &sockbuf;
struct sockaddr *sockname = NULL;
int gotsockname = 0;
Xauth *authptr = 0;
int ret = 1;
@ -258,24 +299,30 @@ int _xcb_get_auth_info(int fd, xcb_auth_info_t *info, int display)
* for UNIX Domain Sockets, but this is irrelevant,
* since compute_auth() ignores the peer name in this
* case anyway.*/
if (getpeername(fd, sockname, &socknamelen) == -1)
if ((sockname = get_peer_sock_name(getpeername, fd)) == NULL)
{
if (getsockname(fd, sockname, &socknamelen) == -1)
if ((sockname = get_peer_sock_name(getsockname, fd)) == NULL)
return 0; /* can only authenticate sockets */
if (sockname->sa_family != AF_UNIX)
{
free(sockname);
return 0; /* except for AF_UNIX, sockets should have peernames */
}
gotsockname = 1;
}
authptr = get_authptr(sockname, socknamelen, display);
authptr = get_authptr(sockname, display);
if (authptr == 0)
{
free(sockname);
return 0; /* cannot find good auth data */
}
info->namelen = memdup(&info->name, authptr->name, authptr->name_length);
if (!info->namelen)
goto no_auth; /* out of memory */
if (!gotsockname && getsockname(fd, sockname, &socknamelen) == -1)
if (!gotsockname && (sockname = get_peer_sock_name(getsockname, fd)) == NULL)
{
free(info->name);
goto no_auth; /* can only authenticate sockets */
@ -288,10 +335,15 @@ int _xcb_get_auth_info(int fd, xcb_auth_info_t *info, int display)
goto no_auth; /* cannot build auth record */
}
free(sockname);
sockname = NULL;
XauDisposeAuth(authptr);
return ret;
no_auth:
free(sockname);
info->name = 0;
info->namelen = 0;
XauDisposeAuth(authptr);

View File

@ -145,8 +145,9 @@ static int _xcb_open(char *host, char *protocol, const int display)
#endif
static const char unix_base[] = "/tmp/.X11-unix/X";
const char *base = unix_base;
char file[PATH_MAX + 1];
int filelen;
size_t filelen;
char *file = NULL;
int actual_filelen;
if(*host)
{
@ -181,24 +182,38 @@ static int _xcb_open(char *host, char *protocol, const int display)
#endif
}
filelen = strlen(base) + 1 + sizeof(display) * 3 + 1;
file = malloc(filelen);
if(file == NULL)
return -1;
/* display specifies Unix socket */
#ifdef HAVE_LAUNCHD
if(base == host)
filelen = snprintf(file, sizeof(file), "%s:%d", base, display);
actual_filelen = snprintf(file, filelen, "%s:%d", base, display);
else
#endif
filelen = snprintf(file, sizeof(file), "%s%d", base, display);
if(filelen < 0)
actual_filelen = snprintf(file, filelen, "%s%d", base, display);
if(actual_filelen < 0)
{
free(file);
return -1;
}
/* snprintf may truncate the file */
filelen = MIN(filelen, sizeof(file) - 1);
filelen = MIN(actual_filelen, filelen - 1);
#ifdef HAVE_ABSTRACT_SOCKETS
fd = _xcb_open_abstract(protocol, file, filelen);
if (fd >= 0 || (errno != ENOENT && errno != ECONNREFUSED))
{
free(file);
return fd;
}
#endif
return _xcb_open_unix(protocol, file);
fd = _xcb_open_unix(protocol, file);
free(file);
return fd;
}
static int _xcb_socket(int family, int type, int proto)