Blame SPECS/ksh-20120801-rmdirfix.patch

Packit 992a25
diff -up ksh20120801/src/cmd/ksh93/sh/subshell.c.orig ksh20120801/src/cmd/ksh93/sh/subshell.c
Packit 992a25
--- ksh20120801/src/cmd/ksh93/sh/subshell.c.orig	2012-07-17 23:54:21.000000000 +0200
Packit 992a25
+++ ksh20120801/src/cmd/ksh93/sh/subshell.c	2012-10-24 15:03:44.436870792 +0200
Packit 992a25
@@ -40,14 +40,6 @@
Packit 992a25
 #   define PIPE_BUF	512
Packit 992a25
 #endif
Packit 992a25
 
Packit 992a25
-#ifndef O_SEARCH
Packit 992a25
-#   ifdef O_PATH
Packit 992a25
-#	define O_SEARCH	O_PATH
Packit 992a25
-#   else
Packit 992a25
-#	define O_SEARCH	0
Packit 992a25
-#   endif
Packit 992a25
-#endif
Packit 992a25
-
Packit 992a25
 /*
Packit 992a25
  * Note that the following structure must be the same
Packit 992a25
  * size as the Dtlink_t structure
Packit 992a25
@@ -84,7 +76,7 @@ static struct subshell
Packit 992a25
 	char		*pwd;	/* present working directory */
Packit 992a25
 	const char	*shpwd;	/* saved pointer to sh.pwd */
Packit 992a25
 	void		*jobs;	/* save job info */
Packit 992a25
-	int		pwdfd;	/* file descritor for pwd */
Packit 992a25
+	int		shpwdfd;/* fd for present working directory */
Packit 992a25
 	mode_t		mask;	/* saved umask */
Packit 992a25
 	short		tmpfd;	/* saved tmp file descriptor */
Packit 992a25
 	short		pipefd;	/* read fd if pipe is created */
Packit 992a25
@@ -101,7 +93,6 @@ static struct subshell
Packit 992a25
 	int		subdup;
Packit 992a25
 	char		subshare;
Packit 992a25
 	char		comsub;
Packit 992a25
-	char		pwdclose;
Packit 992a25
 #if SHOPT_COSHELL
Packit 992a25
 	void		*coshell;
Packit 992a25
 #endif /* SHOPT_COSHELL */
Packit 992a25
@@ -518,7 +509,6 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
Packit 992a25
 		shp->pathinit = 0;
Packit 992a25
 	}
Packit 992a25
 	sp->pathlist = path_dup((Pathcomp_t*)shp->pathlist);
Packit 992a25
-	sp->pwdfd = -1;
Packit 992a25
 	if(!shp->pwd)
Packit 992a25
 		path_pwd(shp,0);
Packit 992a25
 	sp->bckpid = shp->bckpid;
Packit 992a25
@@ -531,39 +521,14 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
Packit 992a25
 	shp->subshare = comsub==2 ||  (comsub==1 && sh_isoption(SH_SUBSHARE));
Packit 992a25
 	if(comsub)
Packit 992a25
 		shp->comsub = comsub;
Packit 992a25
+	sp->shpwdfd=-1;
Packit 992a25
 	if(!comsub || !shp->subshare)
