~ubuntu-branches/ubuntu/natty/wine1.3/natty

« back to all changes in this revision

Viewing changes to server/procfs.c

  • Committer: Bazaar Package Importer
  • Author(s): Scott Ritchie
  • Date: 2011-03-09 05:50:55 UTC
  • Revision ID: james.westby@ubuntu.com-20110309055055-oc6dml4hruy8wa4r
Tags: upstream-1.3.15
ImportĀ upstreamĀ versionĀ 1.3.15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Server-side /proc support for Solaris
 
3
 *
 
4
 * Copyright (C) 2007 Alexandre Julliard
 
5
 *
 
6
 * This library is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU Lesser General Public
 
8
 * License as published by the Free Software Foundation; either
 
9
 * version 2.1 of the License, or (at your option) any later version.
 
10
 *
 
11
 * This library is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
 * Lesser General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU Lesser General Public
 
17
 * License along with this library; if not, write to the Free Software
 
18
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 
19
 */
 
20
 
 
21
#include "config.h"
 
22
 
 
23
#include <assert.h>
 
24
#include <errno.h>
 
25
#include <fcntl.h>
 
26
#include <stdio.h>
 
27
#include <signal.h>
 
28
#include <stdarg.h>
 
29
#include <sys/types.h>
 
30
#include <unistd.h>
 
31
 
 
32
#include "ntstatus.h"
 
33
#define WIN32_NO_STATUS
 
34
#include "winternl.h"
 
35
 
 
36
#include "file.h"
 
37
#include "process.h"
 
38
#include "thread.h"
 
39
 
 
40
#ifdef USE_PROCFS
 
41
 
 
42
/* procfs doesn't support large files */
 
43
# undef _FILE_OFFSET_BITS
 
44
# define _FILE_OFFSET_BITS 32
 
45
#include <procfs.h>
 
46
 
 
47
static int open_proc_as( struct process *process, int flags )
 
48
{
 
49
    char buffer[32];
 
50
    int fd;
 
51
 
 
52
    if (process->unix_pid == -1)
 
53
    {
 
54
        set_error( STATUS_ACCESS_DENIED );
 
55
        return -1;
 
56
    }
 
57
 
 
58
    sprintf( buffer, "/proc/%u/as", process->unix_pid );
 
59
    if ((fd = open( buffer, flags )) == -1)
 
60
    {
 
61
        if (errno == ENOENT)  /* probably got killed */
 
62
        {
 
63
            process->unix_pid = -1;
 
64
            set_error( STATUS_ACCESS_DENIED );
 
65
        }
 
66
        else file_set_error();
 
67
    }
 
68
    return fd;
 
69
}
 
70
 
 
71
static int open_proc_lwpctl( struct thread *thread )
 
72
{
 
73
    char buffer[48];
 
74
    int fd;
 
75
 
 
76
    if (thread->unix_pid == -1) return -1;
 
77
 
 
78
    sprintf( buffer, "/proc/%u/lwp/%u/lwpctl", thread->unix_pid, thread->unix_tid );
 
79
    if ((fd = open( buffer, O_WRONLY )) == -1)
 
80
    {
 
81
        if (errno == ENOENT)  /* probably got killed */
 
82
            thread->unix_pid = thread->unix_tid = -1;
 
83
        else
 
84
            file_set_error();
 
85
    }
 
86
    return fd;
 
87
}
 
88
 
 
89
 
 
90
/* handle a SIGCHLD signal */
 
91
void sigchld_callback(void)
 
92
{
 
93
    assert( 0 );  /* should only be called when using ptrace */
 
94
}
 
95
 
 
96
/* initialize the process tracing mechanism */
 
97
void init_tracing_mechanism(void)
 
98
{
 
99
    /* no initialization needed */
 
100
}
 
101
 
 
102
/* initialize the per-process tracing mechanism */
 
103
void init_process_tracing( struct process *process )
 
104
{
 
105
    /* setup is done on-demand */
 
106
}
 
107
 
 
108
/* terminate the per-process tracing mechanism */
 
109
void finish_process_tracing( struct process *process )
 
110
{
 
111
}
 
112
 
 
113
/* send a Unix signal to a specific thread */
 
