Skip to content

Refactor steam_metadata() related code in UserFile. #4388

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions hphp/runtime/base/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@
#include "hphp/runtime/base/type-string.h"
#include "hphp/runtime/base/type-variant.h"

#define PHP_STREAM_META_TOUCH 1
#define PHP_STREAM_META_OWNER_NAME 2
#define PHP_STREAM_META_OWNER 3
#define PHP_STREAM_META_GROUP_NAME 4
#define PHP_STREAM_META_GROUP 5
#define PHP_STREAM_META_ACCESS 6

struct stat;

namespace HPHP {
Expand Down
75 changes: 6 additions & 69 deletions hphp/runtime/base/user-file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@

#include "hphp/runtime/base/comparisons.h"
#include "hphp/runtime/base/complex-types.h"
#include "hphp/runtime/base/array-init.h"
#include "hphp/runtime/base/runtime-error.h"
#include "hphp/runtime/vm/jit/translator-inline.h"

Expand Down Expand Up @@ -497,81 +496,19 @@ bool UserFile::rmdir(const String& filename, int options) {
return false;
}

bool UserFile::invokeMetadata(const Array& args, const char* funcName) {
bool UserFile::invokeMetadata(const Array& args) {
bool invoked = false;
Variant ret = invoke(m_StreamMetadata, s_stream_metadata, args, invoked);
if (!invoked) {
raise_warning("%s(): %s::stream_metadata is not implemented!",
funcName, m_cls->name()->data());
raise_warning("%s::stream_metadata is not implemented!",
m_cls->name()->data());
return false;
} else if (ret.toBoolean() == true) {
return true;
}
return false;
}

bool UserFile::touch(const String& path, int64_t mtime, int64_t atime) {
if (atime == 0) {
atime = mtime;
if (ret.toBoolean() == true) {
return true;
}

return invokeMetadata(
PackedArrayInit(3)
.append(path)
.append(1) // STREAM_META_TOUCH
.append(atime ? make_packed_array(mtime, atime) : Array::Create())
.toArray(),
"touch");
}

bool UserFile::chmod(const String& path, int64_t mode) {
return invokeMetadata(
PackedArrayInit(3)
.append(path)
.append(6) // STREAM_META_ACCESS
.append(mode)
.toArray(),
"chmod");
}

bool UserFile::chown(const String& path, int64_t uid) {
return invokeMetadata(
PackedArrayInit(3)
.append(path)
.append(3) // STREAM_META_OWNER
.append(uid)
.toArray(),
"chown");
}

bool UserFile::chown(const String& path, const String& uid) {
return invokeMetadata(
PackedArrayInit(3)
.append(path)
.append(2) // STREAM_META_OWNER_NAME
.append(uid)
.toArray(),
"chown");
}

bool UserFile::chgrp(const String& path, int64_t gid) {
return invokeMetadata(
PackedArrayInit(3)
.append(path)
.append(5) // STREAM_META_GROUP
.append(gid)
.toArray(),
"chgrp");
}

bool UserFile::chgrp(const String& path, const String& gid) {
return invokeMetadata(
PackedArrayInit(3)
.append(path)
.append(4) // STREAM_META_GROUP_NAME
.append(gid)
.toArray(),
"chgrp");
return false;
}

///////////////////////////////////////////////////////////////////////////////
Expand Down
54 changes: 47 additions & 7 deletions hphp/runtime/base/user-file.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
#ifndef HPHP_USER_FILE_H
#define HPHP_USER_FILE_H

#include <utime.h>

#include "hphp/runtime/base/array-init.h"
#include "hphp/runtime/base/file.h"
#include "hphp/runtime/base/user-fs-node.h"

Expand Down Expand Up @@ -63,17 +66,54 @@ class UserFile : public File, public UserFSNode {
bool rename(const String& oldname, const String& newname);
bool mkdir(const String& path, int mode, int options);
bool rmdir(const String& path, int options);
bool touch(const String& path, int64_t mtime, int64_t atime);
bool chmod(const String& path, int64_t mode);
bool chown(const String& path, int64_t uid);
bool chown(const String& path, const String& uid);
bool chgrp(const String& path, int64_t gid);
bool chgrp(const String& path, const String& gid);

template<typename ValueT>
bool metadata(const String& path, int option, ValueT value)
{
PackedArrayInit pai(3);
pai.append(path);
pai.append(option);

switch (option) {
case PHP_STREAM_META_TOUCH:
return false;
case PHP_STREAM_META_GROUP:
case PHP_STREAM_META_OWNER:
case PHP_STREAM_META_ACCESS:
case PHP_STREAM_META_GROUP_NAME:
case PHP_STREAM_META_OWNER_NAME:
pai.append(value);
break;
default:
raise_warning("Unknown option %d for stream_metadata", option);
return false;
}

return invokeMetadata(pai.toArray());
}

bool metadata(const String& path, int option, struct utimbuf *value)
{
if (option != PHP_STREAM_META_TOUCH) {
return false;
}

PackedArrayInit pai(3);
pai.append(path);
pai.append(option);
if (value) {
pai.append(make_packed_array(value->modtime, value->actime));
} else {
pai.append(Array::Create());
}

return invokeMetadata(pai.toArray());
}

private:
int urlStat(const String& path, struct stat* stat_sb, int flags = 0);
bool flushImpl(bool strict);
bool invokeMetadata(const Array& args, const char* funcName);
bool invokeMetadata(const Array& args);

protected:
const Func* m_StreamOpen;
Expand Down
37 changes: 0 additions & 37 deletions hphp/runtime/base/user-stream-wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,42 +92,5 @@ Directory* UserStreamWrapper::opendir(const String& path) {
return dir;
}

bool UserStreamWrapper::touch(const String& path,
int64_t mtime, int64_t atime) {
auto file = newres<UserFile>(m_cls);
Resource wrapper(file);
return file->touch(path, mtime, atime);
}

bool UserStreamWrapper::chmod(const String& path, int64_t mode) {
auto file = newres<UserFile>(m_cls);
Resource wrapper(file);
return file->chmod(path, mode);
}

bool UserStreamWrapper::chown(const String& path, int64_t uid) {
auto file = newres<UserFile>(m_cls);
Resource wrapper(file);
return file->chown(path, uid);
}

bool UserStreamWrapper::chown(const String& path, const String& uid) {
auto file = newres<UserFile>(m_cls);
Resource wrapper(file);
return file->chown(path, uid);
}

bool UserStreamWrapper::chgrp(const String& path, int64_t gid) {
auto file = newres<UserFile>(m_cls);
Resource wrapper(file);
return file->chgrp(path, gid);
}

bool UserStreamWrapper::chgrp(const String& path, const String& gid) {
auto file = newres<UserFile>(m_cls);
Resource wrapper(file);
return file->chgrp(path, gid);
}

///////////////////////////////////////////////////////////////////////////////
}
13 changes: 7 additions & 6 deletions hphp/runtime/base/user-stream-wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,13 @@ struct UserStreamWrapper final : Stream::Wrapper {
int mkdir(const String& path, int mode, int options) override;
int rmdir(const String& path, int options) override;
Directory* opendir(const String& path) override;
bool touch(const String& path, int64_t mtime, int64_t atime);
bool chmod(const String& path, int64_t mode);
bool chown(const String& path, int64_t uid);
bool chown(const String& path, const String& uid);
bool chgrp(const String& path, int64_t gid);
bool chgrp(const String& path, const String& gid);

template<typename ValueT>
bool metadata(const String& path, int option, ValueT value) {
auto file = newres<UserFile>(m_cls);
Resource wrapper(file);
return file->metadata(path, option, value);
}

private:
String m_name;
Expand Down
54 changes: 32 additions & 22 deletions hphp/runtime/ext/std/ext_std_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1289,7 +1289,7 @@ bool HHVM_FUNCTION(chmod,
Stream::Wrapper* w = Stream::getWrapperFromURI(filename);
auto usw = dynamic_cast<UserStreamWrapper*>(w);
if (usw != nullptr) {
return usw->chmod(filename, mode);
return usw->metadata(filename, PHP_STREAM_META_ACCESS, mode);
}

CHECK_SYSTEM(chmod(translated.c_str(), mode));
Expand Down Expand Up @@ -1323,9 +1323,11 @@ bool HHVM_FUNCTION(chown,
auto usw = dynamic_cast<UserStreamWrapper*>(w);
if (usw != nullptr) {
if (user.isInteger()) {
return usw->chown(filename, user.toInt64());
return usw->metadata(filename, PHP_STREAM_META_OWNER,
user.toInt64());
} else if (user.isString()) {
return usw->chown(filename, user.toString());
return usw->metadata(filename, PHP_STREAM_META_OWNER_NAME,
user.toString());
}
raise_warning("chown(): parameter 2 should be string or integer, %s given",
getDataTypeString(user.getType()).c_str());
Expand All @@ -1352,9 +1354,11 @@ bool HHVM_FUNCTION(lchown,
auto usw = dynamic_cast<UserStreamWrapper*>(w);
if (usw != nullptr) {
if (user.isInteger()) {
return usw->chown(filename, user.toInt64());
return usw->metadata(filename, PHP_STREAM_META_OWNER,
user.toInt64());
} else if (user.isString()) {
return usw->chown(filename, user.toString());
return usw->metadata(filename, PHP_STREAM_META_OWNER_NAME,
user.toString());
}
raise_warning("lchown(): parameter 2 should be string or integer, %s given",
getDataTypeString(user.getType()).c_str());
Expand Down Expand Up @@ -1398,9 +1402,11 @@ bool HHVM_FUNCTION(chgrp,
auto usw = dynamic_cast<UserStreamWrapper*>(w);
if (usw != nullptr) {
if (group.isInteger()) {
return usw->chgrp(filename, group.toInt64());
return usw->metadata(filename, PHP_STREAM_META_GROUP,
group.toInt64());
} else if (group.isString()) {
return usw->chgrp(filename, group.toString());
return usw->metadata(filename, PHP_STREAM_META_GROUP_NAME,
group.toString());
}
raise_warning("chgrp(): parameter 2 should be string or integer, %s given",
getDataTypeString(group.getType()).c_str());
Expand All @@ -1423,9 +1429,11 @@ bool HHVM_FUNCTION(lchgrp,
auto usw = dynamic_cast<UserStreamWrapper*>(w);
if (usw != nullptr) {
if (group.isInteger()) {
return usw->chgrp(filename, group.toInt64());
return usw->metadata(filename, PHP_STREAM_META_GROUP,
group.toInt64());
} else if (group.isString()) {
return usw->chgrp(filename, group.toString());
return usw->metadata(filename, PHP_STREAM_META_GROUP_NAME,
group.toString());
}
raise_warning("lchgrp(): parameter 2 should be string or integer, %s given",
getDataTypeString(group.getType()).c_str());
Expand All @@ -1444,11 +1452,23 @@ bool HHVM_FUNCTION(touch,
int64_t atime /* = 0 */) {
CHECK_PATH_FALSE(filename, 1);

// If filename points to a user file, invoke UserStreamWrapper::touch(..)
struct utimbuf newtimebuf;
newtimebuf.actime = atime ? atime : mtime;
newtimebuf.modtime = mtime;

struct utimbuf *newtime;
if (mtime == 0 && atime == 0) {
// It is important to pass nullptr so that the OS sets mtime and atime
// to the current time with maximum precision (more precise then seconds)
newtime = nullptr;
} else {
newtime = &newtimebuf;
}

Stream::Wrapper* w = Stream::getWrapperFromURI(filename);
auto usw = dynamic_cast<UserStreamWrapper*>(w);
if (usw != nullptr) {
return usw->touch(filename, mtime, atime);
return usw->metadata(filename, PHP_STREAM_META_TOUCH, newtime);
}

String translated = File::TranslatePath(filename);
Expand All @@ -1466,17 +1486,7 @@ bool HHVM_FUNCTION(touch,
fclose(f);
}

if (mtime == 0 && atime == 0) {
// It is important to pass nullptr so that the OS sets mtime and atime
// to the current time with maximum precision (more precise then seconds)
CHECK_SYSTEM(utime(translated.data(), nullptr));
} else {
struct utimbuf newtime;
newtime.actime = atime ? atime : mtime;
newtime.modtime = mtime;
CHECK_SYSTEM(utime(translated.data(), &newtime));
}

CHECK_SYSTEM(utime(translated.data(), newtime));
return true;
}

Expand Down
7 changes: 0 additions & 7 deletions hphp/runtime/ext/stream/ext_stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,6 @@
#define PHP_STREAM_BUFFER_FULL 2 /* fully buffered */
#define PHP_STREAM_COPY_ALL (-1)

#define PHP_STREAM_META_TOUCH 1
#define PHP_STREAM_META_OWNER_NAME 2
#define PHP_STREAM_META_OWNER 3
#define PHP_STREAM_META_GROUP_NAME 4
#define PHP_STREAM_META_GROUP 5
#define PHP_STREAM_META_ACCESS 6

namespace HPHP {

///////////////////////////////////////////////////////////////////////////////
Expand Down