iconv: Suppress array out of bounds warning.
[platform/upstream/glibc.git] / nptl / pthread_setattr_default_np.c
1 /* Set the default attributes to be used by pthread_create in the process.
2    Copyright (C) 2013-2015 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <http://www.gnu.org/licenses/>.  */
18
19 #include <errno.h>
20 #include <stdlib.h>
21 #include <pthreadP.h>
22 #include <assert.h>
23 #include <string.h>
24 #include <check-cpuset.h>
25
26
27 int
28 pthread_setattr_default_np (const pthread_attr_t *in)
29 {
30   const struct pthread_attr *real_in;
31   struct pthread_attr attrs;
32   int ret;
33
34   assert (sizeof (*in) >= sizeof (struct pthread_attr));
35   real_in = (struct pthread_attr *) in;
36
37   /* Catch invalid values.  */
38   int policy = real_in->schedpolicy;
39   ret = check_sched_policy_attr (policy);
40   if (ret)
41     return ret;
42
43   const struct sched_param *param = &real_in->schedparam;
44   if (param->sched_priority > 0)
45     {
46       ret = check_sched_priority_attr (param->sched_priority, policy);
47       if (ret)
48         return ret;
49     }
50
51   ret = check_cpuset_attr (real_in->cpuset, real_in->cpusetsize);
52   if (ret)
53     return ret;
54
55   /* stacksize == 0 is fine.  It means that we don't change the current
56      value.  */
57   if (real_in->stacksize != 0)
58     {
59       ret = check_stacksize_attr (real_in->stacksize);
60       if (ret)
61         return ret;
62     }
63
64   /* Having a default stack address is wrong.  */
65   if (real_in->flags & ATTR_FLAG_STACKADDR)
66     return EINVAL;
67
68   attrs = *real_in;
69
70   /* Now take the lock because we start writing into
71      __default_pthread_attr.  */
72   lll_lock (__default_pthread_attr_lock, LLL_PRIVATE);
73
74   /* Free the cpuset if the input is 0.  Otherwise copy in the cpuset
75      contents.  */
76   size_t cpusetsize = attrs.cpusetsize;
77   if (cpusetsize == 0)
78     {
79       free (__default_pthread_attr.cpuset);
80       __default_pthread_attr.cpuset = NULL;
81     }
82   else if (cpusetsize == __default_pthread_attr.cpusetsize)
83     {
84       attrs.cpuset = __default_pthread_attr.cpuset;
85       memcpy (attrs.cpuset, real_in->cpuset, cpusetsize);
86     }
87   else
88     {
89       /* This may look wrong at first sight, but it isn't.  We're freeing
90          __default_pthread_attr.cpuset and allocating to attrs.cpuset because
91          we'll copy over all of attr to __default_pthread_attr later.  */
92       cpu_set_t *newp = realloc (__default_pthread_attr.cpuset,
93                                  cpusetsize);
94
95       if (newp == NULL)
96         {
97           ret = ENOMEM;
98           goto out;
99         }
100
101       attrs.cpuset = newp;
102       memcpy (attrs.cpuset, real_in->cpuset, cpusetsize);
103     }
104
105   /* We don't want to accidentally set the default stacksize to zero.  */
106   if (attrs.stacksize == 0)
107     attrs.stacksize = __default_pthread_attr.stacksize;
108   __default_pthread_attr = attrs;
109
110  out:
111   lll_unlock (__default_pthread_attr_lock, LLL_PRIVATE);
112   return ret;
113 }