diff options
author | Eamon Walsh <ewalsh@tycho.nsa.gov> | 2008-03-04 02:02:54 -0500 |
---|---|---|
committer | Eamon Walsh <ewalsh@moss-charon.epoch.ncsc.mil> | 2008-03-04 02:17:13 -0500 |
commit | 7f74ba1b774e56c4c9a29ce5aa7a2f6b8f395e33 (patch) | |
tree | 91acbe0600accba380c80564ae8b60fcf1ef60ab /dix | |
parent | 1bda57a41ea3bb3a624a5e75f421160ac98a0804 (diff) |
dix: Convert selection list to a linked list.
Fixes a bug where pointers were being invalidated after a realloc.
(cherry picked from commit 72f2197545e734cd0aa785d05a57b2fc0351a763)
Diffstat (limited to 'dix')
-rw-r--r-- | dix/selection.c | 48 |
1 files changed, 22 insertions, 26 deletions
diff --git a/dix/selection.c b/dix/selection.c index 52b1611c5..11a174ee6 100644 --- a/dix/selection.c +++ b/dix/selection.c @@ -66,24 +66,22 @@ SOFTWARE. *****************************************************************/ _X_EXPORT Selection *CurrentSelections; -static int NumCurrentSelections; CallbackListPtr SelectionCallback; _X_EXPORT int dixLookupSelection(Selection **result, Atom selectionName, ClientPtr client, Mask access_mode) { - Selection *pSel = NULL; - int i, rc = BadMatch; + Selection *pSel; + int rc = BadMatch; client->errorValue = selectionName; - for (i = 0; i < NumCurrentSelections; i++) - if (CurrentSelections[i].selection == selectionName) { - pSel = CurrentSelections + i; - rc = XaceHookSelectionAccess(client, &pSel, access_mode); + for (pSel = CurrentSelections; pSel; pSel = pSel->next) + if (pSel->selection == selectionName) break; - } + if (pSel) + rc = XaceHookSelectionAccess(client, &pSel, access_mode); *result = pSel; return rc; } @@ -91,14 +89,17 @@ dixLookupSelection(Selection **result, Atom selectionName, void InitSelections(void) { - Selection *pSel = CurrentSelections; + Selection *pSel, *pNextSel; - for (; pSel - CurrentSelections < NumCurrentSelections; pSel++) + pSel = CurrentSelections; + while (pSel) { + pNextSel = pSel->next; dixFreePrivates(pSel->devPrivates); + xfree(pSel); + pSel = pNextSel; + } - xfree(CurrentSelections); CurrentSelections = NULL; - NumCurrentSelections = 0; } static _X_INLINE void @@ -112,9 +113,9 @@ CallSelectionCallback(Selection *pSel, ClientPtr client, void DeleteWindowFromAnySelections(WindowPtr pWin) { - Selection *pSel = CurrentSelections; + Selection *pSel; - for (; pSel - CurrentSelections < NumCurrentSelections; pSel++) + for (pSel = CurrentSelections; pSel; pSel = pSel->next) if (pSel->pWin == pWin) { CallSelectionCallback(pSel, NULL, SelectionWindowDestroy); @@ -127,9 +128,9 @@ DeleteWindowFromAnySelections(WindowPtr pWin) void DeleteClientFromAnySelections(ClientPtr client) { - Selection *pSel = CurrentSelections; + Selection *pSel; - for (; pSel - CurrentSelections < NumCurrentSelections; pSel++) + for (pSel = CurrentSelections; pSel; pSel = pSel->next) if (pSel->client == client) { CallSelectionCallback(pSel, NULL, SelectionClientClose); @@ -197,23 +198,18 @@ ProcSetSelectionOwner(ClientPtr client) /* * It doesn't exist, so add it... */ - int size = (NumCurrentSelections + 1) * sizeof(Selection); - CurrentSelections = xrealloc(CurrentSelections, size); - if (!CurrentSelections) { - NumCurrentSelections = 0; + pSel = xalloc(sizeof(Selection)); + if (!pSel) return BadAlloc; - } - pSel = CurrentSelections + NumCurrentSelections; + pSel->selection = stuff->selection; pSel->devPrivates = NULL; /* security creation/labeling check */ (void)XaceHookSelectionAccess(client, &pSel, DixCreateAccess); - pSel->next = NULL; - if (NumCurrentSelections > 0) - CurrentSelections[NumCurrentSelections - 1].next = pSel; - NumCurrentSelections++; + pSel->next = CurrentSelections; + CurrentSelections = pSel; } else return rc; |