hurd: Handle "pid" magical lookup retry

* hurd/lookup-retry: Include <unistd.h>.
	(__hurd_file_name_lookup_retry): Keep a ref on last result in `lastdir'.
	Release it on return.  Handle "pid" magical lookup retry.
This commit is contained in:
Justus Winter 2018-12-28 22:31:01 +01:00 committed by Samuel Thibault
parent 989182c40a
commit 065957a370
2 changed files with 71 additions and 13 deletions

View File

@ -1,3 +1,9 @@
2018-12-28 Justus Winter <4winter@informatik.uni-hamburg.de>
* hurd/lookup-retry: Include <unistd.h>.
(__hurd_file_name_lookup_retry): Keep a ref on last result in `lastdir'.
Release it on return. Handle "pid" magical lookup retry.
2018-12-28 Rafal Luzynski <digitalfreak@lingonborough.com> 2018-12-28 Rafal Luzynski <digitalfreak@lingonborough.com>
[BZ #10496] [BZ #10496]

View File

@ -25,6 +25,7 @@
#include <string.h> #include <string.h>
#include <_itoa.h> #include <_itoa.h>
#include <eloop-threshold.h> #include <eloop-threshold.h>
#include <unistd.h>
/* Translate the error from dir_lookup into the error the user sees. */ /* Translate the error from dir_lookup into the error the user sees. */
static inline error_t static inline error_t
@ -59,6 +60,7 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port)
error_t err; error_t err;
char *file_name; char *file_name;
int nloops; int nloops;
file_t lastdir = MACH_PORT_NULL;
error_t lookup_op (file_t startdir) error_t lookup_op (file_t startdir)
{ {
@ -107,14 +109,15 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port)
{ {
case FS_RETRY_REAUTH: case FS_RETRY_REAUTH:
if (err = reauthenticate (*result)) if (err = reauthenticate (*result))
return err; goto out;
/* Fall through. */ /* Fall through. */
case FS_RETRY_NORMAL: case FS_RETRY_NORMAL:
if (nloops++ >= __eloop_threshold ()) if (nloops++ >= __eloop_threshold ())
{ {
__mach_port_deallocate (__mach_task_self (), *result); __mach_port_deallocate (__mach_task_self (), *result);
return ELOOP; err = ELOOP;
goto out;
} }
/* An empty RETRYNAME indicates we have the final port. */ /* An empty RETRYNAME indicates we have the final port. */
@ -180,7 +183,7 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port)
if (err) if (err)
__mach_port_deallocate (__mach_task_self (), *result); __mach_port_deallocate (__mach_task_self (), *result);
return err; goto out;
} }
startdir = *result; startdir = *result;
@ -195,7 +198,10 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port)
if (*result != MACH_PORT_NULL) if (*result != MACH_PORT_NULL)
__mach_port_deallocate (__mach_task_self (), *result); __mach_port_deallocate (__mach_task_self (), *result);
if (nloops++ >= __eloop_threshold ()) if (nloops++ >= __eloop_threshold ())
return ELOOP; {
err = ELOOP;
goto out;
}
file_name = &retryname[1]; file_name = &retryname[1];
break; break;
@ -214,7 +220,8 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port)
(*end != '/' && *end != '\0')) (*end != '/' && *end != '\0'))
{ {
errno = save; errno = save;
return ENOENT; err = ENOENT;
goto out;
} }
if (! get_dtable_port) if (! get_dtable_port)
err = EGRATUITOUS; err = EGRATUITOUS;
@ -232,9 +239,12 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port)
} }
errno = save; errno = save;
if (err) if (err)
return err; goto out;
if (*end == '\0') if (*end == '\0')
return 0; {
err = 0;
goto out;
}
else else
{ {
/* Do a normal retry on the remaining components. */ /* Do a normal retry on the remaining components. */
@ -261,9 +271,12 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port)
if (err = __host_info (__mach_host_self (), HOST_BASIC_INFO, if (err = __host_info (__mach_host_self (), HOST_BASIC_INFO,
(integer_t *) &hostinfo, (integer_t *) &hostinfo,
&hostinfocnt)) &hostinfocnt))
return err; goto out;
if (hostinfocnt != HOST_BASIC_INFO_COUNT) if (hostinfocnt != HOST_BASIC_INFO_COUNT)
return EGRATUITOUS; {
err = EGRATUITOUS;
goto out;
}
p = _itoa (hostinfo.cpu_subtype, &retryname[8], 10, 0); p = _itoa (hostinfo.cpu_subtype, &retryname[8], 10, 0);
*--p = '/'; *--p = '/';
p = _itoa (hostinfo.cpu_type, &retryname[8], 10, 0); p = _itoa (hostinfo.cpu_type, &retryname[8], 10, 0);
@ -299,10 +312,11 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port)
} }
case '\0': case '\0':
return opentty (result); err = opentty (result);
goto out;
case '/': case '/':
if (err = opentty (&startdir)) if (err = opentty (&startdir))
return err; goto out;
strcpy (retryname, &retryname[4]); strcpy (retryname, &retryname[4]);
break; break;
default: default:
@ -312,14 +326,48 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port)
goto bad_magic; goto bad_magic;
break; break;
case 'p':
if (retryname[1] == 'i' && retryname[2] == 'd' &&
(retryname[3] == '/' || retryname[3] == 0))
{
char *p, buf[1024]; /* XXX */
size_t len;
p = _itoa (__getpid (), &buf[sizeof buf], 10, 0);
len = &buf[sizeof buf] - p;
memcpy (buf, p, len);
strcpy (buf + len, &retryname[3]);
strcpy (retryname, buf);
/* Do a normal retry on the remaining components. */
__mach_port_mod_refs (__mach_task_self (), lastdir,
MACH_PORT_RIGHT_SEND, 1);
startdir = lastdir;
file_name = retryname;
}
else
goto bad_magic;
break;
default: default:
bad_magic: bad_magic:
return EGRATUITOUS; err = EGRATUITOUS;
goto out;
} }
break; break;
default: default:
return EGRATUITOUS; err = EGRATUITOUS;
goto out;
}
if (MACH_PORT_VALID (*result) && *result != lastdir)
{
if (MACH_PORT_VALID (lastdir))
__mach_port_deallocate (__mach_task_self (), lastdir);
lastdir = *result;
__mach_port_mod_refs (__mach_task_self (), lastdir,
MACH_PORT_RIGHT_SEND, 1);
} }
if (startdir != MACH_PORT_NULL) if (startdir != MACH_PORT_NULL)
@ -332,6 +380,10 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port)
err = (*use_init_port) (dirport, &lookup_op); err = (*use_init_port) (dirport, &lookup_op);
} while (! err); } while (! err);
out:
if (MACH_PORT_VALID (lastdir))
__mach_port_deallocate (__mach_task_self (), lastdir);
return err; return err;
} }
weak_alias (__hurd_file_name_lookup_retry, hurd_file_name_lookup_retry) weak_alias (__hurd_file_name_lookup_retry, hurd_file_name_lookup_retry)