contrib/chg/hgclient.c
changeset 30678 112915e9a363
parent 29731 acf27be56d26
child 30682 fe11f466880d
equal deleted inserted replaced
30677:eb69f78c48ab 30678:112915e9a363
   423 	 * process get terminated. */
   423 	 * process get terminated. */
   424 	fsetcloexec(fd);
   424 	fsetcloexec(fd);
   425 
   425 
   426 	struct sockaddr_un addr;
   426 	struct sockaddr_un addr;
   427 	addr.sun_family = AF_UNIX;
   427 	addr.sun_family = AF_UNIX;
   428 	strncpy(addr.sun_path, sockname, sizeof(addr.sun_path));
   428 
       
   429 	/* use chdir to workaround small sizeof(sun_path) */
       
   430 	int bakfd = -1;
       
   431 	const char *basename = sockname;
       
   432 	{
       
   433 		const char *split = strrchr(sockname, '/');
       
   434 		if (split && split != sockname) {
       
   435 			if (split[1] == '\0')
       
   436 				abortmsg("sockname cannot end with a slash");
       
   437 			size_t len = split - sockname;
       
   438 			char sockdir[len + 1];
       
   439 			memcpy(sockdir, sockname, len);
       
   440 			sockdir[len] = '\0';
       
   441 
       
   442 			bakfd = open(".", O_DIRECTORY);
       
   443 			if (bakfd == -1)
       
   444 				abortmsgerrno("cannot open cwd");
       
   445 
       
   446 			int r = chdir(sockdir);
       
   447 			if (r != 0)
       
   448 				abortmsgerrno("cannot chdir %s", sockdir);
       
   449 
       
   450 			basename = split + 1;
       
   451 		}
       
   452 	}
       
   453 	if (strlen(basename) >= sizeof(addr.sun_path))
       
   454 		abortmsg("sockname is too long: %s", basename);
       
   455 	strncpy(addr.sun_path, basename, sizeof(addr.sun_path));
   429 	addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
   456 	addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
   430 
   457 
       
   458 	/* real connect */
   431 	int r = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
   459 	int r = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
       
   460 	if (bakfd != -1) {
       
   461 		fchdirx(bakfd);
       
   462 		close(bakfd);
       
   463 	}
       
   464 
   432 	if (r < 0) {
   465 	if (r < 0) {
   433 		close(fd);
   466 		close(fd);
   434 		if (errno == ENOENT || errno == ECONNREFUSED)
   467 		if (errno == ENOENT || errno == ECONNREFUSED)
   435 			return NULL;
   468 			return NULL;
   436 		abortmsgerrno("cannot connect to %s", addr.sun_path);
   469 		abortmsgerrno("cannot connect to %s", addr.sun_path);