Packit 992a25
 	{
Packit 992a25
-		struct subshell *xp;
Packit 992a25
 		sp->shpwd = shp->pwd;
Packit 992a25
-#ifdef _lib_fchdir
Packit 992a25
-		for(xp=sp->prev; xp; xp=xp->prev) 
Packit 992a25
-		{
Packit 992a25
-			if(xp->pwdfd>0 && strcmp(xp->pwd,shp->pwd)==0)
Packit 992a25
-			{
Packit 992a25
-				sp->pwdfd = xp->pwdfd;
Packit 992a25
-				break;
Packit 992a25
-			}
Packit 992a25
-		}
Packit 992a25
-		if(sp->pwdfd<0)
Packit 992a25
-		{
Packit 992a25
-			int n = open(".",O_RDONLY);
Packit 992a25
-			if(O_SEARCH && errno==EACCES)
Packit 992a25
-				n =  open(".",O_RDONLY);
Packit 992a25
-			if(n>=0)
Packit 992a25
-			{
Packit 992a25
-				sp->pwdfd = n;
Packit 992a25
-				if(n<10)
Packit 992a25
-				{
Packit 992a25
-					sp->pwdfd = sh_fcntl(n,F_DUPFD,10);
Packit 992a25
-					close(n);
Packit 992a25
-				}
Packit 992a25
-				if(sp->pwdfd>0)
Packit 992a25
-				{
Packit 992a25
-					fcntl(sp->pwdfd,F_SETFD,FD_CLOEXEC);
Packit 992a25
-					sp->pwdclose = 1;
Packit 992a25
-				}
Packit 992a25
-			}
Packit 992a25
-		}
Packit 992a25
+		sp->shpwdfd=((shp->pwdfd >= 0))?sh_fcntl(shp->pwdfd, F_dupfd_cloexec, 10):-1;
Packit 992a25
+#ifdef O_SEARCH
Packit 992a25
+		if(sp->shpwdfd<0)
Packit 992a25
+			errormsg(SH_DICT,ERROR_system(1), "Can't obtain directory fd.");
Packit 992a25
 #endif
Packit 992a25
 		sp->pwd = (shp->pwd?strdup(shp->pwd):0);
Packit 992a25
 		sp->mask = shp->mask;
Packit 992a25
@@ -741,14 +706,11 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
Packit 992a25
 			Namval_t *pwdnod = sh_scoped(shp,PWDNOD);
Packit 992a25
 			if(shp->pwd)
Packit 992a25
 			{
Packit 992a25
-				if(sp->pwdfd >=0)
Packit 992a25
-				{
Packit 992a25
-					if(fchdir(sp->pwdfd)<0)
Packit 992a25
-						chdir(sp->pwd);
Packit 992a25
-				}
Packit 992a25
-				else
Packit 992a25
-					chdir(sp->pwd);
Packit 992a25
 				shp->pwd=sp->pwd;
Packit 992a25
+#ifndef O_SEARCH
Packit 992a25
+				if (sp->shpwdfd < 0)
Packit 992a25
+					chdir(shp->pwd);
Packit 992a25
+#endif
Packit 992a25
 				path_newdir(shp,shp->pathlist);
Packit 992a25
 			}
Packit 992a25
 			if(nv_isattr(pwdnod,NV_NOFREE))
Packit 992a25
@@ -762,8 +724,6 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
Packit 992a25
 		}
Packit 992a25
 		else
Packit 992a25
 			free((void*)sp->pwd);
Packit 992a25
-		if(sp->pwdclose)
Packit 992a25
-			close(sp->pwdfd);
Packit 992a25
 		if(sp->mask!=shp->mask)
Packit 992a25
 			umask(shp->mask=sp->mask);
Packit 992a25
 		if(shp->coutpipe!=sp->coutpipe)
Packit 992a25
@@ -775,6 +735,13 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
Packit 992a25
 		shp->cpipe[1] = sp->cpipe;
Packit 992a25
 		shp->coutpipe = sp->coutpipe;
Packit 992a25
 	}
Packit 992a25
+	if(sp->shpwdfd >=0)
Packit 992a25
+	{
Packit 992a25
+		if(shp->pwdfd >=0)
Packit 992a25
+			sh_close(shp->pwdfd);
Packit 992a25
+		shp->pwdfd=sp->shpwdfd;
Packit 992a25
+		fchdir(shp->pwdfd);
Packit 992a25
+	}
Packit 992a25
 	shp->subshare = sp->subshare;
Packit 992a25
 	shp->comsub = sp->comsub;
Packit 992a25
 	shp->subdup = sp->subdup;
Packit 992a25
diff -up ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c.orig ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c
Packit 992a25
--- ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c.orig	2012-08-02 16:50:40.000000000 +0200
Packit 992a25
+++ ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c	2012-10-24 15:37:46.814469045 +0200
Packit 992a25
@@ -38,6 +38,10 @@
Packit 992a25
 #include	"builtins.h"
Packit 992a25
 #include	<ls.h>
Packit 992a25
 
Packit 992a25
+#ifndef EINTR_REPEAT
Packit 992a25
+#   define EINTR_REPEAT(expr) while((expr) && (errno == EINTR)) errno=0;
Packit 992a25
+#endif
Packit 992a25
+
Packit 992a25
 /*
Packit 992a25
  * Invalidate path name bindings to relative paths
Packit 992a25
  */