114
int send_thread_signal( struct thread *thread, int sig )
 
115
{
 
116
    int fd = open_proc_lwpctl( thread );
 
117
    long kill[2];
 
118
    ssize_t ret;
 
119
 
 
120
    if (fd == -1) return 0;
 
121
 
 
122
    kill[0] = PCKILL;
 
123
    kill[1] = sig;
 
124
    ret = write( fd, kill, sizeof(kill) );
 
125
    close( fd );
 
126
    return (ret == sizeof(kill));
 
127
}
 
128
 
 
129
/* read data from a process memory space */
 
130
int read_process_memory( struct process *process, client_ptr_t ptr, size_t size, char *dest )
 
131
{
 
132
    ssize_t ret;
 
133
    int fd;
 
134
 
 
135
    if ((off_t)ptr != ptr)
 
136
    {
 
137
        set_error( STATUS_ACCESS_DENIED );
 
138
        return 0;
 
139
    }
 
140
 
 
141
    if ((fd = open_proc_as( process, O_RDONLY )) == -1) return 0;
 
142
 
 
143
    ret = pread( fd, dest, size, (off_t)ptr );
 
144
    close( fd );
 
145
    if (ret == size) return 1;
 
146
 
 
147
    if (ret == -1) file_set_error();
 
148
    else set_error( STATUS_ACCESS_VIOLATION );
 
149
    return 0;
 
150
}
 
151
 
 
152
/* write data to a process memory space */
 
153
int write_process_memory( struct process *process, client_ptr_t ptr, size_t size, const char *src )
 
154
{
 
155
    ssize_t ret;
 
156
    int fd;
 
157
 
 
158
    if ((off_t)ptr != ptr)
 
159
    {
 
160
        set_error( STATUS_ACCESS_DENIED );
 
161
        return 0;
 
162
    }
 
163
 
 
164
    if ((fd = open_proc_as( process, O_WRONLY )) == -1) return 0;
 
165
 
 
166
    ret = pwrite( fd, src, size, (off_t)ptr );
 
167
    close( fd );
 
168
    if (ret == size) return 1;
 
169
 
 
170
    if (ret == -1) file_set_error();
 
171
    else set_error( STATUS_ACCESS_VIOLATION );
 
172
    return 0;
 
173
}
 
174
 
 
175
/* retrieve an LDT selector entry */
 
176
void get_selector_entry( struct thread *thread, int entry, unsigned int *base,
 
177
                         unsigned int *limit, unsigned char *flags )
 
178
{
 
179
    ssize_t ret;
 
180
    off_t pos = thread->process->ldt_copy;
 
181
    int fd;
 
182
 
 
183
    if (!pos)
 
184
    {
 
185
        set_error( STATUS_ACCESS_DENIED );
 
186
        return;
 
187
    }
 
188
    if ((fd = open_proc_as( thread->process, O_RDONLY )) == -1) return;
 
189
 
 
190
    ret = pread( fd, base, sizeof(*base), pos + entry*sizeof(int) );
 
191
    if (ret != sizeof(*base)) goto error;
 
192
    ret = pread( fd, limit, sizeof(*limit), pos + (8192 + entry)*sizeof(int) );
 
193
    if (ret != sizeof(*limit)) goto error;
 
194
    ret = pread( fd, flags, sizeof(*flags), pos + 2*8192*sizeof(int) + entry );
 
195
    if (ret != sizeof(*flags)) goto error;
 
196
    close( fd );
 
197
    return;
 
198
 
 
199
error:
 
200
    if (ret == -1) file_set_error();
 
201
    else set_error( STATUS_ACCESS_VIOLATION );
 
202
    close( fd );
 
203
}
 
204
 
 
205
/* retrieve the thread registers */
 
206
void get_thread_context( struct thread *thread, context_t *context, unsigned int flags )
 
207
{
 
208
    /* FIXME: get debug registers */
 
209
}
 
210
 
 
211
/* set the thread registers */
 
212
void set_thread_context( struct thread *thread, const context_t *context, unsigned int flags )
 
213
{
 
214
    /* FIXME: set debug registers */
 
215
}
 
216
 
 
217
#endif /* USE_PROCFS */