##// END OF EJS Templates
phases: emit phases to pushkey protocol in deterministic order...
phases: emit phases to pushkey protocol in deterministic order An upcoming test will report exact bytes sent over the wire protocol. Without this change, the ordering of phases listkey data is non-deterministic.

File last commit:

r31678:1ed57a7d default
r32000:511a6266 default
Show More
osutil.c
1328 lines | 30.1 KiB | text/x-c | CLexer
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396 /*
osutil.c - native operating system services
Copyright 2007 Matt Mackall and others
This software may be used and distributed according to the terms of
the GNU General Public License, incorporated herein by reference.
*/
Bryan O'Sullivan
osutil: use fdopendir instead of dirfd
r5463 #define _ATFILE_SOURCE
Alexis S. L. Carvalho
osutil.c: include Python.h before the other headers...
r5397 #include <Python.h>
Bryan O'Sullivan
Windows: improve performance via buffered I/O...
r8330 #include <fcntl.h>
#include <stdio.h>
Yuya Nishihara
osutil: implement recvmsg() of SCM_RIGHTS for chg command server...
r27473 #include <stdlib.h>
Bryan O'Sullivan
Windows: improve performance via buffered I/O...
r8330 #include <string.h>
Matt Mackall
osutil: emulate os.listdir's OSError for long names (issue2898)
r14873 #include <errno.h>
Bryan O'Sullivan
Windows: improve performance via buffered I/O...
r8330
Petr Kodl
osutil: implementation for Win32...
r7056 #ifdef _WIN32
Matt Mackall
many, many trivial check-code fixups
r10282 #include <windows.h>
#include <io.h>
Petr Kodl
osutil: implementation for Win32...
r7056 #else
Matt Mackall
many, many trivial check-code fixups
r10282 #include <dirent.h>
Yuya Nishihara
osutil: implement recvmsg() of SCM_RIGHTS for chg command server...
r27473 #include <sys/socket.h>
Matt Mackall
many, many trivial check-code fixups
r10282 #include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
Jun Wu
statfs: change Linux feature detection...
r31622 #ifdef HAVE_LINUX_STATFS
Jun Wu
osutil: add a C function getting filesystem type...
r31563 #include <linux/magic.h>
Jun Wu
statfs: change Linux feature detection...
r31622 #include <sys/vfs.h>
Jun Wu
osutil: add a C function getting filesystem type...
r31563 #endif
Jun Wu
osutil: report fstype for BSD and OSX
r31597 #ifdef HAVE_BSD_STATFS
Jun Wu
osutil: add a C function getting filesystem type...
r31563 #include <sys/mount.h>
#include <sys/param.h>
#endif
Petr Kodl
osutil: implementation for Win32...
r7056 #endif
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396
Siddharth Agarwal
osutil: use getdirentriesattr on OS X if possible...
r24461 #ifdef __APPLE__
#include <sys/attr.h>
#include <sys/vnode.h>
#endif
Renato Cunha
osutil.c: Support for py3k added....
r11359 #include "util.h"
Sebastien Binet
osutil: fix compilation with -ansi
r9353 /* some platforms lack the PATH_MAX definition (eg. GNU/Hurd) */
Arne Babenhauserheide
Some platforms lack the PATH_MAX definition (eg. GNU/Hurd)....
r8722 #ifndef PATH_MAX
#define PATH_MAX 4096
#endif
Petr Kodl
osutil: implementation for Win32...
r7056 #ifdef _WIN32
/*
stat struct compatible with hg expectations
Mercurial only uses st_mode, st_size and st_mtime
the rest is kept to minimize changes between implementations
*/
struct hg_stat {
int st_dev;
int st_mode;
int st_nlink;
__int64 st_size;
int st_mtime;
int st_ctime;
};
struct listdir_stat {
PyObject_HEAD
struct hg_stat st;
};
#else
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396 struct listdir_stat {
Matt Mackall
osutil: cleanups...
r5421 PyObject_HEAD
struct stat st;
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396 };
Petr Kodl
osutil: implementation for Win32...
r7056 #endif
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396
Gregory Szorc
osutil: use PyLongObject on Python 3 for listdir_slot...
r30111 #ifdef IS_PY3K
#define listdir_slot(name) \
static PyObject *listdir_stat_##name(PyObject *self, void *x) \
{ \
return PyLong_FromLong(((struct listdir_stat *)self)->st.name); \
}
#else
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396 #define listdir_slot(name) \
Thomas Arendsen Hein
Some additional space/tab cleanups
r7190 static PyObject *listdir_stat_##name(PyObject *self, void *x) \
{ \
return PyInt_FromLong(((struct listdir_stat *)self)->st.name); \
}
Gregory Szorc
osutil: use PyLongObject on Python 3 for listdir_slot...
r30111 #endif
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396
Bryan O'Sullivan
Fix build error with Sun C compiler.
r5431 listdir_slot(st_dev)
listdir_slot(st_mode)
listdir_slot(st_nlink)
Petr Kodl
osutil: implementation for Win32...
r7056 #ifdef _WIN32
static PyObject *listdir_stat_st_size(PyObject *self, void *x)
{
return PyLong_FromLongLong(
(PY_LONG_LONG)((struct listdir_stat *)self)->st.st_size);
}
#else
Bryan O'Sullivan
Fix build error with Sun C compiler.
r5431 listdir_slot(st_size)
Petr Kodl
osutil: implementation for Win32...
r7056 #endif
Bryan O'Sullivan
Fix build error with Sun C compiler.
r5431 listdir_slot(st_mtime)
listdir_slot(st_ctime)
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396
static struct PyGetSetDef listdir_stat_getsets[] = {
Matt Mackall
osutil: cleanups...
r5421 {"st_dev", listdir_stat_st_dev, 0, 0, 0},
{"st_mode", listdir_stat_st_mode, 0, 0, 0},
{"st_nlink", listdir_stat_st_nlink, 0, 0, 0},
{"st_size", listdir_stat_st_size, 0, 0, 0},
{"st_mtime", listdir_stat_st_mtime, 0, 0, 0},
{"st_ctime", listdir_stat_st_ctime, 0, 0, 0},
{0, 0, 0, 0, 0}
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396 };
static PyObject *listdir_stat_new(PyTypeObject *t, PyObject *a, PyObject *k)
{
Matt Mackall
osutil: cleanups...
r5421 return t->tp_alloc(t, 0);
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396 }
static void listdir_stat_dealloc(PyObject *o)
{
Matt Mackall
osutil: cleanups...
r5421 o->ob_type->tp_free(o);
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396 }
static PyTypeObject listdir_stat_type = {
Renato Cunha
osutil.c: Support for py3k added....
r11359 PyVarObject_HEAD_INIT(NULL, 0)
Matt Mackall
osutil: cleanups...
r5421 "osutil.stat", /*tp_name*/
sizeof(struct listdir_stat), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)listdir_stat_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
"stat objects", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
listdir_stat_getsets, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
listdir_stat_new, /* tp_new */
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396 };
Petr Kodl
osutil: implementation for Win32...
r7056 #ifdef _WIN32
static int to_python_time(const FILETIME *tm)
{
/* number of seconds between epoch and January 1 1601 */
const __int64 a0 = (__int64)134774L * (__int64)24L * (__int64)3600L;
/* conversion factor from 100ns to 1s */
const __int64 a1 = 10000000;
/* explicit (int) cast to suspend compiler warnings */
return (int)((((__int64)tm->dwHighDateTime << 32)
+ tm->dwLowDateTime) / a1 - a0);
}
static PyObject *make_item(const WIN32_FIND_DATAA *fd, int wantstat)
{
PyObject *py_st;
struct hg_stat *stp;
int kind = (fd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
? _S_IFDIR : _S_IFREG;
if (!wantstat)
return Py_BuildValue("si", fd->cFileName, kind);
py_st = PyObject_CallObject((PyObject *)&listdir_stat_type, NULL);
if (!py_st)
return NULL;
stp = &((struct listdir_stat *)py_st)->st;
/*
use kind as st_mode
rwx bits on Win32 are meaningless
and Hg does not use them anyway
*/
stp->st_mode = kind;
stp->st_mtime = to_python_time(&fd->ftLastWriteTime);
stp->st_ctime = to_python_time(&fd->ftCreationTime);
if (kind == _S_IFREG)
Matt Mackall
many, many trivial check-code fixups
r10282 stp->st_size = ((__int64)fd->nFileSizeHigh << 32)
Petr Kodl
osutil: implementation for Win32...
r7056 + fd->nFileSizeLow;
return Py_BuildValue("siN", fd->cFileName,
kind, py_st);
}
Benoit Boissinot
osutil.c: refactor argument parsing, allow skip=None being passed
r7098 static PyObject *_listdir(char *path, int plen, int wantstat, char *skip)
Petr Kodl
osutil: implementation for Win32...
r7056 {
PyObject *rval = NULL; /* initialize - return value */
PyObject *list;
HANDLE fh;
WIN32_FIND_DATAA fd;
Benoit Boissinot
osutil.c: refactor argument parsing, allow skip=None being passed
r7098 char *pattern;
Petr Kodl
osutil: implementation for Win32...
r7056
/* build the path + \* pattern string */
Gregory Szorc
osutil: use Python memory allocator in _listdir...
r31468 pattern = PyMem_Malloc(plen + 3); /* path + \* + \0 */
Petr Kodl
osutil: implementation for Win32...
r7056 if (!pattern) {
PyErr_NoMemory();
Benoit Boissinot
osutil.c: refactor argument parsing, allow skip=None being passed
r7098 goto error_nomem;
Petr Kodl
osutil: implementation for Win32...
r7056 }
Augie Fackler
osutil: stop using strcpy...
r28593 memcpy(pattern, path, plen);
Petr Kodl
osutil: implementation for Win32...
r7056
if (plen > 0) {
char c = path[plen-1];
if (c != ':' && c != '/' && c != '\\')
pattern[plen++] = '\\';
}
Augie Fackler
osutil: stop using strcpy...
r28593 pattern[plen++] = '*';
pattern[plen] = '\0';
Petr Kodl
osutil: implementation for Win32...
r7056
fh = FindFirstFileA(pattern, &fd);
if (fh == INVALID_HANDLE_VALUE) {
Petr Kodl
Improve error handling in osutil.c...
r7059 PyErr_SetFromWindowsErrWithFilename(GetLastError(), path);
Petr Kodl
osutil: implementation for Win32...
r7056 goto error_file;
}
list = PyList_New(0);
if (!list)
goto error_list;
do {
PyObject *item;
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if (!strcmp(fd.cFileName, ".")
|| !strcmp(fd.cFileName, ".."))
continue;
if (skip && !strcmp(fd.cFileName, skip)) {
rval = PyList_New(0);
goto error;
}
}
item = make_item(&fd, wantstat);
if (!item)
goto error;
if (PyList_Append(list, item)) {
Py_XDECREF(item);
goto error;
}
Py_XDECREF(item);
} while (FindNextFileA(fh, &fd));
if (GetLastError() != ERROR_NO_MORE_FILES) {
Petr Kodl
Improve error handling in osutil.c...
r7059 PyErr_SetFromWindowsErrWithFilename(GetLastError(), path);
Petr Kodl
osutil: implementation for Win32...
r7056 goto error;
}
rval = list;
Py_XINCREF(rval);
error:
Py_XDECREF(list);
error_list:
FindClose(fh);
error_file:
Gregory Szorc
osutil: use Python memory allocator in _listdir...
r31468 PyMem_Free(pattern);
Benoit Boissinot
osutil.c: refactor argument parsing, allow skip=None being passed
r7098 error_nomem:
Petr Kodl
osutil: implementation for Win32...
r7056 return rval;
}
#else
Matt Mackall
osutil: major listdir cleanup
r7031 int entkind(struct dirent *ent)
Matt Mackall
osutils: pull file stat loop into its own function
r5425 {
Matt Mackall
osutil: major listdir cleanup
r7031 #ifdef DT_REG
switch (ent->d_type) {
case DT_REG: return S_IFREG;
case DT_DIR: return S_IFDIR;
case DT_LNK: return S_IFLNK;
case DT_BLK: return S_IFBLK;
case DT_CHR: return S_IFCHR;
case DT_FIFO: return S_IFIFO;
case DT_SOCK: return S_IFSOCK;
}
Bryan O'Sullivan
osutil: use fdopendir instead of dirfd
r5463 #endif
Matt Mackall
osutil: fix some braindamage...
r7033 return -1;
Matt Mackall
osutils: pull file stat loop into its own function
r5425 }
Bryan O'Sullivan
osutil: factor out creation and init of listdir_stat
r18019 static PyObject *makestat(const struct stat *st)
{
Bryan O'Sullivan
osutil: fix tab damage
r18021 PyObject *stat;
Bryan O'Sullivan
osutil: factor out creation and init of listdir_stat
r18019
Bryan O'Sullivan
osutil: fix tab damage
r18021 stat = PyObject_CallObject((PyObject *)&listdir_stat_type, NULL);
if (stat)
memcpy(&((struct listdir_stat *)stat)->st, st, sizeof(*st));
return stat;
Bryan O'Sullivan
osutil: factor out creation and init of listdir_stat
r18019 }
Siddharth Agarwal
osutil._listdir: rename to _listdir_stat...
r24460 static PyObject *_listdir_stat(char *path, int pathlen, int keepstat,
char *skip)
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396 {
Augie Fackler
osutil: fix leak of stat in makestat when Py_BuildValue fails...
r23962 PyObject *list, *elem, *stat = NULL, *ret = NULL;
Benoit Boissinot
osutil.c: refactor argument parsing, allow skip=None being passed
r7098 char fullpath[PATH_MAX + 10];
Brendan Cully
_listdir only uses dfd if AT_SYMLINK_NOFOLLOW is defined
r7136 int kind, err;
Matt Mackall
osutil: major listdir cleanup
r7031 struct stat st;
struct dirent *ent;
DIR *dir;
Brendan Cully
_listdir only uses dfd if AT_SYMLINK_NOFOLLOW is defined
r7136 #ifdef AT_SYMLINK_NOFOLLOW
int dfd = -1;
#endif
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396
Petr Kodl
Improve error handling in osutil.c...
r7059 if (pathlen >= PATH_MAX) {
Matt Mackall
osutil: emulate os.listdir's OSError for long names (issue2898)
r14873 errno = ENAMETOOLONG;
PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
Benoit Boissinot
osutil.c: refactor argument parsing, allow skip=None being passed
r7098 goto error_value;
Petr Kodl
Improve error handling in osutil.c...
r7059 }
Matt Mackall
osutil: major listdir cleanup
r7031 strncpy(fullpath, path, PATH_MAX);
fullpath[pathlen] = '/';
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396
Matt Mackall
osutil: fix some braindamage...
r7033 #ifdef AT_SYMLINK_NOFOLLOW
dfd = open(path, O_RDONLY);
if (dfd == -1) {
PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
Benoit Boissinot
osutil.c: refactor argument parsing, allow skip=None being passed
r7098 goto error_value;
Matt Mackall
osutil: fix some braindamage...
r7033 }
dir = fdopendir(dfd);
#else
dir = opendir(path);
#endif
Matt Mackall
osutil: cleanups...
r5421 if (!dir) {
Matt Mackall
osutil: major listdir cleanup
r7031 PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
goto error_dir;
Augie Fackler
osutil.c: clean up space before a tab
r23961 }
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396
Matt Mackall
osutil: cleanups...
r5421 list = PyList_New(0);
Matt Mackall
osutil: major listdir cleanup
r7031 if (!list)
goto error_list;
while ((ent = readdir(dir))) {
if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
continue;
Giorgos Keramidas
osutil.c: style fix - delete trailing end-of-line spaces
r5416
Matt Mackall
osutil: major listdir cleanup
r7031 kind = entkind(ent);
if (kind == -1 || keepstat) {
Matt Mackall
osutil: fix some braindamage...
r7033 #ifdef AT_SYMLINK_NOFOLLOW
err = fstatat(dfd, ent->d_name, &st,
AT_SYMLINK_NOFOLLOW);
#else
strncpy(fullpath + pathlen + 1, ent->d_name,
PATH_MAX - pathlen);
Siddharth Agarwal
osutil: mark end of string with null char, not 0...
r24462 fullpath[PATH_MAX] = '\0';
Matt Mackall
osutil: fix some braindamage...
r7033 err = lstat(fullpath, &st);
#endif
Matt Mackall
osutil: major listdir cleanup
r7031 if (err == -1) {
Matt Mackall
osutil: handle deletion race with readdir/stat (issue3463)
r16747 /* race with file deletion? */
if (errno == ENOENT)
continue;
Matt Mackall
osutil: major listdir cleanup
r7031 strncpy(fullpath + pathlen + 1, ent->d_name,
PATH_MAX - pathlen);
fullpath[PATH_MAX] = 0;
PyErr_SetFromErrnoWithFilename(PyExc_OSError,
fullpath);
goto error;
}
kind = st.st_mode & S_IFMT;
}
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396
Matt Mackall
listdir: add support for aborting if a certain path is found...
r7034 /* quit early? */
if (skip && kind == S_IFDIR && !strcmp(ent->d_name, skip)) {
ret = PyList_New(0);
goto error;
}
Matt Mackall
osutil: major listdir cleanup
r7031 if (keepstat) {
Bryan O'Sullivan
osutil: factor out creation and init of listdir_stat
r18019 stat = makestat(&st);
Matt Mackall
osutil: major listdir cleanup
r7031 if (!stat)
goto error;
elem = Py_BuildValue("siN", ent->d_name, kind, stat);
} else
elem = Py_BuildValue("si", ent->d_name, kind);
if (!elem)
goto error;
Augie Fackler
osutil: fix leak of stat in makestat when Py_BuildValue fails...
r23962 stat = NULL;
Matt Mackall
osutil: major listdir cleanup
r7031
PyList_Append(list, elem);
Py_DECREF(elem);
}
Matt Mackall
osutil: cleanups...
r5421
Matt Mackall
osutil: major listdir cleanup
r7031 ret = list;
Py_INCREF(ret);
Matt Mackall
osutil: cleanups...
r5421
Matt Mackall
osutil: major listdir cleanup
r7031 error:
Py_DECREF(list);
Augie Fackler
osutil: fix leak of stat in makestat when Py_BuildValue fails...
r23962 Py_XDECREF(stat);
Matt Mackall
osutil: major listdir cleanup
r7031 error_list:
closedir(dir);
Jun Wu
osutil: fix potential wrong fd close...
r31471 /* closedir also closes its dirfd */
goto error_value;
Matt Mackall
osutil: major listdir cleanup
r7031 error_dir:
Matt Mackall
osutil: fix some braindamage...
r7033 #ifdef AT_SYMLINK_NOFOLLOW
close(dfd);
#endif
Benoit Boissinot
osutil.c: refactor argument parsing, allow skip=None being passed
r7098 error_value:
Matt Mackall
osutil: major listdir cleanup
r7031 return ret;
Matt Mackall
osutil: cleanups...
r5421 }
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396
Siddharth Agarwal
osutil: use getdirentriesattr on OS X if possible...
r24461 #ifdef __APPLE__
typedef struct {
u_int32_t length;
attrreference_t name;
fsobj_type_t obj_type;
struct timespec mtime;
#if __LITTLE_ENDIAN__
mode_t access_mask;
uint16_t padding;
#else
uint16_t padding;
mode_t access_mask;
#endif
off_t size;
} __attribute__((packed)) attrbuf_entry;
int attrkind(attrbuf_entry *entry)
{
switch (entry->obj_type) {
case VREG: return S_IFREG;
case VDIR: return S_IFDIR;
case VLNK: return S_IFLNK;
case VBLK: return S_IFBLK;
case VCHR: return S_IFCHR;
case VFIFO: return S_IFIFO;
case VSOCK: return S_IFSOCK;
}
return -1;
}
/* get these many entries at a time */
#define LISTDIR_BATCH_SIZE 50
static PyObject *_listdir_batch(char *path, int pathlen, int keepstat,
char *skip, bool *fallback)
{
PyObject *list, *elem, *stat = NULL, *ret = NULL;
int kind, err;
unsigned long index;
unsigned int count, old_state, new_state;
bool state_seen = false;
attrbuf_entry *entry;
/* from the getattrlist(2) man page: a path can be no longer than
(NAME_MAX * 3 + 1) bytes. Also, "The getattrlist() function will
silently truncate attribute data if attrBufSize is too small." So
pass in a buffer big enough for the worst case. */
char attrbuf[LISTDIR_BATCH_SIZE * (sizeof(attrbuf_entry) + NAME_MAX * 3 + 1)];
unsigned int basep_unused;
struct stat st;
int dfd = -1;
/* these must match the attrbuf_entry struct, otherwise you'll end up
with garbage */
struct attrlist requested_attr = {0};
requested_attr.bitmapcount = ATTR_BIT_MAP_COUNT;
requested_attr.commonattr = (ATTR_CMN_NAME | ATTR_CMN_OBJTYPE |
ATTR_CMN_MODTIME | ATTR_CMN_ACCESSMASK);
Matt Mackall
mac: ignore resource fork when checking file sizes...
r27877 requested_attr.fileattr = ATTR_FILE_DATALENGTH;
Siddharth Agarwal
osutil: use getdirentriesattr on OS X if possible...
r24461
*fallback = false;
if (pathlen >= PATH_MAX) {
errno = ENAMETOOLONG;
PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
goto error_value;
}
dfd = open(path, O_RDONLY);
if (dfd == -1) {
PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
goto error_value;
}
list = PyList_New(0);
if (!list)
goto error_dir;
do {
count = LISTDIR_BATCH_SIZE;
err = getdirentriesattr(dfd, &requested_attr, &attrbuf,
sizeof(attrbuf), &count, &basep_unused,
&new_state, 0);
if (err < 0) {
if (errno == ENOTSUP) {
/* We're on a filesystem that doesn't support
getdirentriesattr. Fall back to the
stat-based implementation. */
*fallback = true;
} else
PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
goto error;
}
if (!state_seen) {
old_state = new_state;
state_seen = true;
} else if (old_state != new_state) {
/* There's an edge case with getdirentriesattr. Consider
the following initial list of files:
a
b
<--
c
d
If the iteration is paused at the arrow, and b is
deleted before it is resumed, getdirentriesattr will
not return d at all! Ordinarily we're expected to
restart the iteration from the beginning. To avoid
getting stuck in a retry loop here, fall back to
stat. */
*fallback = true;
goto error;
}
entry = (attrbuf_entry *)attrbuf;
for (index = 0; index < count; index++) {
char *filename = ((char *)&entry->name) +
entry->name.attr_dataoffset;
if (!strcmp(filename, ".") || !strcmp(filename, ".."))
continue;
kind = attrkind(entry);
if (kind == -1) {
PyErr_Format(PyExc_OSError,
"unknown object type %u for file "
"%s%s!",
entry->obj_type, path, filename);
goto error;
}
/* quit early? */
if (skip && kind == S_IFDIR && !strcmp(filename, skip)) {
ret = PyList_New(0);
goto error;
}
if (keepstat) {
/* from the getattrlist(2) man page: "Only the
permission bits ... are valid". */
st.st_mode = (entry->access_mask & ~S_IFMT) | kind;
st.st_mtime = entry->mtime.tv_sec;
st.st_size = entry->size;
stat = makestat(&st);
if (!stat)
goto error;
elem = Py_BuildValue("siN", filename, kind, stat);
} else
elem = Py_BuildValue("si", filename, kind);
if (!elem)
goto error;
stat = NULL;
PyList_Append(list, elem);
Py_DECREF(elem);
entry = (attrbuf_entry *)((char *)entry + entry->length);
}
} while (err == 0);
ret = list;
Py_INCREF(ret);
error:
Py_DECREF(list);
Py_XDECREF(stat);
error_dir:
close(dfd);
error_value:
return ret;
}
#endif /* __APPLE__ */
Siddharth Agarwal
osutil._listdir: rename to _listdir_stat...
r24460 static PyObject *_listdir(char *path, int pathlen, int keepstat, char *skip)
{
Siddharth Agarwal
osutil: use getdirentriesattr on OS X if possible...
r24461 #ifdef __APPLE__
PyObject *ret;
bool fallback = false;
ret = _listdir_batch(path, pathlen, keepstat, skip, &fallback);
if (ret != NULL || !fallback)
return ret;
#endif
Siddharth Agarwal
osutil._listdir: rename to _listdir_stat...
r24460 return _listdir_stat(path, pathlen, keepstat, skip);
}
Bryan O'Sullivan
osutil: write a C implementation of statfiles for unix...
r18026 static PyObject *statfiles(PyObject *self, PyObject *args)
{
Bryan O'Sullivan
osutil: tab damage, how i hate thee
r18027 PyObject *names, *stats;
Py_ssize_t i, count;
Bryan O'Sullivan
osutil: write a C implementation of statfiles for unix...
r18026
Bryan O'Sullivan
osutil: tab damage, how i hate thee
r18027 if (!PyArg_ParseTuple(args, "O:statfiles", &names))
return NULL;
Bryan O'Sullivan
osutil: write a C implementation of statfiles for unix...
r18026
Bryan O'Sullivan
osutil: tab damage, how i hate thee
r18027 count = PySequence_Length(names);
if (count == -1) {
PyErr_SetString(PyExc_TypeError, "not a sequence");
return NULL;
}
Bryan O'Sullivan
osutil: write a C implementation of statfiles for unix...
r18026
Bryan O'Sullivan
osutil: tab damage, how i hate thee
r18027 stats = PyList_New(count);
if (stats == NULL)
return NULL;
Bryan O'Sullivan
osutil: write a C implementation of statfiles for unix...
r18026
Bryan O'Sullivan
osutil: tab damage, how i hate thee
r18027 for (i = 0; i < count; i++) {
Augie Fackler
osutil: fix memory leak of PyBytes of path in statfiles...
r23966 PyObject *stat, *pypath;
Bryan O'Sullivan
osutil: tab damage, how i hate thee
r18027 struct stat st;
int ret, kind;
char *path;
Bryan O'Sullivan
osutil: write a C implementation of statfiles for unix...
r18026
Bryan O'Sullivan
osutil: make statfiles check for interrupts periodically...
r26983 /* With a large file count or on a slow filesystem,
don't block signals for long (issue4878). */
if ((i % 1000) == 999 && PyErr_CheckSignals() == -1)
goto bail;
Augie Fackler
osutil: fix memory leak of PyBytes of path in statfiles...
r23966 pypath = PySequence_GetItem(names, i);
if (!pypath)
Bryan O'Sullivan
osutil: don't leak on statfiles error...
r26982 goto bail;
Gregory Szorc
osutil: convert PyString* to PyBytes*...
r30098 path = PyBytes_AsString(pypath);
Bryan O'Sullivan
osutil: tab damage, how i hate thee
r18027 if (path == NULL) {
Augie Fackler
osutil: fix memory leak of PyBytes of path in statfiles...
r23966 Py_DECREF(pypath);
Bryan O'Sullivan
osutil: tab damage, how i hate thee
r18027 PyErr_SetString(PyExc_TypeError, "not a string");
goto bail;
}
ret = lstat(path, &st);
Augie Fackler
osutil: fix memory leak of PyBytes of path in statfiles...
r23966 Py_DECREF(pypath);
Bryan O'Sullivan
osutil: tab damage, how i hate thee
r18027 kind = st.st_mode & S_IFMT;
if (ret != -1 && (kind == S_IFREG || kind == S_IFLNK)) {
stat = makestat(&st);
if (stat == NULL)
goto bail;
PyList_SET_ITEM(stats, i, stat);
} else {
Py_INCREF(Py_None);
PyList_SET_ITEM(stats, i, Py_None);
}
}
Bryan O'Sullivan
osutil: write a C implementation of statfiles for unix...
r18026
Bryan O'Sullivan
osutil: tab damage, how i hate thee
r18027 return stats;
Bryan O'Sullivan
osutil: write a C implementation of statfiles for unix...
r18026
bail:
Bryan O'Sullivan
osutil: tab damage, how i hate thee
r18027 Py_DECREF(stats);
return NULL;
Bryan O'Sullivan
osutil: write a C implementation of statfiles for unix...
r18026 }
Yuya Nishihara
osutil: implement recvmsg() of SCM_RIGHTS for chg command server...
r27473 /*
* recvfds() simply does not release GIL during blocking io operation because
* command server is known to be single-threaded.
Yuya Nishihara
osutil: disable compilation of recvfds() on unsupported platforms...
r27970 *
* Old systems such as Solaris don't provide CMSG_LEN, msg_control, etc.
* Currently, recvfds() is not supported on these platforms.
Yuya Nishihara
osutil: implement recvmsg() of SCM_RIGHTS for chg command server...
r27473 */
Yuya Nishihara
osutil: disable compilation of recvfds() on unsupported platforms...
r27970 #ifdef CMSG_LEN
Yuya Nishihara
osutil: implement recvmsg() of SCM_RIGHTS for chg command server...
r27473
static ssize_t recvfdstobuf(int sockfd, int **rfds, void *cbuf, size_t cbufsize)
{
char dummy[1];
struct iovec iov = {dummy, sizeof(dummy)};
struct msghdr msgh = {0};
struct cmsghdr *cmsg;
msgh.msg_iov = &iov;
msgh.msg_iovlen = 1;
msgh.msg_control = cbuf;
msgh.msg_controllen = (socklen_t)cbufsize;
if (recvmsg(sockfd, &msgh, 0) < 0)
return -1;
for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg;
cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
if (cmsg->cmsg_level != SOL_SOCKET ||
cmsg->cmsg_type != SCM_RIGHTS)
continue;
*rfds = (int *)CMSG_DATA(cmsg);
return (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
}
*rfds = cbuf;
return 0;
}
static PyObject *recvfds(PyObject *self, PyObject *args)
{
int sockfd;
int *rfds = NULL;
ssize_t rfdscount, i;
char cbuf[256];
PyObject *rfdslist = NULL;
if (!PyArg_ParseTuple(args, "i", &sockfd))
return NULL;
rfdscount = recvfdstobuf(sockfd, &rfds, cbuf, sizeof(cbuf));
if (rfdscount < 0)
return PyErr_SetFromErrno(PyExc_OSError);
rfdslist = PyList_New(rfdscount);
if (!rfdslist)
goto bail;
for (i = 0; i < rfdscount; i++) {
Gregory Szorc
osutil: use PyLongObject in recvfds...
r30110 PyObject *obj = PyLong_FromLong(rfds[i]);
Yuya Nishihara
osutil: implement recvmsg() of SCM_RIGHTS for chg command server...
r27473 if (!obj)
goto bail;
PyList_SET_ITEM(rfdslist, i, obj);
}
return rfdslist;
bail:
Py_XDECREF(rfdslist);
return NULL;
}
Yuya Nishihara
osutil: disable compilation of recvfds() on unsupported platforms...
r27970 #endif /* CMSG_LEN */
Jun Wu
osutil: implement setprocname to set process title for some platforms...
r30409
#if defined(HAVE_SETPROCTITLE)
/* setproctitle is the first choice - available in FreeBSD */
#define SETPROCNAME_USE_SETPROCTITLE
#elif (defined(__linux__) || defined(__APPLE__)) && PY_MAJOR_VERSION == 2
/* rewrite the argv buffer in place - works in Linux and OS X. Py_GetArgcArgv
* in Python 3 returns the copied wchar_t **argv, thus unsupported. */
#define SETPROCNAME_USE_ARGVREWRITE
#else
#define SETPROCNAME_USE_NONE
#endif
#ifndef SETPROCNAME_USE_NONE
static PyObject *setprocname(PyObject *self, PyObject *args)
{
const char *name = NULL;
if (!PyArg_ParseTuple(args, "s", &name))
return NULL;
#if defined(SETPROCNAME_USE_SETPROCTITLE)
setproctitle("%s", name);
#elif defined(SETPROCNAME_USE_ARGVREWRITE)
{
static char *argvstart = NULL;
static size_t argvsize = 0;
if (argvstart == NULL) {
int argc = 0, i;
char **argv = NULL;
char *argvend;
extern void Py_GetArgcArgv(int *argc, char ***argv);
Py_GetArgcArgv(&argc, &argv);
/* Check the memory we can use. Typically, argv[i] and
* argv[i + 1] are continuous. */
argvend = argvstart = argv[0];
for (i = 0; i < argc; ++i) {
if (argv[i] > argvend || argv[i] < argvstart)
break; /* not continuous */
size_t len = strlen(argv[i]);
argvend = argv[i] + len + 1 /* '\0' */;
}
if (argvend > argvstart) /* sanity check */
argvsize = argvend - argvstart;
}
if (argvstart && argvsize > 1) {
int n = snprintf(argvstart, argvsize, "%s", name);
if (n >= 0 && (size_t)n < argvsize)
memset(argvstart + n, 0, argvsize - n);
}
}
#endif
Py_RETURN_NONE;
}
#endif /* ndef SETPROCNAME_USE_NONE */
Jun Wu
statfs: change Linux feature detection...
r31622 #if defined(HAVE_BSD_STATFS)
Yuya Nishihara
statfs: refactor inner function as a mapping from statfs to string...
r31676 static const char *describefstype(const struct statfs *pbuf)
{
Jun Wu
osutil: report fstype for BSD and OSX
r31597 /* BSD or OSX provides a f_fstypename field */
Jun Wu
statfs: avoid static allocation...
r31623 return pbuf->f_fstypename;
Yuya Nishihara
statfs: refactor inner function as a mapping from statfs to string...
r31676 }
Jun Wu
statfs: change Linux feature detection...
r31622 #elif defined(HAVE_LINUX_STATFS)
Yuya Nishihara
statfs: refactor inner function as a mapping from statfs to string...
r31676 static const char *describefstype(const struct statfs *pbuf)
{
Jun Wu
osutil: add a C function getting filesystem type...
r31563 /* Begin of Linux filesystems */
#ifdef ADFS_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == ADFS_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "adfs";
#endif
#ifdef AFFS_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == AFFS_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "affs";
#endif
Jun Wu
statfs: detect more filesystems on Linux...
r31627 #ifdef AUTOFS_SUPER_MAGIC
if (pbuf->f_type == AUTOFS_SUPER_MAGIC)
return "autofs";
#endif
Jun Wu
osutil: add a C function getting filesystem type...
r31563 #ifdef BDEVFS_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == BDEVFS_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "bdevfs";
#endif
#ifdef BEFS_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == BEFS_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "befs";
#endif
#ifdef BFS_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == BFS_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "bfs";
#endif
#ifdef BINFMTFS_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == BINFMTFS_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "binfmtfs";
#endif
#ifdef BTRFS_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == BTRFS_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "btrfs";
#endif
#ifdef CGROUP_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == CGROUP_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "cgroup";
#endif
#ifdef CIFS_MAGIC_NUMBER
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == CIFS_MAGIC_NUMBER)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "cifs";
#endif
#ifdef CODA_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == CODA_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "coda";
#endif
#ifdef COH_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == COH_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "coh";
#endif
#ifdef CRAMFS_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == CRAMFS_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "cramfs";
#endif
#ifdef DEBUGFS_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == DEBUGFS_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "debugfs";
#endif
#ifdef DEVFS_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == DEVFS_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "devfs";
#endif
#ifdef DEVPTS_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == DEVPTS_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "devpts";
#endif
#ifdef EFIVARFS_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == EFIVARFS_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "efivarfs";
#endif
#ifdef EFS_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == EFS_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "efs";
#endif
#ifdef EXT_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == EXT_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "ext";
#endif
#ifdef EXT2_OLD_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == EXT2_OLD_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "ext2";
#endif
#ifdef EXT2_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == EXT2_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "ext2";
#endif
#ifdef EXT3_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == EXT3_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "ext3";
#endif
#ifdef EXT4_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == EXT4_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "ext4";
#endif
Jun Wu
statfs: detect more filesystems on Linux...
r31627 #ifdef F2FS_SUPER_MAGIC
if (pbuf->f_type == F2FS_SUPER_MAGIC)
return "f2fs";
#endif
Jun Wu
osutil: add a C function getting filesystem type...
r31563 #ifdef FUSE_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == FUSE_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "fuse";
#endif
#ifdef FUTEXFS_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == FUTEXFS_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "futexfs";
#endif
#ifdef HFS_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == HFS_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "hfs";
#endif
#ifdef HOSTFS_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == HOSTFS_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "hostfs";
#endif
#ifdef HPFS_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == HPFS_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "hpfs";
#endif
#ifdef HUGETLBFS_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == HUGETLBFS_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "hugetlbfs";
#endif
#ifdef ISOFS_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == ISOFS_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "isofs";
#endif
#ifdef JFFS2_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == JFFS2_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "jffs2";
#endif
#ifdef JFS_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == JFS_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "jfs";
#endif
#ifdef MINIX_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == MINIX_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "minix";
#endif
#ifdef MINIX2_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == MINIX2_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "minix2";
#endif
#ifdef MINIX3_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == MINIX3_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "minix3";
#endif
#ifdef MQUEUE_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == MQUEUE_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "mqueue";
#endif
#ifdef MSDOS_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == MSDOS_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "msdos";
#endif
#ifdef NCP_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == NCP_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "ncp";
#endif
#ifdef NFS_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == NFS_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "nfs";
#endif
#ifdef NILFS_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == NILFS_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "nilfs";
#endif
#ifdef NTFS_SB_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == NTFS_SB_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "ntfs-sb";
#endif
#ifdef OCFS2_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == OCFS2_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "ocfs2";
#endif
#ifdef OPENPROM_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == OPENPROM_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "openprom";
#endif
Jun Wu
statfs: detect more filesystems on Linux...
r31627 #ifdef OVERLAYFS_SUPER_MAGIC
if (pbuf->f_type == OVERLAYFS_SUPER_MAGIC)
return "overlay";
#endif
Jun Wu
osutil: add a C function getting filesystem type...
r31563 #ifdef PIPEFS_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == PIPEFS_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "pipefs";
#endif
#ifdef PROC_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == PROC_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "proc";
#endif
#ifdef PSTOREFS_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == PSTOREFS_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "pstorefs";
#endif
#ifdef QNX4_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == QNX4_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "qnx4";
#endif
#ifdef QNX6_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == QNX6_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "qnx6";
#endif
#ifdef RAMFS_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == RAMFS_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "ramfs";
#endif
#ifdef REISERFS_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == REISERFS_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "reiserfs";
#endif
#ifdef ROMFS_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == ROMFS_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "romfs";
#endif
Jun Wu
statfs: detect more filesystems on Linux...
r31627 #ifdef SECURITYFS_MAGIC
if (pbuf->f_type == SECURITYFS_MAGIC)
return "securityfs";
#endif
Jun Wu
osutil: add a C function getting filesystem type...
r31563 #ifdef SELINUX_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == SELINUX_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "selinux";
#endif
#ifdef SMACK_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == SMACK_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "smack";
#endif
#ifdef SMB_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == SMB_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "smb";
#endif
#ifdef SOCKFS_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == SOCKFS_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "sockfs";
#endif
#ifdef SQUASHFS_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == SQUASHFS_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "squashfs";
#endif
#ifdef SYSFS_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == SYSFS_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "sysfs";
#endif
#ifdef SYSV2_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == SYSV2_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "sysv2";
#endif
#ifdef SYSV4_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == SYSV4_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "sysv4";
#endif
#ifdef TMPFS_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == TMPFS_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "tmpfs";
#endif
#ifdef UDF_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == UDF_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "udf";
#endif
#ifdef UFS_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == UFS_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "ufs";
#endif
#ifdef USBDEVICE_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == USBDEVICE_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "usbdevice";
#endif
#ifdef V9FS_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == V9FS_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "v9fs";
#endif
#ifdef VXFS_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == VXFS_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "vxfs";
#endif
#ifdef XENFS_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == XENFS_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "xenfs";
#endif
#ifdef XENIX_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == XENIX_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "xenix";
#endif
#ifdef XFS_SUPER_MAGIC
Jun Wu
statfs: avoid static allocation...
r31623 if (pbuf->f_type == XFS_SUPER_MAGIC)
Jun Wu
osutil: add a C function getting filesystem type...
r31563 return "xfs";
#endif
/* End of Linux filesystems */
return NULL;
}
Yuya Nishihara
statfs: refactor inner function as a mapping from statfs to string...
r31676 #endif /* def HAVE_LINUX_STATFS */
Jun Wu
osutil: export a "getfstype" method...
r31564
Yuya Nishihara
statfs: refactor inner function as a mapping from statfs to string...
r31676 #if defined(HAVE_BSD_STATFS) || defined(HAVE_LINUX_STATFS)
/* given a directory path, return filesystem type name (best-effort) */
Yuya Nishihara
statfs: rename pygetfstype to getfstype...
r31677 static PyObject *getfstype(PyObject *self, PyObject *args)
Jun Wu
osutil: export a "getfstype" method...
r31564 {
const char *path = NULL;
Jun Wu
statfs: avoid static allocation...
r31623 struct statfs buf;
Yuya Nishihara
statfs: refactor inner function as a mapping from statfs to string...
r31676 int r;
Jun Wu
osutil: export a "getfstype" method...
r31564 if (!PyArg_ParseTuple(args, "s", &path))
return NULL;
Jun Wu
statfs: avoid static allocation...
r31623 memset(&buf, 0, sizeof(buf));
Yuya Nishihara
statfs: refactor inner function as a mapping from statfs to string...
r31676 r = statfs(path, &buf);
if (r != 0)
Yuya Nishihara
statfs: make getfstype() raise OSError...
r31678 return PyErr_SetFromErrno(PyExc_OSError);
Yuya Nishihara
statfs: refactor inner function as a mapping from statfs to string...
r31676 return Py_BuildValue("s", describefstype(&buf));
Jun Wu
osutil: export a "getfstype" method...
r31564 }
Jun Wu
statfs: change Linux feature detection...
r31622 #endif /* defined(HAVE_LINUX_STATFS) || defined(HAVE_BSD_STATFS) */
Jun Wu
osutil: add a C function getting filesystem type...
r31563
Petr Kodl
osutil: implementation for Win32...
r7056 #endif /* ndef _WIN32 */
Benoit Boissinot
osutil.c: refactor argument parsing, allow skip=None being passed
r7098 static PyObject *listdir(PyObject *self, PyObject *args, PyObject *kwargs)
{
PyObject *statobj = NULL; /* initialize - optional arg */
PyObject *skipobj = NULL; /* initialize - optional arg */
char *path, *skip = NULL;
int wantstat, plen;
static char *kwlist[] = {"path", "stat", "skip", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|OO:listdir",
kwlist, &path, &plen, &statobj, &skipobj))
return NULL;
wantstat = statobj && PyObject_IsTrue(statobj);
if (skipobj && skipobj != Py_None) {
Renato Cunha
osutil.c: Support for py3k added....
r11359 skip = PyBytes_AsString(skipobj);
Benoit Boissinot
osutil.c: refactor argument parsing, allow skip=None being passed
r7098 if (!skip)
return NULL;
}
return _listdir(path, plen, wantstat, skip);
}
Bryan O'Sullivan
Windows: improve performance via buffered I/O...
r8330 #ifdef _WIN32
static PyObject *posixfile(PyObject *self, PyObject *args, PyObject *kwds)
{
static char *kwlist[] = {"name", "mode", "buffering", NULL};
PyObject *file_obj = NULL;
char *name = NULL;
char *mode = "rb";
Patrick Mezard
osutil: silence uninitialized variable warning
r8597 DWORD access = 0;
Bryan O'Sullivan
Windows: improve performance via buffered I/O...
r8330 DWORD creation;
HANDLE handle;
int fd, flags = 0;
int bufsize = -1;
char m0, m1, m2;
char fpmode[4];
int fppos = 0;
int plus;
FILE *fp;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|si:posixfile", kwlist,
Py_FileSystemDefaultEncoding,
&name, &mode, &bufsize))
return NULL;
m0 = mode[0];
m1 = m0 ? mode[1] : '\0';
m2 = m1 ? mode[2] : '\0';
plus = m1 == '+' || m2 == '+';
fpmode[fppos++] = m0;
if (m1 == 'b' || m2 == 'b') {
flags = _O_BINARY;
fpmode[fppos++] = 'b';
}
else
flags = _O_TEXT;
Adrian Buehlmann
osutil: treat open modes 'w' and 'a' as 'w+' and 'a+' in posixfile...
r13273 if (m0 == 'r' && !plus) {
flags |= _O_RDONLY;
access = GENERIC_READ;
} else {
/*
work around http://support.microsoft.com/kb/899149 and
set _O_RDWR for 'w' and 'a', even if mode has no '+'
*/
Bryan O'Sullivan
Windows: improve performance via buffered I/O...
r8330 flags |= _O_RDWR;
access = GENERIC_READ | GENERIC_WRITE;
fpmode[fppos++] = '+';
}
fpmode[fppos++] = '\0';
switch (m0) {
case 'r':
creation = OPEN_EXISTING;
break;
case 'w':
creation = CREATE_ALWAYS;
break;
case 'a':
creation = OPEN_ALWAYS;
flags |= _O_APPEND;
break;
default:
PyErr_Format(PyExc_ValueError,
"mode string must begin with one of 'r', 'w', "
"or 'a', not '%c'", m0);
goto bail;
}
handle = CreateFile(name, access,
FILE_SHARE_READ | FILE_SHARE_WRITE |
FILE_SHARE_DELETE,
NULL,
creation,
FILE_ATTRIBUTE_NORMAL,
0);
if (handle == INVALID_HANDLE_VALUE) {
PyErr_SetFromWindowsErrWithFilename(GetLastError(), name);
goto bail;
}
Matt Mackall
many, many trivial check-code fixups
r10282 fd = _open_osfhandle((intptr_t)handle, flags);
Renato Cunha
osutil.c: Support for py3k added....
r11359
Bryan O'Sullivan
Windows: improve performance via buffered I/O...
r8330 if (fd == -1) {
CloseHandle(handle);
PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
goto bail;
}
Renato Cunha
osutil.c: Support for py3k added....
r11359 #ifndef IS_PY3K
Bryan O'Sullivan
Windows: improve performance via buffered I/O...
r8330 fp = _fdopen(fd, fpmode);
if (fp == NULL) {
_close(fd);
PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
goto bail;
}
file_obj = PyFile_FromFile(fp, name, mode, fclose);
if (file_obj == NULL) {
fclose(fp);
goto bail;
}
PyFile_SetBufSize(file_obj, bufsize);
Renato Cunha
osutil.c: Support for py3k added....
r11359 #else
file_obj = PyFile_FromFd(fd, name, mode, bufsize, NULL, NULL, NULL, 1);
if (file_obj == NULL)
goto bail;
#endif
Bryan O'Sullivan
Windows: improve performance via buffered I/O...
r8330 bail:
PyMem_Free(name);
return file_obj;
}
#endif
Dan Villiom Podlaski Christiansen
util: add Mac-specific check whether we're in a GUI session (issue2553)...
r13734 #ifdef __APPLE__
Dan Villiom Podlaski Christiansen
osutil: replace #import with #include, and add a check for it
r13748 #include <ApplicationServices/ApplicationServices.h>
Dan Villiom Podlaski Christiansen
util: add Mac-specific check whether we're in a GUI session (issue2553)...
r13734
static PyObject *isgui(PyObject *self)
{
Matt Mackall
osutil: fix up check-code issues
r13736 CFDictionaryRef dict = CGSessionCopyCurrentDictionary();
Dan Villiom Podlaski Christiansen
util: add Mac-specific check whether we're in a GUI session (issue2553)...
r13734
Matt Mackall
osutil: fix up check-code issues
r13736 if (dict != NULL) {
CFRelease(dict);
Steve Streeting
osutil: avoid accidentally destroying the True object in isgui (issue2937)...
r15094 Py_RETURN_TRUE;
Matt Mackall
osutil: fix up check-code issues
r13736 } else {
Steve Streeting
osutil: avoid accidentally destroying the True object in isgui (issue2937)...
r15094 Py_RETURN_FALSE;
Matt Mackall
osutil: fix up check-code issues
r13736 }
Dan Villiom Podlaski Christiansen
util: add Mac-specific check whether we're in a GUI session (issue2553)...
r13734 }
#endif
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396 static char osutil_doc[] = "Native operating system services.";
static PyMethodDef methods[] = {
Matt Mackall
osutil: cleanups...
r5421 {"listdir", (PyCFunction)listdir, METH_VARARGS | METH_KEYWORDS,
"list a directory\n"},
Bryan O'Sullivan
Windows: improve performance via buffered I/O...
r8330 #ifdef _WIN32
{"posixfile", (PyCFunction)posixfile, METH_VARARGS | METH_KEYWORDS,
"Open a file with POSIX-like semantics.\n"
"On error, this function may raise either a WindowsError or an IOError."},
Bryan O'Sullivan
osutil: write a C implementation of statfiles for unix...
r18026 #else
{"statfiles", (PyCFunction)statfiles, METH_VARARGS | METH_KEYWORDS,
"stat a series of files or symlinks\n"
"Returns None for non-existent entries and entries of other types.\n"},
Yuya Nishihara
osutil: disable compilation of recvfds() on unsupported platforms...
r27970 #ifdef CMSG_LEN
Yuya Nishihara
osutil: implement recvmsg() of SCM_RIGHTS for chg command server...
r27473 {"recvfds", (PyCFunction)recvfds, METH_VARARGS,
"receive list of file descriptors via socket\n"},
Bryan O'Sullivan
Windows: improve performance via buffered I/O...
r8330 #endif
Jun Wu
osutil: implement setprocname to set process title for some platforms...
r30409 #ifndef SETPROCNAME_USE_NONE
{"setprocname", (PyCFunction)setprocname, METH_VARARGS,
"set process title (best-effort)\n"},
Yuya Nishihara
osutil: disable compilation of recvfds() on unsupported platforms...
r27970 #endif
Jun Wu
statfs: change Linux feature detection...
r31622 #if defined(HAVE_BSD_STATFS) || defined(HAVE_LINUX_STATFS)
Yuya Nishihara
statfs: rename pygetfstype to getfstype...
r31677 {"getfstype", (PyCFunction)getfstype, METH_VARARGS,
Jun Wu
osutil: export a "getfstype" method...
r31564 "get filesystem type (best-effort)\n"},
#endif
Jun Wu
osutil: implement setprocname to set process title for some platforms...
r30409 #endif /* ndef _WIN32 */
Dan Villiom Podlaski Christiansen
util: add Mac-specific check whether we're in a GUI session (issue2553)...
r13734 #ifdef __APPLE__
Matt Mackall
osutil: fix up check-code issues
r13736 {
"isgui", (PyCFunction)isgui, METH_NOARGS,
"Is a CoreGraphics session available?"
},
Dan Villiom Podlaski Christiansen
util: add Mac-specific check whether we're in a GUI session (issue2553)...
r13734 #endif
Matt Mackall
osutil: cleanups...
r5421 {NULL, NULL}
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396 };
Renato Cunha
osutil.c: Support for py3k added....
r11359 #ifdef IS_PY3K
static struct PyModuleDef osutil_module = {
PyModuleDef_HEAD_INIT,
"osutil",
osutil_doc,
-1,
methods
};
PyMODINIT_FUNC PyInit_osutil(void)
{
if (PyType_Ready(&listdir_stat_type) < 0)
return NULL;
return PyModule_Create(&osutil_module);
}
#else
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396 PyMODINIT_FUNC initosutil(void)
{
Matt Mackall
osutil: cleanups...
r5421 if (PyType_Ready(&listdir_stat_type) == -1)
return;
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396
Matt Mackall
osutil: cleanups...
r5421 Py_InitModule3("osutil", methods, osutil_doc);
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396 }
Renato Cunha
osutil.c: Support for py3k added....
r11359 #endif