Packit 992a25
@@ -49,6 +53,95 @@ static void rehash(register Namval_t *np
Packit 992a25
 		_nv_unset(np,0);
Packit 992a25
 }
Packit 992a25
 
Packit 992a25
+/*
Packit 992a25
+ * Obtain a file handle to the directory "path" relative to directory
Packit 992a25
+ * "dir", or open a NFSv4 xattr directory handle for file dir/path.
Packit 992a25
+ */
Packit 992a25
+int sh_diropenat(Shell_t *shp, int dir, const char *path, bool xattr)
Packit 992a25
+{
Packit 992a25
+	int fd,shfd;
Packit 992a25
+	int savederrno=errno;
Packit 992a25
+#ifndef AT_FDCWD
Packit 992a25
+	NOT_USED(dir);
Packit 992a25
+#endif
Packit 992a25
+#ifndef O_XATTR
Packit 992a25
+	NOT_USED(xattr);
Packit 992a25
+#endif
Packit 992a25
+
Packit 992a25
+#ifdef O_XATTR
Packit 992a25
+	if(xattr)
Packit 992a25
+	{
Packit 992a25
+		int apfd; /* attribute parent fd */
Packit 992a25
+		/* open parent node... */
Packit 992a25
+		EINTR_REPEAT((apfd = openat(dir, path, O_RDONLY|O_NONBLOCK|O_cloexec)) < 0);
Packit 992a25
+		if(apfd < 0)
Packit 992a25
+			return -1;
Packit 992a25
+
Packit 992a25
+		/* ... and then open a fd to the attribute directory */
Packit 992a25
+		 EINTR_REPEAT((fd = openat(apfd, e_dot, O_XATTR|O_cloexec)) < 0);
Packit 992a25
+
Packit 992a25
+		savederrno = errno;
Packit 992a25
+		EINTR_REPEAT(close(apfd) < 0);
Packit 992a25
+		errno = savederrno;
Packit 992a25
+	}
Packit 992a25
+	else
Packit 992a25
+#endif
Packit 992a25
+	{
Packit 992a25
+#ifdef AT_FDCWD
Packit 992a25
+		/*
Packit 992a25
+		 * Open directory. First we try without |O_SEARCH| and
Packit 992a25
+		 * if this fails with EACCESS we try with |O_SEARCH|
Packit 992a25
+		 * again.
Packit 992a25
+		 * This is required ...
Packit 992a25
+		 * - ... because some platforms may require that it can
Packit 992a25
+		 * only be used for directories while some filesystems
Packit 992a25
+		 * (e.g. Reiser4 or HSM systems) allow a |fchdir()| into
Packit 992a25
+		 * files, too)
Packit 992a25
+		 * - ... to preserve the semantics of "cd", e.g.
Packit 992a25
+		 * otherwise "cd" would return [No access] instead of
Packit 992a25
+		 * [Not a directory] for files on filesystems which do
Packit 992a25
+		 * not allow a "cd" into files.
Packit 992a25
+		 * - ... to allow that a
Packit 992a25
+		 * $ redirect {n}
Packit 992a25
+		 * platforms.
Packit 992a25
+		 */
Packit 992a25
+		EINTR_REPEAT((fd = openat(dir, path, O_RDONLY|O_NONBLOCK|O_cloexec)) < 0);
Packit 992a25
+#   ifdef O_SEARCH
Packit 992a25
+		if((fd < 0) && (errno == EACCES))
Packit 992a25
+		{
Packit 992a25
+			EINTR_REPEAT((fd = openat(dir, path, O_SEARCH|O_cloexec)) < 0)
Packit 992a25
+		}
Packit 992a25
+#   endif
Packit 992a25
+#else
Packit 992a25
+		/*
Packit 992a25
+		 * Version of openat() call above for systems without
Packit 992a25
+		 * openat API. This only works because we basically
Packit 992a25
+		 * gurantee that |dir| is always the same place as
Packit 992a25
+		 * |cwd| on such machines (but this won't be the case
Packit 992a25
+		 * in the future).
Packit 992a25
+		 */
Packit 992a25
+		/*
Packit 992a25
+		 * This |fchdir()| call is not needed (yet) since
Packit 992a25
+		 * all consumers do not use |dir| when |AT_FDCWD|
Packit 992a25
+		 * is not available.
Packit 992a25
+		 *
Packit 992a25
+		 * fchdir(dir);
Packit 992a25
+		 */
Packit 992a25
+		EINTR_REPEAT((fd = open(path, O_cloexec)) < 0);
Packit 992a25
+#endif
Packit 992a25
+	}
Packit 992a25
+
Packit 992a25
+	if(fd < 0)
Packit 992a25
+		return fd;
Packit 992a25
+
Packit 992a25
+	/* Move fd to a number > 10 and *register* the fd number with the shell */
Packit 992a25
+	shfd = sh_fcntl(fd, F_dupfd_cloexec, 10);
Packit 992a25
+	savederrno=errno;
Packit 992a25
+	sh_close(fd);
Packit 992a25
+	errno=savederrno;
Packit 992a25
+	return(shfd);
Packit 992a25
+}
Packit 992a25
+
Packit 992a25
 int	b_cd(int argc, char *argv[],Shbltin_t *context)
Packit 992a25
 {
Packit 992a25
 	register char *dir;
Packit 992a25
@@ -56,18 +149,20 @@ int	b_cd(int argc, char *argv[],Shbltin_
Packit 992a25
 	register const char *dp;
Packit 992a25
 	register Shell_t *shp = context->shp;
Packit 992a25
 	int saverrno=0;
Packit 992a25
-	int rval,flag=0;
Packit 992a25
+	int rval;
Packit 992a25
+	bool flag=false,xattr=false;
Packit 992a25
 	char *oldpwd;
Packit 992a25
+	int newdirfd;
Packit 992a25
 	Namval_t *opwdnod, *pwdnod;
Packit 992a25
 	if(sh_isoption(SH_RESTRICTED))
Packit 992a25
 		errormsg(SH_DICT,ERROR_exit(1),e_restricted+4);
Packit 992a25
 	while((rval = optget(argv,sh_optcd))) switch(rval)
Packit 992a25
 	{
Packit 992a25
 		case 'L':
Packit 992a25
-			flag = 0;
Packit 992a25
+			flag = false;
Packit 992a25
 			break;
Packit 992a25
 		case 'P':
Packit 992a25
-			flag = 1;
Packit 992a25
+			flag = true;
Packit 992a25
 			break;
Packit 992a25
 		case ':':
Packit 992a25
 			errormsg(SH_DICT,2, "%s", opt_info.arg);
Packit 992a25
@@ -179,14 +274,72 @@ int	b_cd(int argc, char *argv[],Shbltin_
Packit 992a25
 					continue;
Packit 992a25
 #endif /* SHOPT_FS_3D */
Packit 992a25
 		}
Packit 992a25
+		rval = newdirfd = sh_diropenat(shp, shp->pwdfd,
Packit 992a25
+			path_relative(shp,stakptr(PATH_OFFSET)), xattr);
Packit 992a25
+		if(newdirfd >=0)
Packit 992a25
+		{
Packit 992a25
+			/* chdir for directories on HSM/tapeworms may take minutes */
Packit 992a25
+			if(fchdir(newdirfd) >= 0)
Packit 992a25
+			{
Packit 992a25
+				if(shp->pwdfd >= 0)
Packit 992a25
+					sh_close(shp->pwdfd);
Packit 992a25
+				shp->pwdfd=newdirfd;
Packit 992a25
+				goto success;
Packit 992a25
+			}
Packit 992a25
+		}
Packit 992a25
+#ifndef O_SEARCH
Packit 992a25
+		else
Packit 992a25
+		{
Packit 992a25
 		if((rval=chdir(path_relative(shp,stakptr(PATH_OFFSET)))) >= 0)
Packit 992a25
-			goto success;
Packit 992a25
-		if(errno!=ENOENT && saverrno==0)
Packit 992a25
+			{
Packit 992a25
+				if(shp->pwdfd >= 0)
Packit 992a25
+				{
Packit 992a25
+					sh_close(shp->pwdfd);
Packit 992a25
+#ifdef AT_FDCWD
Packit 992a25
+					shp->pwdfd = AT_FDCWD;
Packit 992a25
+#else
Packit 992a25
+					shp->pwdfd = -1;
Packit 992a25
+#endif
Packit 992a25
+				}
Packit 992a25
+			}
Packit 992a25
+		}
Packit 992a25
+#endif
Packit 992a25
+		if(saverrno==0)
Packit 992a25
 			saverrno=errno;
Packit 992a25
+		if(newdirfd >=0)
Packit 992a25
+			sh_close(newdirfd);
Packit 992a25
 	}
Packit 992a25
 	while(cdpath);
Packit 992a25
 	if(rval<0 && *dir=='/' && *(path_relative(shp,stakptr(PATH_OFFSET)))!='/')
Packit 992a25
-		rval = chdir(dir);
Packit 992a25
+	{
Packit 992a25
+		rval = newdirfd = sh_diropenat(shp,
Packit 992a25
+			shp->pwdfd,
Packit 992a25
+			dir, xattr);
Packit 992a25
+		if(newdirfd >=0)
Packit 992a25
+		{
Packit 992a25
+			/* chdir for directories on HSM/tapeworms may take minutes */
Packit 992a25
+			if(fchdir(newdirfd) >= 0)
Packit 992a25
+			{
Packit 992a25
+				if(shp->pwdfd >= 0)
Packit 992a25
+					sh_close(shp->pwdfd);
Packit 992a25
+				shp->pwdfd=newdirfd;
Packit 992a25
+				goto success;
Packit 992a25
+			}
Packit 992a25
+		}
Packit 992a25
+#ifndef O_SEARCH
Packit 992a25
+		else
Packit 992a25
+		{
Packit 992a25
+			if(chdir(dir) >=0)
Packit 992a25
+			{
Packit 992a25
+				if(shp->pwdfd >= 0)
Packit 992a25
+				{
Packit 992a25
+					sh_close(shp->pwdfd);
Packit 992a25
+					shp->pwdfd=-1;
Packit 992a25
+				}
Packit 992a25
+			}
Packit 992a25
+		}
Packit 992a25
+#endif
Packit 992a25
+	}
Packit 992a25
 	/* use absolute chdir() if relative chdir() fails */
Packit 992a25
 	if(rval<0)
Packit 992a25
 	{
Packit 992a25
@@ -213,7 +366,7 @@ success:
Packit 992a25
 	if(*dir != '/')
Packit 992a25
 		return(0);
Packit 992a25
 	nv_putval(opwdnod,oldpwd,NV_RDONLY);
Packit 992a25
-	flag = strlen(dir);
Packit 992a25
+	flag = (strlen(dir)>0)?true:false;
Packit 992a25
 	/* delete trailing '/' */
Packit 992a25
 	while(--flag>0 && dir[flag]=='/')
Packit 992a25
 		dir[flag] = 0;
Packit 992a25
diff -up ksh-20120801/src/cmd/ksh93/include/shell.h.orig ksh-20120801/src/cmd/ksh93/include/shell.h
Packit 992a25
--- ksh-20120801/src/cmd/ksh93/include/shell.h.orig	2012-07-17 22:07:40.000000000 +0200
Packit 992a25
+++ ksh-20120801/src/cmd/ksh93/include/shell.h	2012-10-24 15:42:10.756987230 +0200
Packit 992a25
@@ -145,6 +145,7 @@ struct Shell_s
Packit 992a25
 	unsigned char	trapnote;	/* set when trap/signal is pending */
Packit 992a25
 	char		shcomp;		/* set when runing shcomp */
Packit 992a25
 	short		subshell;	/* set for virtual subshell */
Packit 992a25
+	int		pwdfd;		/* file descriptor for pwd */
Packit 992a25
 #ifdef _SH_PRIVATE
Packit 992a25
 	_SH_PRIVATE
Packit 992a25
 #endif /* _SH_PRIVATE */
Packit 992a25
diff -up ksh-20120801/src/cmd/ksh93/sh/init.c.orig ksh-20120801/src/cmd/ksh93/sh/init.c
Packit 992a25
--- ksh-20120801/src/cmd/ksh93/sh/init.c.orig	2012-05-11 19:19:10.000000000 +0200
Packit 992a25
+++ ksh-20120801/src/cmd/ksh93/sh/init.c	2012-10-24 15:31:59.659485151 +0200
Packit 992a25
@@ -1365,6 +1365,18 @@ Shell_t *sh_init(register int argc,regis
Packit 992a25
 		}
Packit 992a25
 	}
Packit 992a25
 	sh_ioinit(shp);
Packit 992a25
+#ifdef AT_FDCWD
Packit 992a25
+       shp->pwdfd = sh_diropenat(shp, AT_FDCWD, e_dot, false);
Packit 992a25
+#else
Packit 992a25
+       /* Systems without AT_FDCWD/openat() do not use the |dir| argument */
Packit 992a25
+       shp->pwdfd = sh_diropenat(shp, -1, e_dot, false);
Packit 992a25
+#endif
Packit 992a25
+#ifdef O_SEARCH
Packit 992a25
+       /* This should _never_ happen, guranteed by design and goat sacrifice */
Packit 992a25
+       if(shp->pwdfd < 0)
Packit 992a25
+               errormsg(SH_DICT,ERROR_system(1), "Can't obtain directory fd.");
Packit 992a25
+#endif
Packit 992a25
+
Packit 992a25
 	/* initialize signal handling */
Packit 992a25
 	sh_siginit(shp);
Packit 992a25
 	stakinstall(NIL(Stak_t*),nospace);
Packit 992a25
diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.orig ksh-20120801/src/cmd/ksh93/sh/xec.c
Packit 992a25
--- ksh-20120801/src/cmd/ksh93/sh/xec.c.orig	2012-07-23 16:49:32.000000000 +0200
Packit 992a25
+++ ksh-20120801/src/cmd/ksh93/sh/xec.c	2012-10-24 15:35:02.209539671 +0200
Packit 992a25
@@ -1348,8 +1348,12 @@ int sh_exec(register const Shnode_t *t,
Packit 992a25
 						{
Packit 992a25
 							if(!shp->pwd)
Packit 992a25
 								path_pwd(shp,0);
Packit 992a25
-							if(shp->pwd)
Packit 992a25
-								stat(".",&statb);
Packit 992a25
+#ifndef O_SEARCH
Packit 992a25
+							else if (shp->pwdfd>=0)
Packit 992a25
+								fstat(shp->pwdfd,&statb);
Packit 992a25
+							else if (shp->pwd)
Packit 992a25
+								stat(e_dot,&statb);
Packit 992a25
+#endif
Packit 992a25
 							sfsync(NULL);
Packit 992a25
 							share = sfset(sfstdin,SF_SHARE,0);
Packit 992a25
 							sh_onstate(SH_STOPOK);
Packit 992a25
@@ -1428,14 +1432,32 @@ int sh_exec(register const Shnode_t *t,
Packit 992a25
 						sh_offstate(SH_NOFORK);
Packit 992a25
 					if(!(nv_isattr(np,BLT_ENV)))
Packit 992a25
 					{
Packit 992a25
-						if(shp->pwd)
Packit 992a25
+#ifdef O_SEARCH
Packit 992a25
+						while((fchdir(shp->pwdfd) < 0) && errno==EINTR)
Packit 992a25
+							errno = 0;
Packit 992a25
+#else
Packit 992a25
+						if(shp->pwd || (shp->pwdfd >= 0))
Packit 992a25
 						{
Packit 992a25
 							struct stat stata;
Packit 992a25
 							stat(".",&stata);
Packit 992a25
 							/* restore directory changed */
Packit 992a25
 							if(statb.st_ino!=stata.st_ino || statb.st_dev!=stata.st_dev)
Packit 992a25
-								chdir(shp->pwd);
Packit 992a25
+							{
Packit 992a25
+								/* chdir for directories on HSM/tapeworms may take minutes */
Packit 992a25
+								int err=errno;
Packit 992a25
+								if(shp->pwdfd >= 0)
Packit 992a25
+								{
Packit 992a25
+									 while((fchdir(shp->pwdfd) < 0) && errno==EINTR)
Packit 992a25
+										errno = err;
Packit 992a25
+								}
Packit 992a25
+								else
Packit 992a25
+								{
Packit 992a25
+									 while((chdir(shp->pwd) < 0) && errno==EINTR)
Packit 992a25
+										errno = err;
Packit 992a25
+								}
Packit 992a25
+							}
Packit 992a25
 						}
Packit 992a25
+#endif /* O_SEARCH */
Packit 992a25
 						sh_offstate(SH_STOPOK);
Packit 992a25
 						if(share&SF_SHARE)
Packit 992a25
 							sfset(sfstdin,SF_PUBLIC|SF_SHARE,1);
Packit 992a25
diff -up ksh-20120801/src/lib/libast/features/common.orig ksh-20120801/src/lib/libast/features/common
Packit 992a25
--- ksh-20120801/src/lib/libast/features/common.orig	2011-12-12 20:55:33.000000000 +0100
Packit 992a25
+++ ksh-20120801/src/lib/libast/features/common	2012-10-24 15:54:35.433885131 +0200
Packit 992a25
@@ -463,6 +463,66 @@ typ uintptr_t stdint.h inttypes.h no{
Packit 992a25
 	typedef unsigned _ast_int4_t uintptr_t;
Packit 992a25
 	#endif
Packit 992a25
 }end
Packit 992a25
+typ _Bool = uint8_t
Packit 992a25
+cat{
Packit 992a25
+	#if defined(_STDC_C99) || __STDC_VERSION__ >= 199901L
Packit 992a25
+	#include <stdbool.h>
Packit 992a25
+	#else
Packit 992a25
+	#define bool	_Bool
Packit 992a25
+	#define false	0
Packit 992a25
+	#define true	1
Packit 992a25
+	#endif
Packit 992a25
+}end
Packit 992a25
+tst key __thread -lpthread note{ __thread keyword exists and works with -lpthread }end execute{
Packit 992a25
+	#include	<pthread.h>
Packit 992a25
+	
Packit 992a25
+	#define INITIAL		1
Packit 992a25
+	#define LOOP		100
Packit 992a25
+	
Packit 992a25
+	static __thread int	specific = INITIAL;
Packit 992a25
+	static int		global = 0;
Packit 992a25
+	
Packit 992a25
+	static void* worker(void* arg)
Packit 992a25
+	{
Packit 992a25
+		int	k;
Packit 992a25
+		int	v;
Packit 992a25
+		v = (int)(arg - 0);
Packit 992a25
+		for (k = 0; k < LOOP; ++k)
Packit 992a25
+		{	
Packit 992a25
+			specific += v;
Packit 992a25
+			usleep(1);
Packit 992a25
+		}
Packit 992a25
+		if (specific != (INITIAL + LOOP * v)) 
Packit 992a25
+			global = 1;
Packit 992a25
+		return 0;
Packit 992a25
+	}
Packit 992a25
+	int main()
Packit 992a25
+	{
Packit 992a25
+		pthread_t	th[2];
Packit 992a25
+	
Packit 992a25
+		if (pthread_create(&th[0], 0, worker, (void*)0 + 5) ||
Packit 992a25
+		    pthread_create(&th[1], 0, worker, (void*)0 + 7))
Packit 992a25
+		{
Packit 992a25
+			NOTE("pthread_create failed");
Packit 992a25
+			return 1;
Packit 992a25
+		}
Packit 992a25
+		pthread_join(th[0], 0);
Packit 992a25
+		pthread_join(th[1], 0);
Packit 992a25
+		if (global)
Packit 992a25
+		{
Packit 992a25
+			NOTE("__thread variable not thread specific");
Packit 992a25
+			return 1;
Packit 992a25
+		}
Packit 992a25
+		if (specific != INITIAL)
Packit 992a25
+		{
Packit 992a25
+			NOTE("main __thread variable changed by another thread");
Packit 992a25
+			return 1;
Packit 992a25
+		}
Packit 992a25
+		return 0;
Packit 992a25
+	}
Packit 992a25
+}end no{
Packit 992a25
+	#define __thread		/* __thread keyword does not exist or does not work with -lpthread */
Packit 992a25
+}end
Packit 992a25
 
Packit 992a25
 tst	- -DTRY=1 - -DTRY=1 -Dvoid=char - -DTRY=2 - -DTRY=3 - -DTRY=4 output{
Packit 992a25
 	#if _STD_ && _hdr_stdarg